Index: mojo/services/catalog/catalog.cc |
diff --git a/mojo/services/catalog/catalog.cc b/mojo/services/catalog/catalog.cc |
index 66a651dd70b0b82289cfdfd8bcbe516201a28c4a..bb7285765e19996cf3ef0f11a0fe6eea9a8f30b5 100644 |
--- a/mojo/services/catalog/catalog.cc |
+++ b/mojo/services/catalog/catalog.cc |
@@ -5,26 +5,77 @@ |
#include "mojo/services/catalog/catalog.h" |
#include "base/bind.h" |
+#include "base/json/json_file_value_serializer.h" |
#include "base/strings/string_split.h" |
#include "base/task_runner_util.h" |
#include "mojo/common/url_type_converters.h" |
#include "mojo/services/catalog/entry.h" |
#include "mojo/services/catalog/store.h" |
#include "mojo/shell/public/cpp/names.h" |
-#include "mojo/util/filename_util.h" |
#include "url/gurl.h" |
#include "url/url_util.h" |
namespace catalog { |
+namespace { |
+ |
+base::FilePath GetManifestPath(const base::FilePath& package_dir, |
+ const std::string& name) { |
+ // TODO(beng): think more about how this should be done for exe targets. |
+ std::string type = mojo::GetNameType(name); |
+ std::string path = mojo::GetNamePath(name); |
+ if (type == mojo::kNameType_Mojo) |
+ return package_dir.AppendASCII(path + "/manifest.json"); |
+ if (type == mojo::kNameType_Exe) |
+ return package_dir.AppendASCII(path + "_manifest.json"); |
+ return base::FilePath(); |
+} |
+ |
+base::FilePath GetPackagePath(const base::FilePath& package_dir, |
+ const std::string& name) { |
+ std::string type = mojo::GetNameType(name); |
+ if (type == mojo::kNameType_Mojo) { |
+ // It's still a mojo: URL, use the default mapping scheme. |
+ const std::string host = mojo::GetNamePath(name); |
+ return package_dir.AppendASCII(host + "/" + host + ".mojo"); |
+ } |
+ if (type == mojo::kNameType_Exe) { |
+#if defined OS_WIN |
+ std::string extension = ".exe"; |
+#else |
+ std::string extension; |
+#endif |
+ return package_dir.AppendASCII(mojo::GetNamePath(name) + extension); |
+ } |
+ return base::FilePath(); |
+} |
+ |
+scoped_ptr<ReadManifestResult> ReadManifest(const base::FilePath& package_dir, |
+ const std::string& name) { |
+ base::FilePath manifest_path = GetManifestPath(package_dir, name); |
+ JSONFileValueDeserializer deserializer(manifest_path); |
+ int error = 0; |
+ std::string message; |
+ // TODO(beng): probably want to do more detailed error checking. This should |
+ // be done when figuring out if to unblock connection completion. |
+ scoped_ptr<ReadManifestResult> result(new ReadManifestResult); |
+ result->manifest_root = deserializer.Deserialize(&error, &message); |
+ result->package_dir = package_dir; |
+ return result; |
+} |
+ |
+} // namespace |
+ |
+ReadManifestResult::ReadManifestResult() {} |
+ReadManifestResult::~ReadManifestResult() {} |
//////////////////////////////////////////////////////////////////////////////// |
// Catalog, public: |
-Catalog::Catalog(base::TaskRunner* blocking_pool, scoped_ptr<Store> store) |
+Catalog::Catalog(scoped_ptr<Store> store, base::TaskRunner* file_task_runner) |
: store_(std::move(store)), |
+ file_task_runner_(file_task_runner), |
weak_factory_(this) { |
- PathService::Get(base::DIR_MODULE, &package_path_); |
- reader_.reset(new Reader(package_path_, blocking_pool)); |
+ PathService::Get(base::DIR_MODULE, &system_package_dir_); |
DeserializeCatalog(); |
} |
@@ -72,22 +123,22 @@ void Catalog::ResolveProtocolScheme( |
void Catalog::ResolveMojoName(const mojo::String& mojo_name, |
const ResolveMojoNameCallback& callback) { |
- std::string resolved_name = mojo_name; |
- auto alias_iter = mojo_name_aliases_.find(resolved_name); |
- if (alias_iter != mojo_name_aliases_.end()) |
- resolved_name = alias_iter->second.first; |
- |
- std::string qualifier = mojo::GetNamePath(resolved_name); |
- auto qualifier_iter = qualifiers_.find(resolved_name); |
- if (qualifier_iter != qualifiers_.end()) |
- qualifier = qualifier_iter->second; |
- |
- if (IsNameInCatalog(resolved_name)) { |
- CompleteResolveMojoName(resolved_name, qualifier, callback); |
+ std::string type = mojo::GetNameType(mojo_name); |
+ if (type != "mojo" && type != "exe") { |
+ scoped_ptr<Entry> entry(new Entry(mojo_name)); |
+ callback.Run(mojo::shell::mojom::ResolveResult::From(*entry)); |
+ return; |
+ } |
+ |
+ auto entry = catalog_.find(mojo_name); |
+ if (entry != catalog_.end()) { |
+ callback.Run(mojo::shell::mojom::ResolveResult::From(*entry->second)); |
} else { |
- reader_->Read(resolved_name, |
- base::Bind(&Catalog::OnReadEntry, weak_factory_.GetWeakPtr(), |
- resolved_name, callback)); |
+ base::PostTaskAndReplyWithResult( |
+ file_task_runner_, FROM_HERE, |
+ base::Bind(&ReadManifest, system_package_dir_, mojo_name), |
+ base::Bind(&Catalog::OnReadManifest, weak_factory_.GetWeakPtr(), |
+ mojo_name, callback)); |
} |
} |
@@ -101,7 +152,7 @@ void Catalog::GetEntries(mojo::Array<mojo::String> names, |
for (const std::string& name : names_vec) { |
if (catalog_.find(name) == catalog_.end()) |
continue; |
- const Entry& entry = catalog_[name]; |
+ const Entry& entry = *catalog_[name]; |
mojom::CatalogEntryPtr entry_ptr(mojom::CatalogEntry::New()); |
entry_ptr->display_name = entry.display_name(); |
entries[entry.name()] = std::move(entry_ptr); |
@@ -112,43 +163,6 @@ void Catalog::GetEntries(mojo::Array<mojo::String> names, |
//////////////////////////////////////////////////////////////////////////////// |
// Catalog, private: |
-void Catalog::CompleteResolveMojoName( |
- const std::string& resolved_name, |
- const std::string& qualifier, |
- const ResolveMojoNameCallback& callback) { |
- auto entry_iter = catalog_.find(resolved_name); |
- CHECK(entry_iter != catalog_.end()); |
- |
- GURL package_url = mojo::util::AddTrailingSlashIfNeeded( |
- mojo::util::FilePathToFileURL(package_path_)); |
- GURL file_url; |
- std::string type = mojo::GetNameType(resolved_name); |
- if (type == "mojo") { |
- // It's still a mojo: URL, use the default mapping scheme. |
- const std::string host = mojo::GetNamePath(resolved_name); |
- file_url = package_url.Resolve(host + "/" + host + ".mojo"); |
- } else if (type == "exe") { |
-#if defined OS_WIN |
- std::string extension = ".exe"; |
-#else |
- std::string extension; |
-#endif |
- file_url = package_url.Resolve( |
- mojo::GetNamePath(resolved_name) + extension); |
- } |
- |
- mojo::shell::mojom::CapabilitySpecPtr capabilities_ptr = |
- mojo::shell::mojom::CapabilitySpec::From( |
- entry_iter->second.capabilities()); |
- |
- callback.Run(resolved_name, qualifier, std::move(capabilities_ptr), |
- file_url.spec()); |
-} |
- |
-bool Catalog::IsNameInCatalog(const std::string& name) const { |
- return catalog_.find(name) != catalog_.end(); |
-} |
- |
void Catalog::DeserializeCatalog() { |
if (!store_) |
return; |
@@ -161,59 +175,44 @@ void Catalog::DeserializeCatalog() { |
CHECK(v->GetAsDictionary(&dictionary)); |
scoped_ptr<Entry> entry = Entry::Deserialize(*dictionary); |
if (entry) |
- catalog_[entry->name()] = *entry; |
+ catalog_[entry->name()] = std::move(entry); |
} |
} |
void Catalog::SerializeCatalog() { |
scoped_ptr<base::ListValue> catalog(new base::ListValue); |
for (const auto& entry : catalog_) |
- catalog->Append(entry.second.Serialize()); |
+ catalog->Append(entry.second->Serialize()); |
if (store_) |
store_->UpdateStore(std::move(catalog)); |
} |
// static |
-void Catalog::OnReadEntry(base::WeakPtr<Catalog> catalog, |
- const std::string& name, |
- const ResolveMojoNameCallback& callback, |
- scoped_ptr<Entry> entry) { |
- if (!catalog) { |
- callback.Run(name, mojo::GetNamePath(name), nullptr, nullptr); |
- return; |
- } |
- catalog->OnReadEntryImpl(name, callback, std::move(entry)); |
-} |
- |
-void Catalog::OnReadEntryImpl(const std::string& name, |
- const ResolveMojoNameCallback& callback, |
- scoped_ptr<Entry> entry) { |
- // TODO(beng): evaluate the conditions under which entry is null. |
- if (!entry) { |
- entry.reset(new Entry); |
- entry->set_name(name); |
- entry->set_display_name(name); |
- entry->set_qualifier(mojo::GetNamePath(name)); |
+void Catalog::OnReadManifest(base::WeakPtr<Catalog> catalog, |
+ const std::string& name, |
+ const ResolveMojoNameCallback& callback, |
+ scoped_ptr<ReadManifestResult> result) { |
+ scoped_ptr<Entry> entry(new Entry(name)); |
+ if (result->manifest_root) { |
+ const base::DictionaryValue* dictionary = nullptr; |
+ CHECK(result->manifest_root->GetAsDictionary(&dictionary)); |
+ entry = Entry::Deserialize(*dictionary); |
} |
+ entry->set_path(GetPackagePath(result->package_dir, name)); |
- if (catalog_.find(entry->name()) == catalog_.end()) { |
- catalog_[entry->name()] = *entry; |
- |
- if (!entry->applications().empty()) { |
- for (const auto& child : entry->applications()) { |
- mojo_name_aliases_[child.name()] = |
- std::make_pair(entry->name(), child.qualifier()); |
- } |
- } |
- qualifiers_[entry->name()] = entry->qualifier(); |
- } |
+ callback.Run(mojo::shell::mojom::ResolveResult::From(*entry)); |
+ if (catalog) |
+ catalog->AddEntryToCatalog(std::move(entry)); |
+} |
+void Catalog::AddEntryToCatalog(scoped_ptr<Entry> entry) { |
+ DCHECK(entry); |
+ if (catalog_.end() != catalog_.find(entry->name())) |
+ return; |
+ for (auto child : entry->applications()) |
+ AddEntryToCatalog(make_scoped_ptr(child)); |
+ catalog_[entry->name()] = std::move(entry); |
SerializeCatalog(); |
- |
- auto qualifier_iter = qualifiers_.find(name); |
- DCHECK(qualifier_iter != qualifiers_.end()); |
- std::string qualifier = qualifier_iter->second; |
- CompleteResolveMojoName(name, qualifier, callback); |
} |
} // namespace catalog |