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; | |
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.
| |
60 mojo::Array<FontDescriptionPtr> fontInfos(0); | |
ncarter (slow)
2016/02/09 18:59:45
font_infos
Daniel Nishi
2016/02/11 00:23:50
Done.
| |
61 for (iter = font_cache_map_->begin(); iter != font_cache_map_->end(); | |
62 ++iter) { | |
63 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.
| |
64 for (faceIter = iter->second.begin(); faceIter != iter->second.end(); | |
65 ++faceIter) { | |
66 FontDescriptionPtr fontPtr = | |
ncarter (slow)
2016/02/09 18:59:45
font_ptr
Daniel Nishi
2016/02/11 00:23:50
Done.
| |
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 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 std::string FontAccessServiceImpl::FindPathInCache( | |
95 const std::string& family, | |
96 const std::string& style) { | |
97 if (!font_cache_map_.get()) | |
98 return std::string(); | |
99 | |
100 FontCacheMap::iterator iter; | |
101 iter = font_cache_map_->find(family); | |
102 if (iter != font_cache_map_->end()) { | |
103 FontStyleMap::iterator faceIter; | |
104 faceIter = iter->second.find(style); | |
105 if (faceIter != iter->second.end()) { | |
106 return faceIter->second.path; | |
107 } | |
108 } | |
109 return std::string(); | |
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 std::string path) { | |
esprehn
2016/02/09 19:29:56
path& ?
Daniel Nishi
2016/02/11 00:23:50
Done.
| |
131 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); | |
132 base::FilePath filepath(base::FilePath::FromUTF8Unsafe(path)); | |
133 base::File::Info info; | |
134 BlobInfo realInfo; | |
135 realInfo.is_valid = base::GetFileInfo(filepath, &info); | |
136 if (!realInfo.is_valid) { | |
137 return realInfo; | |
138 } | |
139 | |
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, | |
esprehn
2016/02/09 19:29:56
path& ?
Daniel Nishi
2016/02/11 00:23:50
Done.
| |
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 bool valid_read = file.Read(0, static_cast<char*>(data), size); | |
158 if (!valid_read) { | |
159 return mojo::ScopedHandleBase<mojo::SharedBufferHandle>(); | |
160 } | |
161 | |
162 | |
163 return std::move(buffer.handle); | |
164 } | |
165 | |
166 void FontAccessServiceImpl::GetFileDataCallback( | |
167 const FontAccessService::GetFontDataCallback& callback, | |
168 const std::string& path, | |
169 BlobInfo info) { | |
170 if (!info.is_valid) { | |
171 callback.Run(mojo::ScopedHandleBase<mojo::SharedBufferHandle>(), 0); | |
172 return; | |
173 } | |
174 | |
175 BrowserThread::PostTaskAndReplyWithResult( | |
176 BrowserThread::FILE, FROM_HERE, | |
177 base::Bind(&FontAccessServiceImpl::GetSharedBuffer, path, info.size), | |
178 base::Bind(&FontAccessServiceImpl::PassBufferAndSize, callback, | |
179 info.size)); | |
180 } | |
181 | |
182 void FontAccessServiceImpl::PassBufferAndSize( | |
183 const FontAccessService::GetFontDataCallback& callback, | |
184 uint64_t size, | |
185 mojo::ScopedSharedBufferHandle handle) { | |
186 callback.Run(std::move(handle), size); | |
187 } | |
188 | |
189 } // content | |
OLD | NEW |