OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/font_access/font_access_service_impl.h" |
| 6 |
| 7 #include "base/files/file.h" |
| 8 #include "base/files/file_path.h" |
| 9 #include "base/files/file_util.h" |
| 10 #include "base/sequenced_task_runner.h" |
| 11 #include "content/browser/font_access/font_getter.h" |
| 12 #include "content/public/browser/browser_thread.h" |
| 13 #include "mojo/public/cpp/system/buffer.h" |
| 14 #include "net/base/mime_util.h" |
| 15 |
| 16 namespace content { |
| 17 |
| 18 FontAccessServiceImpl::FontAccessServiceImpl( |
| 19 base::Callback<scoped_ptr<FontCacheMap>(void)> getter, |
| 20 mojo::InterfaceRequest<FontAccessService> request) |
| 21 : binding_(this, std::move(request)), |
| 22 cache_map_getter_(getter), |
| 23 weak_factory_(this) {} |
| 24 |
| 25 FontAccessServiceImpl::~FontAccessServiceImpl() {} |
| 26 |
| 27 void FontAccessServiceImpl::GetFontList(const GetFontListCallback& callback) { |
| 28 ClobberCacheAndReply(base::Bind(&FontAccessServiceImpl::GetFontListFromCache, |
| 29 weak_factory_.GetWeakPtr(), callback)); |
| 30 } |
| 31 |
| 32 void FontAccessServiceImpl::GetFontData(const mojo::String& family, |
| 33 const mojo::String& style, |
| 34 const GetFontDataCallback& callback) { |
| 35 base::FilePath path = FindPathInCache(family.get(), style.get()); |
| 36 // If service doesn't exist, or if the cache missed. |
| 37 if (path.empty()) { |
| 38 ClobberCacheAndReply(base::Bind(&FontAccessServiceImpl::GetFontDataInternal, |
| 39 weak_factory_.GetWeakPtr(), family.get(), |
| 40 style.get(), callback)); |
| 41 return; |
| 42 } |
| 43 |
| 44 BrowserThread::PostTaskAndReplyWithResult( |
| 45 BrowserThread::FILE, FROM_HERE, |
| 46 base::Bind(&FontAccessServiceImpl::GetFileInfo, path), |
| 47 base::Bind(&FontAccessServiceImpl::GetFileDataCallback, |
| 48 weak_factory_.GetWeakPtr(), callback, path)); |
| 49 } |
| 50 |
| 51 void FontAccessServiceImpl::Create( |
| 52 mojo::InterfaceRequest<FontAccessService> request) { |
| 53 new FontAccessServiceImpl(base::Bind(&content::GetFontCacheMap), |
| 54 std::move(request)); |
| 55 } |
| 56 |
| 57 FontAccessServiceImpl::BlobInfo::BlobInfo() : size(0) {} |
| 58 |
| 59 FontAccessServiceImpl::BlobInfo::~BlobInfo() {} |
| 60 |
| 61 void FontAccessServiceImpl::GetFontListFromCache( |
| 62 const GetFontListCallback& callback) { |
| 63 FontCacheMap::iterator iter; |
| 64 mojo::Array<FontDescriptionPtr> font_infos(0); |
| 65 for (auto& entry : *font_cache_map_) { |
| 66 for (auto& face_entry : entry.second) { |
| 67 FontDescriptionPtr font_ptr = FontDescription::New(); |
| 68 font_ptr->family = entry.first; |
| 69 font_ptr->style = face_entry.first; |
| 70 font_ptr->full_name = face_entry.second.full_name; |
| 71 font_infos.push_back(std::move(font_ptr)); |
| 72 } |
| 73 } |
| 74 callback.Run(std::move(font_infos)); |
| 75 } |
| 76 |
| 77 void FontAccessServiceImpl::GetFontDataInternal( |
| 78 const std::string& family, |
| 79 const std::string& style, |
| 80 const GetFontDataCallback& callback) { |
| 81 base::FilePath path = FindPathInCache(family, style); |
| 82 if (path.empty()) { |
| 83 callback.Run(mojo::ScopedHandleBase<mojo::SharedBufferHandle>(), 0); |
| 84 return; |
| 85 } |
| 86 |
| 87 BrowserThread::PostTaskAndReplyWithResult( |
| 88 BrowserThread::FILE, FROM_HERE, |
| 89 base::Bind(&FontAccessServiceImpl::GetFileInfo, path), |
| 90 base::Bind(&FontAccessServiceImpl::GetFileDataCallback, |
| 91 weak_factory_.GetWeakPtr(), callback, path)); |
| 92 } |
| 93 |
| 94 base::FilePath FontAccessServiceImpl::FindPathInCache( |
| 95 const std::string& family, |
| 96 const std::string& style) { |
| 97 if (!font_cache_map_.get()) |
| 98 return base::FilePath(); |
| 99 |
| 100 FontCacheMap::iterator iter; |
| 101 iter = font_cache_map_->find(family); |
| 102 if (iter != font_cache_map_->end()) { |
| 103 FontStyleMap::iterator face_iter; |
| 104 face_iter = iter->second.find(style); |
| 105 if (face_iter != iter->second.end()) { |
| 106 return face_iter->second.path; |
| 107 } |
| 108 } |
| 109 return base::FilePath(); |
| 110 } |
| 111 |
| 112 void FontAccessServiceImpl::ClobberCacheAndReply(const base::Closure closure) { |
| 113 base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); |
| 114 scoped_refptr<base::SequencedTaskRunner> tr = pool->GetSequencedTaskRunner( |
| 115 pool->GetNamedSequenceToken(std::string(kFontAccessToken))); |
| 116 base::PostTaskAndReplyWithResult( |
| 117 tr.get(), FROM_HERE, cache_map_getter_, |
| 118 base::Bind(&FontAccessServiceImpl::SwapCacheAndReply, |
| 119 weak_factory_.GetWeakPtr(), closure)); |
| 120 } |
| 121 |
| 122 void FontAccessServiceImpl::SwapCacheAndReply(const base::Closure closure, |
| 123 scoped_ptr<FontCacheMap> cache) { |
| 124 font_cache_map_.swap(cache); |
| 125 closure.Run(); |
| 126 } |
| 127 |
| 128 // static |
| 129 FontAccessServiceImpl::BlobInfo FontAccessServiceImpl::GetFileInfo( |
| 130 const base::FilePath& filepath) { |
| 131 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
| 132 base::File::Info info; |
| 133 BlobInfo real_info; |
| 134 real_info.is_valid = base::GetFileInfo(filepath, &info); |
| 135 if (!real_info.is_valid) |
| 136 return real_info; |
| 137 |
| 138 real_info.size = info.size; |
| 139 real_info.last_modified = info.last_modified; |
| 140 net::GetMimeTypeFromFile(filepath, &real_info.mime); |
| 141 |
| 142 return real_info; |
| 143 } |
| 144 |
| 145 // static |
| 146 mojo::ScopedSharedBufferHandle FontAccessServiceImpl::GetSharedBuffer( |
| 147 const base::FilePath& filepath, |
| 148 uint64_t size) { |
| 149 mojo::SharedBuffer buffer(size); |
| 150 base::File file(filepath, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 151 void* data; |
| 152 mojo::MapBuffer(buffer.handle.get(), 0, size, &data, |
| 153 MOJO_MAP_BUFFER_FLAG_NONE); |
| 154 bool valid_read = file.Read(0, static_cast<char*>(data), size); |
| 155 if (!valid_read) |
| 156 return mojo::ScopedHandleBase<mojo::SharedBufferHandle>(); |
| 157 |
| 158 return std::move(buffer.handle); |
| 159 } |
| 160 |
| 161 void FontAccessServiceImpl::GetFileDataCallback( |
| 162 const FontAccessService::GetFontDataCallback& callback, |
| 163 const base::FilePath& path, |
| 164 BlobInfo info) { |
| 165 if (!info.is_valid) { |
| 166 callback.Run(mojo::ScopedHandleBase<mojo::SharedBufferHandle>(), 0); |
| 167 return; |
| 168 } |
| 169 |
| 170 BrowserThread::PostTaskAndReplyWithResult( |
| 171 BrowserThread::FILE, FROM_HERE, |
| 172 base::Bind(&FontAccessServiceImpl::GetSharedBuffer, path, info.size), |
| 173 base::Bind(&FontAccessServiceImpl::PassBufferAndSize, callback, |
| 174 info.size)); |
| 175 } |
| 176 |
| 177 void FontAccessServiceImpl::PassBufferAndSize( |
| 178 const FontAccessService::GetFontDataCallback& callback, |
| 179 uint64_t size, |
| 180 mojo::ScopedSharedBufferHandle handle) { |
| 181 callback.Run(std::move(handle), size); |
| 182 } |
| 183 |
| 184 } // content |
OLD | NEW |