1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_FONT_UNIQUE_NAME_LOOKUP_FONT_UNIQUE_NAME_LOOKUP_ANDROID_H_
#define CONTENT_BROWSER_FONT_UNIQUE_NAME_LOOKUP_FONT_UNIQUE_NAME_LOOKUP_ANDROID_H_
#include <string>
#include <utility>
#include "base/files/file_path.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/sequenced_task_runner.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/mojom/font_unique_name_lookup/font_unique_name_lookup.mojom.h"
static_assert(BUILDFLAG(IS_ANDROID), "This implementation only works safely "
"on Android due to the way it assumes font files to be "
"read-only and unmodifiable.");
namespace content {
// Scans a set of font files for the full font name and postscript name
// information in the name table and builds a Protobuf lookup structure from
// it. The protobuf can be persisted to disk to the Android cache directory, and
// it can be read from disk as well. Provides the lookup structure as a
// ReadOnlySharedMemoryRegion. Performing lookup on it is done through
// FontTableMatcher.
class CONTENT_EXPORT FontUniqueNameLookup {
public:
FontUniqueNameLookup() = delete;
// Retrieve an instance of FontUniqueNameLookup. On the first call to
// GetInstance() this that will start a task reading the lookup table from
// cache if there was a cached one, updating the lookup table if needed
// (i.e. if there was an Android firmware update or no cached one existed)
// from the standard Android font directories, and writing the updated lookup
// table back to file.
static FontUniqueNameLookup& GetInstance();
// Construct a FontUniqueNameLookup given a cache directory path
// |cache_directory| to persist the internal lookup table, a
// FontFilesCollector to enumerate font files and a BuildFingerprintProvider
// to access the Android build fingerprint.
FontUniqueNameLookup(const base::FilePath& cache_directory);
~FontUniqueNameLookup();
// Return a ReadOnlySharedMemoryRegion to access the serialized form of the
// current lookup table. To be used with FontTableMatcher.
base::ReadOnlySharedMemoryRegion DuplicateMemoryRegion();
void QueueShareMemoryRegionWhenReady(
scoped_refptr<base::SequencedTaskRunner> task_runner,
blink::mojom::FontUniqueNameLookup::GetUniqueNameLookupTableCallback
callback);
// Returns true if an up-to-date, consistent font table is present.
bool IsValid();
// If an Android firmware update was detected by checking
// BuildFingerprintProvider, call UpdateTable(). Do not use this method.
// Instead, call GetInstance() to get an initialized instance. Publicly
// exposed for testing.
bool UpdateTableIfNeeded();
// Rescan the files returned by the FontFilesCollector and rebuild the lookup
// table by indexing them. Do not use this method. Instead, call GetInstance()
// to get an initialized instance. Returns true if instance is valid after
// updating, returns false if an error occured in acquiring memory or
// serializing the scanned files to the shared memory region. Publicly exposed
// for testing.
bool UpdateTable();
// Try to find a serialized lookup table in the directory specified at
// construction and load it into memory. Do not use this method. Instead, call
// GetInstance() to get an initialized instance. Publicly exposed for testing.
bool LoadFromFile();
// Serialize the current lookup table into a file in the the cache directory
// specified at construction time. If an up to date table is present and
// persisting fails, discard the internal table, as it might be that we were
// not able to update the file the previous time. Do not use this
// method. Instead, call GetInstance() to get an initialized
// instance. Publicly exposed for testing.
bool PersistToFile();
// Override the internal font files enumeration with an explicit set of fonts
// to be scanned in |font_file_paths|. Only used for testing.
void SetFontFilePathsForTesting(std::vector<base::FilePath> font_file_paths) {
font_file_paths_for_testing_ = std::move(font_file_paths);
}
// Override the Android build fingerprint for testing.
void SetAndroidBuildFingerprintForTesting(
const std::string& build_fingerprint_override) {
android_build_fingerprint_for_testing_ = build_fingerprint_override;
}
// Returns the storage location of the table cache protobuf file.
base::FilePath TableCacheFilePathForTesting() { return TableCacheFilePath(); }
protected:
void ScheduleLoadOrUpdateTable();
private:
// If an Android build fingerprint override is set through
// SetAndroidBuildFingerprint() return that, otherwise return the actual
// platform's Android build fingerprint.
std::string GetAndroidBuildFingerprint() const;
// If an override is set through SetFontFilePathsForTesting() return those
// fonts, otherwise enumerate font files in the the Android platform font
// directories.
std::vector<base::FilePath> GetFontFilePaths() const;
base::FilePath TableCacheFilePath();
void PostCallbacks();
// We have a asynchronous update tasks which need write access to the
// proto_storage_ MappedReadOnlyRegion after reading the index file from disk,
// or after scanning and indexing metadata from font files. At the same time,
// we may receive incoming Mojo requests to tell whether the proto_storage_
// storage area is already ready early for sync access by the
// renderers. Synchronize the information on whether the proto_storage_ is
// ready by means of a WaitableEvent.
base::WaitableEvent proto_storage_ready_;
base::MappedReadOnlyRegion proto_storage_;
base::FilePath cache_directory_;
std::string android_build_fingerprint_for_testing_;
std::vector<base::FilePath> font_file_paths_for_testing_ =
std::vector<base::FilePath>();
struct CallbackOnTaskRunner {
CallbackOnTaskRunner(
scoped_refptr<base::SequencedTaskRunner>,
blink::mojom::FontUniqueNameLookup::GetUniqueNameLookupTableCallback);
CallbackOnTaskRunner(CallbackOnTaskRunner&&);
~CallbackOnTaskRunner();
scoped_refptr<base::SequencedTaskRunner> task_runner;
blink::mojom::FontUniqueNameLookup::GetUniqueNameLookupTableCallback
mojo_callback;
};
std::vector<CallbackOnTaskRunner> pending_callbacks_;
};
} // namespace content
#endif // CONTENT_BROWSER_FONT_UNIQUE_NAME_LOOKUP_FONT_UNIQUE_NAME_LOOKUP_ANDROID_H_
|