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

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

Issue 1878893002: Move //mojo/services tracing & catalog to //services (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@63move
Patch Set: . Created 4 years, 8 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/data/capabilities » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
5 #include "mojo/services/catalog/catalog.h"
6
7 #include "base/bind.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/json/json_reader.h"
10 #include "base/strings/string_split.h"
11 #include "base/task_runner_util.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "mojo/common/url_type_converters.h"
14 #include "mojo/services/catalog/entry.h"
15 #include "mojo/services/catalog/manifest_provider.h"
16 #include "mojo/services/catalog/store.h"
17 #include "services/shell/public/cpp/names.h"
18 #include "url/gurl.h"
19 #include "url/url_util.h"
20
21 namespace catalog {
22 namespace {
23
24 base::FilePath GetManifestPath(const base::FilePath& package_dir,
25 const std::string& name) {
26 // TODO(beng): think more about how this should be done for exe targets.
27 std::string type = mojo::GetNameType(name);
28 std::string path = mojo::GetNamePath(name);
29 if (type == mojo::kNameType_Mojo) {
30 return package_dir.AppendASCII("Mojo Applications").AppendASCII(
31 path + "/manifest.json");
32 }
33 if (type == mojo::kNameType_Exe)
34 return package_dir.AppendASCII(path + "_manifest.json");
35 return base::FilePath();
36 }
37
38 base::FilePath GetPackagePath(const base::FilePath& package_dir,
39 const std::string& name) {
40 std::string type = mojo::GetNameType(name);
41 if (type == mojo::kNameType_Mojo) {
42 // It's still a mojo: URL, use the default mapping scheme.
43 const std::string host = mojo::GetNamePath(name);
44 return package_dir.AppendASCII("Mojo Applications").AppendASCII(
45 host + "/" + host + ".mojo");
46 }
47 if (type == mojo::kNameType_Exe) {
48 #if defined OS_WIN
49 std::string extension = ".exe";
50 #else
51 std::string extension;
52 #endif
53 return package_dir.AppendASCII(mojo::GetNamePath(name) + extension);
54 }
55 return base::FilePath();
56 }
57
58 scoped_ptr<ReadManifestResult> ProcessManifest(
59 const base::FilePath& user_package_dir,
60 const base::FilePath& system_package_dir,
61 const std::string& name,
62 scoped_ptr<base::Value> manifest_root) {
63 scoped_ptr<Entry> entry(new Entry(name));
64 if (manifest_root) {
65 const base::DictionaryValue* dictionary = nullptr;
66 CHECK(manifest_root->GetAsDictionary(&dictionary));
67 entry = Entry::Deserialize(*dictionary);
68 }
69 entry->set_path(GetPackagePath(system_package_dir, name));
70
71 scoped_ptr<ReadManifestResult> result(new ReadManifestResult);
72 // NOTE: This TypeConverter must run on a thread which allows IO.
73 result->resolve_result = mojo::shell::mojom::ResolveResult::From(*entry);
74 result->catalog_entry = std::move(entry);
75 result->package_dir = system_package_dir;
76 return result;
77 }
78
79 scoped_ptr<ReadManifestResult> ReadManifest(
80 const base::FilePath& user_package_dir,
81 const base::FilePath& system_package_dir,
82 const std::string& name) {
83 base::FilePath manifest_path = GetManifestPath(system_package_dir, name);
84 JSONFileValueDeserializer deserializer(manifest_path);
85 int error = 0;
86 std::string message;
87
88 // TODO(beng): probably want to do more detailed error checking. This should
89 // be done when figuring out if to unblock connection completion.
90 return ProcessManifest(user_package_dir, system_package_dir, name,
91 deserializer.Deserialize(&error, &message));
92 }
93
94 void AddEntryToMap(const Entry& entry,
95 mojo::Map<mojo::String, mojom::CatalogEntryPtr>* map) {
96 mojom::CatalogEntryPtr entry_ptr(mojom::CatalogEntry::New());
97 entry_ptr->display_name = entry.display_name();
98 (*map)[entry.name()] = std::move(entry_ptr);
99 }
100
101 } // namespace
102
103 ReadManifestResult::ReadManifestResult() {}
104 ReadManifestResult::~ReadManifestResult() {}
105
106 ////////////////////////////////////////////////////////////////////////////////
107 // Catalog, public:
108
109 Catalog::Catalog(scoped_ptr<Store> store,
110 base::TaskRunner* file_task_runner,
111 EntryCache* system_catalog,
112 ManifestProvider* manifest_provider)
113 : manifest_provider_(manifest_provider),
114 store_(std::move(store)),
115 file_task_runner_(file_task_runner),
116 system_catalog_(system_catalog),
117 weak_factory_(this) {
118 PathService::Get(base::DIR_MODULE, &system_package_dir_);
119 DeserializeCatalog();
120 }
121
122 Catalog::~Catalog() {}
123
124 void Catalog::BindResolver(mojom::ResolverRequest request) {
125 resolver_bindings_.AddBinding(this, std::move(request));
126 }
127
128 void Catalog::BindShellResolver(
129 mojo::shell::mojom::ShellResolverRequest request) {
130 shell_resolver_bindings_.AddBinding(this, std::move(request));
131 }
132
133 void Catalog::BindCatalog(mojom::CatalogRequest request) {
134 catalog_bindings_.AddBinding(this, std::move(request));
135 }
136
137 ////////////////////////////////////////////////////////////////////////////////
138 // Catalog, mojom::Resolver:
139
140 void Catalog::ResolveInterfaces(mojo::Array<mojo::String> interfaces,
141 const ResolveInterfacesCallback& callback) {
142 // TODO(beng): implement.
143 }
144
145 void Catalog::ResolveMIMEType(const mojo::String& mime_type,
146 const ResolveMIMETypeCallback& callback) {
147 // TODO(beng): implement.
148 }
149
150 void Catalog::ResolveProtocolScheme(
151 const mojo::String& scheme,
152 const ResolveProtocolSchemeCallback& callback) {
153 // TODO(beng): implement.
154 }
155
156 ////////////////////////////////////////////////////////////////////////////////
157 // Catalog, mojo::shell::mojom::ShellResolver:
158
159 void Catalog::ResolveMojoName(const mojo::String& mojo_name,
160 const ResolveMojoNameCallback& callback) {
161 std::string type = mojo::GetNameType(mojo_name);
162 if (type != "mojo" && type != "exe") {
163 scoped_ptr<Entry> entry(new Entry(mojo_name));
164 callback.Run(mojo::shell::mojom::ResolveResult::From(*entry));
165 return;
166 }
167
168 auto entry = user_catalog_.find(mojo_name);
169 if (entry != user_catalog_.end()) {
170 callback.Run(mojo::shell::mojom::ResolveResult::From(*entry->second));
171 return;
172 }
173 entry = system_catalog_->find(mojo_name);
174 if (entry != system_catalog_->end()) {
175 callback.Run(mojo::shell::mojom::ResolveResult::From(*entry->second));
176 return;
177 }
178
179 std::string manifest_contents;
180 if (manifest_provider_ &&
181 manifest_provider_->GetApplicationManifest(mojo_name.To<std::string>(),
182 &manifest_contents)) {
183 scoped_ptr<base::Value> manifest_root =
184 base::JSONReader::Read(manifest_contents);
185 base::PostTaskAndReplyWithResult(
186 file_task_runner_, FROM_HERE,
187 base::Bind(&ProcessManifest, user_package_dir_, system_package_dir_,
188 mojo_name, base::Passed(&manifest_root)),
189 base::Bind(&Catalog::OnReadManifest, weak_factory_.GetWeakPtr(),
190 mojo_name, callback));
191 } else {
192 base::PostTaskAndReplyWithResult(
193 file_task_runner_, FROM_HERE,
194 base::Bind(&ReadManifest, user_package_dir_, system_package_dir_,
195 mojo_name),
196 base::Bind(&Catalog::OnReadManifest, weak_factory_.GetWeakPtr(),
197 mojo_name, callback));
198 }
199 }
200
201 ////////////////////////////////////////////////////////////////////////////////
202 // Catalog, mojom::Catalog:
203
204 void Catalog::GetEntries(mojo::Array<mojo::String> names,
205 const GetEntriesCallback& callback) {
206 mojo::Map<mojo::String, mojom::CatalogEntryPtr> entries;
207 if (names.is_null()) {
208 for (const auto& entry : user_catalog_)
209 AddEntryToMap(*entry.second, &entries);
210 for (const auto& entry : *system_catalog_)
211 AddEntryToMap(*entry.second, &entries);
212 } else {
213 std::vector<mojo::String> names_vec = names.PassStorage();
214 for (const std::string& name : names_vec) {
215 Entry* entry = nullptr;
216 if (user_catalog_.find(name) != user_catalog_.end())
217 entry = user_catalog_[name].get();
218 else if (system_catalog_->find(name) != system_catalog_->end())
219 entry = (*system_catalog_)[name].get();
220 else
221 continue;
222 AddEntryToMap(*entry, &entries);
223 }
224 }
225 callback.Run(std::move(entries));
226 }
227
228 ////////////////////////////////////////////////////////////////////////////////
229 // Catalog, private:
230
231 void Catalog::DeserializeCatalog() {
232 if (!store_)
233 return;
234 const base::ListValue* catalog = store_->GetStore();
235 CHECK(catalog);
236 // TODO(sky): make this handle aliases.
237 // TODO(beng): implement this properly!
238 for (auto it = catalog->begin(); it != catalog->end(); ++it) {
239 const base::DictionaryValue* dictionary = nullptr;
240 const base::Value* v = *it;
241 CHECK(v->GetAsDictionary(&dictionary));
242 scoped_ptr<Entry> entry = Entry::Deserialize(*dictionary);
243 if (entry)
244 user_catalog_[entry->name()] = std::move(entry);
245 }
246 }
247
248 void Catalog::SerializeCatalog() {
249 // TODO(beng): system catalog?
250 scoped_ptr<base::ListValue> catalog(new base::ListValue);
251 for (const auto& entry : user_catalog_)
252 catalog->Append(entry.second->Serialize());
253 if (store_)
254 store_->UpdateStore(std::move(catalog));
255 }
256
257 // static
258 void Catalog::OnReadManifest(base::WeakPtr<Catalog> catalog,
259 const std::string& name,
260 const ResolveMojoNameCallback& callback,
261 scoped_ptr<ReadManifestResult> result) {
262 callback.Run(std::move(result ->resolve_result));
263 if (catalog) {
264 catalog->AddEntryToCatalog(
265 std::move(result->catalog_entry),
266 result->package_dir == catalog->system_package_dir_);
267 }
268 }
269
270 void Catalog::AddEntryToCatalog(scoped_ptr<Entry> entry,
271 bool is_system_catalog) {
272 DCHECK(entry);
273 EntryCache* catalog = is_system_catalog ? system_catalog_ : &user_catalog_;
274 if (catalog->end() != catalog->find(entry->name()))
275 return;
276 for (auto child : entry->applications())
277 AddEntryToCatalog(make_scoped_ptr(child), is_system_catalog);
278 (*catalog)[entry->name()] = std::move(entry);
279 SerializeCatalog();
280 }
281
282 } // namespace catalog
OLDNEW
« no previous file with comments | « mojo/services/catalog/catalog.h ('k') | mojo/services/catalog/data/capabilities » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698