blob: 0b081044cf9ffbffb79577463f3f62479be6b744 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/files/file_path.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/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"
#include <ft2build.h>
#include FT_SYSTEM_H
#include FT_SFNT_NAMES_H
#include <string>
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 {
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);
// 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,
// 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(
const std::vector<std::string> font_file_paths) {
font_file_paths_for_testing_ = 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(); }
void ScheduleLoadOrUpdateTable();
// 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<std::string> 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<std::string> font_file_paths_for_testing_ =
struct CallbackOnTaskRunner {
scoped_refptr<base::SequencedTaskRunner> task_runner;
std::vector<CallbackOnTaskRunner> pending_callbacks_;
} // namespace content