| Index: content/browser/font_access/font_access_service_impl.cc
|
| diff --git a/content/browser/font_access/font_access_service_impl.cc b/content/browser/font_access/font_access_service_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6895d44869ae1a18fa8851c0a0c559f9787ff340
|
| --- /dev/null
|
| +++ b/content/browser/font_access/font_access_service_impl.cc
|
| @@ -0,0 +1,184 @@
|
| +// Copyright 2016 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 "content/browser/font_access/font_access_service_impl.h"
|
| +
|
| +#include "base/files/file.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/file_util.h"
|
| +#include "base/sequenced_task_runner.h"
|
| +#include "content/browser/font_access/font_getter.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "mojo/public/cpp/system/buffer.h"
|
| +#include "net/base/mime_util.h"
|
| +
|
| +namespace content {
|
| +
|
| +FontAccessServiceImpl::FontAccessServiceImpl(
|
| + base::Callback<scoped_ptr<FontCacheMap>(void)> getter,
|
| + mojo::InterfaceRequest<FontAccessService> request)
|
| + : binding_(this, std::move(request)),
|
| + cache_map_getter_(getter),
|
| + weak_factory_(this) {}
|
| +
|
| +FontAccessServiceImpl::~FontAccessServiceImpl() {}
|
| +
|
| +void FontAccessServiceImpl::GetFontList(const GetFontListCallback& callback) {
|
| + ClobberCacheAndReply(base::Bind(&FontAccessServiceImpl::GetFontListFromCache,
|
| + weak_factory_.GetWeakPtr(), callback));
|
| +}
|
| +
|
| +void FontAccessServiceImpl::GetFontData(const mojo::String& family,
|
| + const mojo::String& style,
|
| + const GetFontDataCallback& callback) {
|
| + base::FilePath path = FindPathInCache(family.get(), style.get());
|
| + // If service doesn't exist, or if the cache missed.
|
| + if (path.empty()) {
|
| + ClobberCacheAndReply(base::Bind(&FontAccessServiceImpl::GetFontDataInternal,
|
| + weak_factory_.GetWeakPtr(), family.get(),
|
| + style.get(), callback));
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTaskAndReplyWithResult(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + base::Bind(&FontAccessServiceImpl::GetFileInfo, path),
|
| + base::Bind(&FontAccessServiceImpl::GetFileDataCallback,
|
| + weak_factory_.GetWeakPtr(), callback, path));
|
| +}
|
| +
|
| +void FontAccessServiceImpl::Create(
|
| + mojo::InterfaceRequest<FontAccessService> request) {
|
| + new FontAccessServiceImpl(base::Bind(&content::GetFontCacheMap),
|
| + std::move(request));
|
| +}
|
| +
|
| +FontAccessServiceImpl::BlobInfo::BlobInfo() : size(0) {}
|
| +
|
| +FontAccessServiceImpl::BlobInfo::~BlobInfo() {}
|
| +
|
| +void FontAccessServiceImpl::GetFontListFromCache(
|
| + const GetFontListCallback& callback) {
|
| + FontCacheMap::iterator iter;
|
| + mojo::Array<FontDescriptionPtr> font_infos(0);
|
| + for (auto& entry : *font_cache_map_) {
|
| + for (auto& face_entry : entry.second) {
|
| + FontDescriptionPtr font_ptr = FontDescription::New();
|
| + font_ptr->family = entry.first;
|
| + font_ptr->style = face_entry.first;
|
| + font_ptr->full_name = face_entry.second.full_name;
|
| + font_infos.push_back(std::move(font_ptr));
|
| + }
|
| + }
|
| + callback.Run(std::move(font_infos));
|
| +}
|
| +
|
| +void FontAccessServiceImpl::GetFontDataInternal(
|
| + const std::string& family,
|
| + const std::string& style,
|
| + const GetFontDataCallback& callback) {
|
| + base::FilePath path = FindPathInCache(family, style);
|
| + if (path.empty()) {
|
| + callback.Run(mojo::ScopedHandleBase<mojo::SharedBufferHandle>(), 0);
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTaskAndReplyWithResult(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + base::Bind(&FontAccessServiceImpl::GetFileInfo, path),
|
| + base::Bind(&FontAccessServiceImpl::GetFileDataCallback,
|
| + weak_factory_.GetWeakPtr(), callback, path));
|
| +}
|
| +
|
| +base::FilePath FontAccessServiceImpl::FindPathInCache(
|
| + const std::string& family,
|
| + const std::string& style) {
|
| + if (!font_cache_map_.get())
|
| + return base::FilePath();
|
| +
|
| + FontCacheMap::iterator iter;
|
| + iter = font_cache_map_->find(family);
|
| + if (iter != font_cache_map_->end()) {
|
| + FontStyleMap::iterator face_iter;
|
| + face_iter = iter->second.find(style);
|
| + if (face_iter != iter->second.end()) {
|
| + return face_iter->second.path;
|
| + }
|
| + }
|
| + return base::FilePath();
|
| +}
|
| +
|
| +void FontAccessServiceImpl::ClobberCacheAndReply(const base::Closure closure) {
|
| + base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
|
| + scoped_refptr<base::SequencedTaskRunner> tr = pool->GetSequencedTaskRunner(
|
| + pool->GetNamedSequenceToken(std::string(kFontAccessToken)));
|
| + base::PostTaskAndReplyWithResult(
|
| + tr.get(), FROM_HERE, cache_map_getter_,
|
| + base::Bind(&FontAccessServiceImpl::SwapCacheAndReply,
|
| + weak_factory_.GetWeakPtr(), closure));
|
| +}
|
| +
|
| +void FontAccessServiceImpl::SwapCacheAndReply(const base::Closure closure,
|
| + scoped_ptr<FontCacheMap> cache) {
|
| + font_cache_map_.swap(cache);
|
| + closure.Run();
|
| +}
|
| +
|
| +// static
|
| +FontAccessServiceImpl::BlobInfo FontAccessServiceImpl::GetFileInfo(
|
| + const base::FilePath& filepath) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
|
| + base::File::Info info;
|
| + BlobInfo real_info;
|
| + real_info.is_valid = base::GetFileInfo(filepath, &info);
|
| + if (!real_info.is_valid)
|
| + return real_info;
|
| +
|
| + real_info.size = info.size;
|
| + real_info.last_modified = info.last_modified;
|
| + net::GetMimeTypeFromFile(filepath, &real_info.mime);
|
| +
|
| + return real_info;
|
| +}
|
| +
|
| +// static
|
| +mojo::ScopedSharedBufferHandle FontAccessServiceImpl::GetSharedBuffer(
|
| + const base::FilePath& filepath,
|
| + uint64_t size) {
|
| + mojo::SharedBuffer buffer(size);
|
| + base::File file(filepath, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
| + void* data;
|
| + mojo::MapBuffer(buffer.handle.get(), 0, size, &data,
|
| + MOJO_MAP_BUFFER_FLAG_NONE);
|
| + bool valid_read = file.Read(0, static_cast<char*>(data), size);
|
| + if (!valid_read)
|
| + return mojo::ScopedHandleBase<mojo::SharedBufferHandle>();
|
| +
|
| + return std::move(buffer.handle);
|
| +}
|
| +
|
| +void FontAccessServiceImpl::GetFileDataCallback(
|
| + const FontAccessService::GetFontDataCallback& callback,
|
| + const base::FilePath& path,
|
| + BlobInfo info) {
|
| + if (!info.is_valid) {
|
| + callback.Run(mojo::ScopedHandleBase<mojo::SharedBufferHandle>(), 0);
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTaskAndReplyWithResult(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + base::Bind(&FontAccessServiceImpl::GetSharedBuffer, path, info.size),
|
| + base::Bind(&FontAccessServiceImpl::PassBufferAndSize, callback,
|
| + info.size));
|
| +}
|
| +
|
| +void FontAccessServiceImpl::PassBufferAndSize(
|
| + const FontAccessService::GetFontDataCallback& callback,
|
| + uint64_t size,
|
| + mojo::ScopedSharedBufferHandle handle) {
|
| + callback.Run(std::move(handle), size);
|
| +}
|
| +
|
| +} // content
|
|
|