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