| Index: mojo/services/catalog/reader.cc
|
| diff --git a/mojo/services/catalog/reader.cc b/mojo/services/catalog/reader.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..41a19a12ed364c51f1f4a5b84c311d5dacfea993
|
| --- /dev/null
|
| +++ b/mojo/services/catalog/reader.cc
|
| @@ -0,0 +1,127 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef MOJO_SERVICES_CATALOG_READER_H_
|
| +#define MOJO_SERVICES_CATALOG_READER_H_
|
| +
|
| +#include "base/files/file_enumerator.h"
|
| +#include "base/macros.h"
|
| +#include "base/thread_task_runner_handle.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();
|
| +}
|
| +
|
| +}
|
| +
|
| +Reader::Reader(EntryCache* entry_cache,
|
| + base::TaskRunner* file_task_runner,
|
| + const base::FilePath& package_dir,
|
| + const base::Closure& read_complete_closure)
|
| + : entry_cache_(entry_cache),
|
| + original_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
| + file_task_runner_(file_task_runner),
|
| + package_dir_(package_dir),
|
| + read_complete_closure_(read_complete_closure) {}
|
| +
|
| +Reader::~Reader() {}
|
| +
|
| +void Reader::ReadAllManifests(const base::Closure& read_complete_closure) {
|
| + base::PostTaskAndReplyWithResult(
|
| + file_task_runer_,
|
| + FROM_HERE,
|
| + base::Bind(&Reader::ScanPackageDir, base::Unretained(this),
|
| + package_dir_),
|
| + read_complete_closure);
|
| +}
|
| +
|
| +void Reader::ReadManifestForName(const std::string& mojo_name,
|
| + const base::Closure& read_complete_closure) {
|
| + base::PostTaskAndReplyWithResult(
|
| + file_task_runer_,
|
| + FROM_HERE,
|
| + base::Bind(&Reader::ReadManifestForNameOnFileThread, base::Unretained(this),
|
| + mojo_name),
|
| + read_complete_closure);
|
| +}
|
| +
|
| +void Reader::ScanPackageDir(const base::FilePath& package_dir) {
|
| + base::FileEnumerator enumerator(package_dir, false, base::DIRECTORIES);
|
| + do {
|
| + base::FilePath app_directory = enumerator.Next();
|
| + if (app_directory.empty())
|
| + break;
|
| +
|
| + ReadManifestAtPath(app_directory.Append("manifest.json"));
|
| + } while (true);
|
| +}
|
| +
|
| +void Reader::ReadManifestForNameOnFileThread(const std::string& mojo_name) {
|
| + ReadManifestAtPath(GetManifestPath(mojo_name))
|
| +}
|
| +
|
| +void Reader::ReadManifestAtPath() {
|
| + JSONFileValueDeserializer deserializer(manifest_path);
|
| + int error = 0;
|
| + std::string message;
|
| + scoped_ptr<base::Value> value = deserializer.Deserialize(&error, &message);
|
| + original_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&Reader::OnReadManifest, weak_factory_.GetWeakPtr(),
|
| + std::move(value)));
|
| +}
|
| +
|
| +void Reader::OnReadManifest(scoped_ptr<base::Value> manifest) {
|
| + scoped_ptr<Entry> entry(new Entry(name));
|
| + if (manifest) {
|
| + const base::DictionaryValue* dictionary = nullptr;
|
| + CHECK(manifest->GetAsDictionary(&dictionary));
|
| + entry = Entry::Deserialize(*dictionary);
|
| + }
|
| + entry->set_path(GetPackagePath(package_dir_, name));
|
| + AddEntryToCatalog(std::move(entry));
|
| +}
|
| +
|
| +void Reader::AddEntryToCatalog(scoped_ptr<Entry> entry) {
|
| + DCHECK(entry);
|
| + if (entry_cache_->end() != entry_cache_->find(entry->name()))
|
| + return;
|
| + for (auto child : entry->applications())
|
| + AddEntryToCatalog(make_scoped_ptr(child));
|
| + (*entry_cache_)[entry->name()] = std::move(entry);
|
| +}
|
| +
|
| +} // namespace catalog
|
| +
|
| +#endif // MOJO_SERVICES_CATALOG_READER_H_
|
|
|