Chromium Code Reviews| 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..9fa53cbe6e7571aa2a46128b7e0726beac6f42c7 |
| --- /dev/null |
| +++ b/content/browser/font_access/font_access_service_impl.cc |
| @@ -0,0 +1,189 @@ |
| +// 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; |
|
ncarter (slow)
2016/02/09 18:59:45
Why not use a range based for loop?
for (auto& en
Daniel Nishi
2016/02/11 00:23:50
Done.
|
| + mojo::Array<FontDescriptionPtr> fontInfos(0); |
|
ncarter (slow)
2016/02/09 18:59:45
font_infos
Daniel Nishi
2016/02/11 00:23:50
Done.
|
| + for (iter = font_cache_map_->begin(); iter != font_cache_map_->end(); |
| + ++iter) { |
| + FontStyleMap::iterator faceIter; |
|
ncarter (slow)
2016/02/09 18:59:45
face_iter (or just use a range loop)
Daniel Nishi
2016/02/11 00:23:50
Done.
|
| + for (faceIter = iter->second.begin(); faceIter != iter->second.end(); |
| + ++faceIter) { |
| + FontDescriptionPtr fontPtr = |
|
ncarter (slow)
2016/02/09 18:59:45
font_ptr
Daniel Nishi
2016/02/11 00:23:50
Done.
|
| + 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 == "") { |
| + 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)); |
| +} |
| + |
| +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) { |
|
esprehn
2016/02/09 19:29:56
path& ?
Daniel Nishi
2016/02/11 00:23:50
Done.
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
| + base::FilePath filepath(base::FilePath::FromUTF8Unsafe(path)); |
| + base::File::Info info; |
| + BlobInfo realInfo; |
| + realInfo.is_valid = base::GetFileInfo(filepath, &info); |
| + if (!realInfo.is_valid) { |
| + return 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, |
|
esprehn
2016/02/09 19:29:56
path& ?
Daniel Nishi
2016/02/11 00:23:50
Done.
|
| + 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); |
| + 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 std::string& 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 |