Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: content/browser/font_access/font_access_service_impl.cc

Issue 1615133002: Implement API for accessing fonts installed locally on the system. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add file reading failure checking. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698