| 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..925da0aca777b22ac19ef31c66810ad8a1a33fe3
|
| --- /dev/null
|
| +++ b/content/browser/font_access/font_access_service_impl.cc
|
| @@ -0,0 +1,178 @@
|
| +// 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_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) {
|
| + std::string 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> fontInfos(0);
|
| + for (iter = font_cache_map_->begin(); iter != font_cache_map_->end();
|
| + ++iter) {
|
| + FontStyleMap::iterator faceIter;
|
| + for (faceIter = iter->second.begin(); faceIter != iter->second.end();
|
| + ++faceIter) {
|
| + FontDescriptionPtr fontPtr =
|
| + FontDescription::New();
|
| + fontPtr->family = iter->first;
|
| + fontPtr->style = faceIter->first;
|
| + fontPtr->fullName = faceIter->second.fullName;
|
| + fontInfos.push_back(std::move(fontPtr));
|
| + }
|
| + }
|
| + callback.Run(std::move(fontInfos));
|
| +}
|
| +
|
| +void FontAccessServiceImpl::GetFontDataInternal(
|
| + const std::string& family,
|
| + const std::string& style,
|
| + const GetFontDataCallback& callback) {
|
| + std::string path = FindPathInCache(family, style);
|
| + if (path == "") {
|
| + mojo::SharedBuffer buffer(0);
|
| + callback.Run(std::move(buffer.handle), 0);
|
| + return;
|
| + }
|
| +
|
| + BrowserThread::PostTaskAndReplyWithResult(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + base::Bind(&FontAccessServiceImpl::GetFileInfo, path),
|
| + base::Bind(&FontAccessServiceImpl::GetFileDataCallback,
|
| + weak_factory_.GetWeakPtr(), callback, path));
|
| +}
|
| +
|
| +std::string FontAccessServiceImpl::FindPathInCache(
|
| + const std::string& family,
|
| + const std::string& style) {
|
| + if (!font_cache_map_.get())
|
| + return std::string();
|
| +
|
| + FontCacheMap::iterator iter;
|
| + iter = font_cache_map_->find(family);
|
| + if (iter != font_cache_map_->end()) {
|
| + FontStyleMap::iterator faceIter;
|
| + faceIter = iter->second.find(style);
|
| + if (faceIter != iter->second.end()) {
|
| + return faceIter->second.path;
|
| + }
|
| + }
|
| + return std::string();
|
| +}
|
| +
|
| +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 std::string path) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
|
| + base::FilePath filepath(base::FilePath::FromUTF8Unsafe(path));
|
| + base::File::Info info;
|
| + base::GetFileInfo(filepath, &info);
|
| +
|
| + BlobInfo realInfo;
|
| + realInfo.size = info.size;
|
| + realInfo.last_modified = info.last_modified;
|
| + net::GetMimeTypeFromFile(filepath, &realInfo.mime);
|
| +
|
| + return realInfo;
|
| +}
|
| +
|
| +// static
|
| +mojo::ScopedSharedBufferHandle FontAccessServiceImpl::GetSharedBuffer(
|
| + const std::string path,
|
| + uint64_t size) {
|
| + mojo::SharedBuffer buffer(size);
|
| + base::FilePath filepath(base::FilePath::FromUTF8Unsafe(path));
|
| + 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);
|
| + file.Read(0, static_cast<char*>(data), size);
|
| +
|
| + return std::move(buffer.handle);
|
| +}
|
| +
|
| +void FontAccessServiceImpl::GetFileDataCallback(
|
| + const FontAccessService::GetFontDataCallback& callback,
|
| + const std::string& path,
|
| + BlobInfo info) {
|
| + 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
|
|
|