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 |