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

Side by Side Diff: mojo/services/catalog/catalog.cc

Issue 1821383002: Moves manifest parsing to a new class, Reader. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@60catref
Patch Set: . Created 4 years, 9 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
« no previous file with comments | « mojo/services/catalog/catalog.h ('k') | mojo/services/catalog/entry.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/services/catalog/catalog.h" 5 #include "mojo/services/catalog/catalog.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/strings/string_split.h" 8 #include "base/strings/string_split.h"
10 #include "base/task_runner_util.h" 9 #include "base/task_runner_util.h"
11 #include "mojo/common/url_type_converters.h" 10 #include "mojo/common/url_type_converters.h"
12 #include "mojo/services/catalog/entry.h" 11 #include "mojo/services/catalog/entry.h"
13 #include "mojo/services/catalog/store.h" 12 #include "mojo/services/catalog/store.h"
14 #include "mojo/shell/public/cpp/names.h" 13 #include "mojo/shell/public/cpp/names.h"
15 #include "mojo/util/filename_util.h" 14 #include "mojo/util/filename_util.h"
15 #include "url/gurl.h"
16 #include "url/url_util.h" 16 #include "url/url_util.h"
17 17
18 namespace catalog { 18 namespace catalog {
19 namespace {
20
21 scoped_ptr<base::Value> ReadManifest(const base::FilePath& manifest_path) {
22 JSONFileValueDeserializer deserializer(manifest_path);
23 int error = 0;
24 std::string message;
25 // TODO(beng): probably want to do more detailed error checking. This should
26 // be done when figuring out if to unblock connection completion.
27 return deserializer.Deserialize(&error, &message);
28 }
29
30 } // namespace
31 19
32 //////////////////////////////////////////////////////////////////////////////// 20 ////////////////////////////////////////////////////////////////////////////////
33 // Catalog, public: 21 // Catalog, public:
34 22
35 Catalog::Catalog(base::TaskRunner* blocking_pool, scoped_ptr<Store> store) 23 Catalog::Catalog(base::TaskRunner* blocking_pool, scoped_ptr<Store> store)
36 : blocking_pool_(blocking_pool), 24 : store_(std::move(store)),
37 store_(std::move(store)),
38 weak_factory_(this) { 25 weak_factory_(this) {
39 base::FilePath shell_dir; 26 PathService::Get(base::DIR_MODULE, &package_path_);
40 PathService::Get(base::DIR_MODULE, &shell_dir); 27 reader_.reset(new Reader(package_path_, blocking_pool));
41
42 system_package_dir_ =
43 mojo::util::FilePathToFileURL(shell_dir).Resolve(std::string());
44 system_package_dir_ =
45 mojo::util::AddTrailingSlashIfNeeded(system_package_dir_);
46
47 DeserializeCatalog(); 28 DeserializeCatalog();
48 } 29 }
49 30
50 Catalog::~Catalog() {} 31 Catalog::~Catalog() {}
51 32
52 void Catalog::BindResolver(mojom::ResolverRequest request) { 33 void Catalog::BindResolver(mojom::ResolverRequest request) {
53 resolver_bindings_.AddBinding(this, std::move(request)); 34 resolver_bindings_.AddBinding(this, std::move(request));
54 } 35 }
55 36
56 void Catalog::BindShellResolver( 37 void Catalog::BindShellResolver(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 std::string resolved_name = mojo_name; 75 std::string resolved_name = mojo_name;
95 auto alias_iter = mojo_name_aliases_.find(resolved_name); 76 auto alias_iter = mojo_name_aliases_.find(resolved_name);
96 if (alias_iter != mojo_name_aliases_.end()) 77 if (alias_iter != mojo_name_aliases_.end())
97 resolved_name = alias_iter->second.first; 78 resolved_name = alias_iter->second.first;
98 79
99 std::string qualifier = mojo::GetNamePath(resolved_name); 80 std::string qualifier = mojo::GetNamePath(resolved_name);
100 auto qualifier_iter = qualifiers_.find(resolved_name); 81 auto qualifier_iter = qualifiers_.find(resolved_name);
101 if (qualifier_iter != qualifiers_.end()) 82 if (qualifier_iter != qualifiers_.end())
102 qualifier = qualifier_iter->second; 83 qualifier = qualifier_iter->second;
103 84
104 if (IsNameInCatalog(resolved_name)) 85 if (IsNameInCatalog(resolved_name)) {
105 CompleteResolveMojoName(resolved_name, qualifier, callback); 86 CompleteResolveMojoName(resolved_name, qualifier, callback);
106 else 87 } else {
107 AddNameToCatalog(resolved_name, callback); 88 reader_->Read(resolved_name,
89 base::Bind(&Catalog::OnReadEntry, weak_factory_.GetWeakPtr(),
90 resolved_name, callback));
91 }
108 } 92 }
109 93
110 //////////////////////////////////////////////////////////////////////////////// 94 ////////////////////////////////////////////////////////////////////////////////
111 // Catalog, mojom::Catalog: 95 // Catalog, mojom::Catalog:
112 96
113 void Catalog::GetEntries(mojo::Array<mojo::String> names, 97 void Catalog::GetEntries(mojo::Array<mojo::String> names,
114 const GetEntriesCallback& callback) { 98 const GetEntriesCallback& callback) {
115 mojo::Map<mojo::String, mojom::CatalogEntryPtr> entries; 99 mojo::Map<mojo::String, mojom::CatalogEntryPtr> entries;
116 std::vector<mojo::String> names_vec = names.PassStorage(); 100 std::vector<mojo::String> names_vec = names.PassStorage();
117 for (const std::string& name : names_vec) { 101 for (const std::string& name : names_vec) {
(...skipping 10 matching lines...) Expand all
128 //////////////////////////////////////////////////////////////////////////////// 112 ////////////////////////////////////////////////////////////////////////////////
129 // Catalog, private: 113 // Catalog, private:
130 114
131 void Catalog::CompleteResolveMojoName( 115 void Catalog::CompleteResolveMojoName(
132 const std::string& resolved_name, 116 const std::string& resolved_name,
133 const std::string& qualifier, 117 const std::string& qualifier,
134 const ResolveMojoNameCallback& callback) { 118 const ResolveMojoNameCallback& callback) {
135 auto entry_iter = catalog_.find(resolved_name); 119 auto entry_iter = catalog_.find(resolved_name);
136 CHECK(entry_iter != catalog_.end()); 120 CHECK(entry_iter != catalog_.end());
137 121
122 GURL package_url = mojo::util::AddTrailingSlashIfNeeded(
123 mojo::util::FilePathToFileURL(package_path_));
138 GURL file_url; 124 GURL file_url;
139 std::string type = mojo::GetNameType(resolved_name); 125 std::string type = mojo::GetNameType(resolved_name);
140 if (type == "mojo") { 126 if (type == "mojo") {
141 // It's still a mojo: URL, use the default mapping scheme. 127 // It's still a mojo: URL, use the default mapping scheme.
142 const std::string host = mojo::GetNamePath(resolved_name); 128 const std::string host = mojo::GetNamePath(resolved_name);
143 file_url = system_package_dir_.Resolve(host + "/" + host + ".mojo"); 129 file_url = package_url.Resolve(host + "/" + host + ".mojo");
144 } else if (type == "exe") { 130 } else if (type == "exe") {
145 #if defined OS_WIN 131 #if defined OS_WIN
146 std::string extension = ".exe"; 132 std::string extension = ".exe";
147 #else 133 #else
148 std::string extension; 134 std::string extension;
149 #endif 135 #endif
150 file_url = system_package_dir_.Resolve( 136 file_url = package_url.Resolve(
151 mojo::GetNamePath(resolved_name) + extension); 137 mojo::GetNamePath(resolved_name) + extension);
152 } 138 }
153 139
154 mojo::shell::mojom::CapabilitySpecPtr capabilities_ptr = 140 mojo::shell::mojom::CapabilitySpecPtr capabilities_ptr =
155 mojo::shell::mojom::CapabilitySpec::From( 141 mojo::shell::mojom::CapabilitySpec::From(
156 entry_iter->second.capabilities()); 142 entry_iter->second.capabilities());
157 143
158 callback.Run(resolved_name, qualifier, std::move(capabilities_ptr), 144 callback.Run(resolved_name, qualifier, std::move(capabilities_ptr),
159 file_url.spec()); 145 file_url.spec());
160 } 146 }
161 147
162 bool Catalog::IsNameInCatalog(const std::string& name) const { 148 bool Catalog::IsNameInCatalog(const std::string& name) const {
163 return catalog_.find(name) != catalog_.end(); 149 return catalog_.find(name) != catalog_.end();
164 } 150 }
165 151
166 void Catalog::AddNameToCatalog(const std::string& name,
167 const ResolveMojoNameCallback& callback) {
168 GURL manifest_url = GetManifestURL(name);
169 if (manifest_url.is_empty()) {
170 // The name is of some form that can't be resolved to a manifest (e.g. some
171 // scheme used for tests). Just pass it back to the caller so it can be
172 // loaded with a custom loader.
173 callback.Run(name, mojo::GetNamePath(name), nullptr, nullptr);
174 return;
175 }
176
177 std::string type = mojo::GetNameType(name);
178 CHECK(type == "mojo" || type == "exe");
179 base::FilePath manifest_path = mojo::util::UrlToFilePath(manifest_url);
180 base::PostTaskAndReplyWithResult(
181 blocking_pool_, FROM_HERE, base::Bind(&ReadManifest, manifest_path),
182 base::Bind(&Catalog::OnReadManifest, weak_factory_.GetWeakPtr(),
183 name, callback));
184 }
185
186 void Catalog::DeserializeCatalog() { 152 void Catalog::DeserializeCatalog() {
187 if (!store_) 153 if (!store_)
188 return; 154 return;
189 const base::ListValue* catalog = store_->GetStore(); 155 const base::ListValue* catalog = store_->GetStore();
190 CHECK(catalog); 156 CHECK(catalog);
191 // TODO(sky): make this handle aliases. 157 // TODO(sky): make this handle aliases.
192 for (auto it = catalog->begin(); it != catalog->end(); ++it) { 158 for (auto it = catalog->begin(); it != catalog->end(); ++it) {
193 const base::DictionaryValue* dictionary = nullptr; 159 const base::DictionaryValue* dictionary = nullptr;
194 const base::Value* v = *it; 160 const base::Value* v = *it;
195 CHECK(v->GetAsDictionary(&dictionary)); 161 CHECK(v->GetAsDictionary(&dictionary));
196 scoped_ptr<Entry> entry = Entry::Deserialize(*dictionary); 162 scoped_ptr<Entry> entry = Entry::Deserialize(*dictionary);
197 if (entry.get()) 163 if (entry)
198 catalog_[entry->name()] = *entry; 164 catalog_[entry->name()] = *entry;
199 } 165 }
200 } 166 }
201 167
202 void Catalog::SerializeCatalog() { 168 void Catalog::SerializeCatalog() {
203 scoped_ptr<base::ListValue> catalog(new base::ListValue); 169 scoped_ptr<base::ListValue> catalog(new base::ListValue);
204 for (const auto& entry : catalog_) 170 for (const auto& entry : catalog_)
205 catalog->Append(entry.second.Serialize()); 171 catalog->Append(entry.second.Serialize());
206 if (store_) 172 if (store_)
207 store_->UpdateStore(std::move(catalog)); 173 store_->UpdateStore(std::move(catalog));
208 } 174 }
209 175
210 scoped_ptr<Entry> Catalog::DeserializeApplication( 176 // static
211 const base::DictionaryValue* dictionary) { 177 void Catalog::OnReadEntry(base::WeakPtr<Catalog> catalog,
212 scoped_ptr<Entry> entry = Entry::Deserialize(*dictionary); 178 const std::string& name,
213 if (!entry) 179 const ResolveMojoNameCallback& callback,
214 return entry; 180 scoped_ptr<Entry> entry) {
181 if (!catalog) {
182 callback.Run(name, mojo::GetNamePath(name), nullptr, nullptr);
183 return;
184 }
185 catalog->OnReadEntryImpl(name, callback, std::move(entry));
186 }
215 187
216 // TODO(beng): move raw dictionary analysis into Deserialize(). 188 void Catalog::OnReadEntryImpl(const std::string& name,
189 const ResolveMojoNameCallback& callback,
190 scoped_ptr<Entry> entry) {
191 // TODO(beng): evaluate the conditions under which entry is null.
192 if (!entry) {
193 entry.reset(new Entry);
194 entry->set_name(name);
195 entry->set_display_name(name);
196 entry->set_qualifier(mojo::GetNamePath(name));
197 }
198
217 if (catalog_.find(entry->name()) == catalog_.end()) { 199 if (catalog_.find(entry->name()) == catalog_.end()) {
218 catalog_[entry->name()] = *entry; 200 catalog_[entry->name()] = *entry;
219 201
220 if (dictionary->HasKey("applications")) { 202 if (!entry->applications().empty()) {
221 const base::ListValue* applications = nullptr; 203 for (const auto& child : entry->applications()) {
222 dictionary->GetList("applications", &applications); 204 mojo_name_aliases_[child.name()] =
223 for (size_t i = 0; i < applications->GetSize(); ++i) { 205 std::make_pair(entry->name(), child.qualifier());
224 const base::DictionaryValue* child_value = nullptr;
225 applications->GetDictionary(i, &child_value);
226 scoped_ptr<Entry> child = DeserializeApplication(child_value);
227 if (child) {
228 mojo_name_aliases_[child->name()] =
229 std::make_pair(entry->name(), child->qualifier());
230 }
231 } 206 }
232 } 207 }
233 qualifiers_[entry->name()] = entry->qualifier(); 208 qualifiers_[entry->name()] = entry->qualifier();
234 } 209 }
235 return entry;
236 }
237 210
238 GURL Catalog::GetManifestURL(const std::string& name) {
239 // TODO(beng): think more about how this should be done for exe targets.
240 std::string type = mojo::GetNameType(name);
241 std::string path = mojo::GetNamePath(name);
242 if (type == "mojo")
243 return system_package_dir_.Resolve(path + "/manifest.json");
244 else if (type == "exe")
245 return system_package_dir_.Resolve(path + "_manifest.json");
246 return GURL();
247 }
248
249 // static
250 void Catalog::OnReadManifest(base::WeakPtr<Catalog> catalog,
251 const std::string& name,
252 const ResolveMojoNameCallback& callback,
253 scoped_ptr<base::Value> manifest) {
254 if (!catalog) {
255 // The Catalog was destroyed, we're likely in shutdown. Run the
256 // callback so we don't trigger a DCHECK.
257 callback.Run(name, mojo::GetNamePath(name), nullptr, nullptr);
258 return;
259 }
260 catalog->OnReadManifestImpl(name, callback, std::move(manifest));
261 }
262
263 void Catalog::OnReadManifestImpl(const std::string& name,
264 const ResolveMojoNameCallback& callback,
265 scoped_ptr<base::Value> manifest) {
266 if (manifest) {
267 base::DictionaryValue* dictionary = nullptr;
268 CHECK(manifest->GetAsDictionary(&dictionary));
269 DeserializeApplication(dictionary);
270 } else {
271 Entry entry;
272 entry.set_name(name);
273 entry.set_display_name(name);
274 catalog_[entry.name()] = entry;
275 qualifiers_[entry.name()] = mojo::GetNamePath(name);
276 }
277 SerializeCatalog(); 211 SerializeCatalog();
278 212
279 auto qualifier_iter = qualifiers_.find(name); 213 auto qualifier_iter = qualifiers_.find(name);
280 DCHECK(qualifier_iter != qualifiers_.end()); 214 DCHECK(qualifier_iter != qualifiers_.end());
281 std::string qualifier = qualifier_iter->second; 215 std::string qualifier = qualifier_iter->second;
282 CompleteResolveMojoName(name, qualifier, callback); 216 CompleteResolveMojoName(name, qualifier, callback);
283 } 217 }
284 218
285 } // namespace catalog 219 } // namespace catalog
OLDNEW
« no previous file with comments | « mojo/services/catalog/catalog.h ('k') | mojo/services/catalog/entry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698