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

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

Issue 2651953002: Revert of [Service Manager] Get rid of dynamic service discovery (Closed)
Patch Set: Created 3 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
« no previous file with comments | « services/catalog/catalog.h ('k') | 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 "services/catalog/catalog.h" 5 #include "services/catalog/catalog.h"
6 6
7 #include <memory> 7 #include "base/bind.h"
8 #include <string>
9
10 #include "base/base_paths.h"
11 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
12 #include "base/files/file_util.h" 9 #include "base/files/scoped_temp_dir.h"
13 #include "base/json/json_reader.h"
14 #include "base/lazy_instance.h"
15 #include "base/macros.h" 10 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
17 #include "base/path_service.h" 12 #include "base/path_service.h"
13 #include "base/strings/string_split.h"
18 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "components/filesystem/directory_impl.h" 15 #include "components/filesystem/directory_impl.h"
21 #include "components/filesystem/lock_table.h" 16 #include "components/filesystem/lock_table.h"
22 #include "components/filesystem/public/interfaces/types.mojom.h" 17 #include "components/filesystem/public/interfaces/types.mojom.h"
23 #include "mojo/public/cpp/bindings/strong_binding.h" 18 #include "mojo/public/cpp/bindings/strong_binding.h"
24 #include "services/catalog/constants.h" 19 #include "services/catalog/constants.h"
25 #include "services/catalog/entry_cache.h" 20 #include "services/catalog/entry_cache.h"
26 #include "services/catalog/instance.h" 21 #include "services/catalog/instance.h"
22 #include "services/catalog/reader.h"
27 #include "services/service_manager/public/cpp/connection.h" 23 #include "services/service_manager/public/cpp/connection.h"
28 #include "services/service_manager/public/cpp/interface_registry.h" 24 #include "services/service_manager/public/cpp/interface_registry.h"
29 #include "services/service_manager/public/cpp/service_context.h" 25 #include "services/service_manager/public/cpp/service_context.h"
30 26
31 namespace catalog { 27 namespace catalog {
32
33 namespace { 28 namespace {
34 29
35 const char kCatalogServicesKey[] = "services"; 30 bool IsPathNameValid(const std::string& name) {
36 const char kCatalogServiceEmbeddedKey[] = "embedded"; 31 if (name.empty() || name == "." || name == "..")
37 const char kCatalogServiceExecutableKey[] = "executable"; 32 return false;
38 const char kCatalogServiceManifestKey[] = "manifest";
39 33
40 base::LazyInstance<std::unique_ptr<base::Value>> g_default_static_manifest = 34 for (auto c : name) {
41 LAZY_INSTANCE_INITIALIZER; 35 if (!base::IsAsciiAlpha(c) && !base::IsAsciiDigit(c) &&
36 c != '_' && c != '.')
37 return false;
38 }
39 return true;
40 }
42 41
43 void LoadCatalogManifestIntoCache(const base::Value* root, EntryCache* cache) { 42 base::FilePath GetPathForApplicationName(const std::string& application_name) {
44 DCHECK(root); 43 static const char kServicePrefix[] = "";
45 const base::DictionaryValue* catalog = nullptr; 44 std::string path = application_name;
46 if (!root->GetAsDictionary(&catalog)) { 45 const bool is_service = base::StartsWith(
47 LOG(ERROR) << "Catalog manifest is not a dictionary value."; 46 path, kServicePrefix, base::CompareCase::INSENSITIVE_ASCII);
48 return; 47 if (!is_service)
49 } 48 return base::FilePath();
50 DCHECK(catalog); 49 if (path.find('.') != std::string::npos)
50 return base::FilePath();
51 path.erase(path.begin(), path.begin() + strlen(kServicePrefix));
52 base::TrimString(path, "/", &path);
53 size_t end_of_name = path.find('/');
54 if (end_of_name != std::string::npos)
55 path.erase(path.begin() + end_of_name, path.end());
51 56
52 const base::DictionaryValue* services = nullptr; 57 if (!IsPathNameValid(path))
53 if (!catalog->GetDictionary(kCatalogServicesKey, &services)) { 58 return base::FilePath();
54 LOG(ERROR) << "Catalog manifest \"services\" is not a dictionary value.";
55 return;
56 }
57 59
58 for (base::DictionaryValue::Iterator it(*services); !it.IsAtEnd(); 60 base::FilePath base_path;
59 it.Advance()) { 61 PathService::Get(base::DIR_EXE, &base_path);
60 const base::DictionaryValue* service_entry = nullptr; 62 // TODO(beng): this won't handle user-specific components.
61 if (!it.value().GetAsDictionary(&service_entry)) { 63 return base_path.AppendASCII(kPackagesDirName).AppendASCII(path).
62 LOG(ERROR) << "Catalog service entry for \"" << it.key() 64 AppendASCII("resources");
63 << "\" is not a dictionary value.";
64 continue;
65 }
66
67 bool is_embedded = false;
68 service_entry->GetBoolean(kCatalogServiceEmbeddedKey, &is_embedded);
69
70 base::FilePath executable_path;
71 std::string executable_path_string;
72 if (service_entry->GetString(kCatalogServiceExecutableKey,
73 &executable_path_string)) {
74 base::FilePath exe_dir;
75 CHECK(base::PathService::Get(base::DIR_EXE, &exe_dir));
76 #if defined(OS_WIN)
77 executable_path_string += ".exe";
78 base::ReplaceFirstSubstringAfterOffset(
79 &executable_path_string, 0, "@EXE_DIR",
80 base::UTF16ToUTF8(exe_dir.value()));
81 executable_path =
82 base::FilePath(base::UTF8ToUTF16(executable_path_string));
83 #else
84 base::ReplaceFirstSubstringAfterOffset(
85 &executable_path_string, 0, "@EXE_DIR", exe_dir.value());
86 executable_path = base::FilePath(executable_path_string);
87 #endif
88 }
89
90 const base::DictionaryValue* manifest = nullptr;
91 if (!service_entry->GetDictionary(kCatalogServiceManifestKey, &manifest)) {
92 LOG(ERROR) << "Catalog entry for \"" << it.key() << "\" has an invalid "
93 << "\"manifest\" value.";
94 continue;
95 }
96
97 DCHECK(!(is_embedded && !executable_path.empty()));
98
99 auto entry = Entry::Deserialize(*manifest);
100 if (entry) {
101 if (!executable_path.empty())
102 entry->set_path(executable_path);
103 bool added = cache->AddRootEntry(std::move(entry));
104 DCHECK(added);
105 } else {
106 LOG(ERROR) << "Failed to read manifest entry for \"" << it.key() << "\".";
107 }
108 }
109 } 65 }
110 66
111 } // namespace 67 } // namespace
112 68
113 class Catalog::ServiceImpl : public service_manager::Service { 69 class Catalog::ServiceImpl : public service_manager::Service {
114 public: 70 public:
115 explicit ServiceImpl(Catalog* catalog) : catalog_(catalog) {} 71 explicit ServiceImpl(Catalog* catalog) : catalog_(catalog) {}
116 ~ServiceImpl() override {} 72 ~ServiceImpl() override {}
117 73
118 // service_manager::Service: 74 // service_manager::Service:
119 bool OnConnect(const service_manager::ServiceInfo& remote_info, 75 bool OnConnect(const service_manager::ServiceInfo& remote_info,
120 service_manager::InterfaceRegistry* registry) override { 76 service_manager::InterfaceRegistry* registry) override {
121 registry->AddInterface<mojom::Catalog>(catalog_); 77 registry->AddInterface<mojom::Catalog>(catalog_);
78 registry->AddInterface<mojom::CatalogControl>(catalog_);
122 registry->AddInterface<filesystem::mojom::Directory>(catalog_); 79 registry->AddInterface<filesystem::mojom::Directory>(catalog_);
123 registry->AddInterface<service_manager::mojom::Resolver>(catalog_); 80 registry->AddInterface<service_manager::mojom::Resolver>(catalog_);
124 return true; 81 return true;
125 } 82 }
126 83
127 private: 84 private:
128 Catalog* const catalog_; 85 Catalog* const catalog_;
129 86
130 DISALLOW_COPY_AND_ASSIGN(ServiceImpl); 87 DISALLOW_COPY_AND_ASSIGN(ServiceImpl);
131 }; 88 };
132 89
133 Catalog::Catalog(std::unique_ptr<base::Value> static_manifest, 90 Catalog::Catalog(std::unique_ptr<base::Value> static_manifest) : Catalog() {
134 ManifestProvider* service_manifest_provider) 91 system_reader_.reset(new Reader(std::move(static_manifest),
135 : service_context_(new service_manager::ServiceContext( 92 system_cache_.get()));
136 base::MakeUnique<ServiceImpl>(this), 93 loaded_ = true;
137 service_manager::mojom::ServiceRequest(&service_))), 94 }
138 service_manifest_provider_(service_manifest_provider), 95
139 weak_factory_(this) { 96 Catalog::Catalog(base::SequencedWorkerPool* worker_pool,
140 if (static_manifest) { 97 ManifestProvider* manifest_provider) : Catalog() {
141 LoadCatalogManifestIntoCache(static_manifest.get(), &system_cache_); 98 system_reader_.reset(new Reader(worker_pool, manifest_provider));
142 } else if (g_default_static_manifest.Get()) { 99 ScanSystemPackageDir();
143 LoadCatalogManifestIntoCache( 100 }
144 g_default_static_manifest.Get().get(), &system_cache_); 101
145 } 102 Catalog::Catalog(base::SingleThreadTaskRunner* task_runner,
103 ManifestProvider* manifest_provider) : Catalog() {
104 system_reader_.reset(new Reader(task_runner, manifest_provider));
105 ScanSystemPackageDir();
146 } 106 }
147 107
148 Catalog::~Catalog() {} 108 Catalog::~Catalog() {}
149 109
110 void Catalog::OverridePackageName(const std::string& service_name,
111 const std::string& package_name) {
112 system_reader_->OverridePackageName(service_name, package_name);
113 }
114
150 service_manager::mojom::ServicePtr Catalog::TakeService() { 115 service_manager::mojom::ServicePtr Catalog::TakeService() {
151 return std::move(service_); 116 return std::move(service_);
152 } 117 }
153 118
154 // static 119 Catalog::Catalog() : system_cache_(new EntryCache), weak_factory_(this) {
155 void Catalog::SetDefaultCatalogManifest( 120 service_context_.reset(new service_manager::ServiceContext(
156 std::unique_ptr<base::Value> static_manifest) { 121 base::MakeUnique<ServiceImpl>(this),
157 g_default_static_manifest.Get() = std::move(static_manifest); 122 service_manager::mojom::ServiceRequest(&service_)));
158 } 123 }
159 124
160 // static 125 void Catalog::ScanSystemPackageDir() {
161 void Catalog::LoadDefaultCatalogManifest(const base::FilePath& path) { 126 base::FilePath system_package_dir;
162 std::string catalog_contents; 127 PathService::Get(base::DIR_MODULE, &system_package_dir);
163 base::FilePath exe_path; 128 system_package_dir = system_package_dir.AppendASCII(kPackagesDirName);
164 base::PathService::Get(base::DIR_EXE, &exe_path); 129 system_reader_->Read(system_package_dir, system_cache_.get(),
165 base::FilePath catalog_path = exe_path.Append(path); 130 base::Bind(&Catalog::SystemPackageDirScanned,
166 bool result = base::ReadFileToString(catalog_path, &catalog_contents); 131 weak_factory_.GetWeakPtr()));
167 DCHECK(result);
168 std::unique_ptr<base::Value> manifest_value =
169 base::JSONReader::Read(catalog_contents);
170 DCHECK(manifest_value);
171 catalog::Catalog::SetDefaultCatalogManifest(std::move(manifest_value));
172 } 132 }
173 133
174 void Catalog::Create(const service_manager::Identity& remote_identity, 134 void Catalog::Create(const service_manager::Identity& remote_identity,
175 service_manager::mojom::ResolverRequest request) { 135 service_manager::mojom::ResolverRequest request) {
176 Instance* instance = GetInstanceForUserId(remote_identity.user_id()); 136 Instance* instance = GetInstanceForUserId(remote_identity.user_id());
177 instance->BindResolver(std::move(request)); 137 instance->BindResolver(std::move(request));
178 } 138 }
179 139
180 void Catalog::Create(const service_manager::Identity& remote_identity, 140 void Catalog::Create(const service_manager::Identity& remote_identity,
181 mojom::CatalogRequest request) { 141 mojom::CatalogRequest request) {
182 Instance* instance = GetInstanceForUserId(remote_identity.user_id()); 142 Instance* instance = GetInstanceForUserId(remote_identity.user_id());
183 instance->BindCatalog(std::move(request)); 143 instance->BindCatalog(std::move(request));
184 } 144 }
185 145
186 void Catalog::Create(const service_manager::Identity& remote_identity, 146 void Catalog::Create(const service_manager::Identity& remote_identity,
187 filesystem::mojom::DirectoryRequest request) { 147 filesystem::mojom::DirectoryRequest request) {
188 if (!lock_table_) 148 if (!lock_table_)
189 lock_table_ = new filesystem::LockTable; 149 lock_table_ = new filesystem::LockTable;
190 150 base::FilePath resources_path =
191 base::FilePath resources_path; 151 GetPathForApplicationName(remote_identity.name());
192 base::PathService::Get(base::DIR_MODULE, &resources_path);
193 mojo::MakeStrongBinding( 152 mojo::MakeStrongBinding(
194 base::MakeUnique<filesystem::DirectoryImpl>( 153 base::MakeUnique<filesystem::DirectoryImpl>(
195 resources_path, scoped_refptr<filesystem::SharedTempDir>(), 154 resources_path, scoped_refptr<filesystem::SharedTempDir>(),
196 lock_table_), 155 lock_table_),
197 std::move(request)); 156 std::move(request));
198 } 157 }
199 158
159 void Catalog::Create(const service_manager::Identity& remote_identity,
160 mojom::CatalogControlRequest request) {
161 control_bindings_.AddBinding(this, std::move(request));
162 }
163
164 void Catalog::OverrideManifestPath(
165 const std::string& service_name,
166 const base::FilePath& path,
167 const OverrideManifestPathCallback& callback) {
168 system_reader_->OverrideManifestPath(service_name, path);
169 callback.Run();
170 }
171
200 Instance* Catalog::GetInstanceForUserId(const std::string& user_id) { 172 Instance* Catalog::GetInstanceForUserId(const std::string& user_id) {
201 auto it = instances_.find(user_id); 173 auto it = instances_.find(user_id);
202 if (it != instances_.end()) 174 if (it != instances_.end())
203 return it->second.get(); 175 return it->second.get();
204 176
205 auto result = instances_.insert(std::make_pair( 177 Instance* instance = new Instance(system_reader_.get());
206 user_id, 178 instances_[user_id] = base::WrapUnique(instance);
207 base::MakeUnique<Instance>(&system_cache_, service_manifest_provider_))); 179 if (loaded_)
208 return result.first->second.get(); 180 instance->CacheReady(system_cache_.get());
181
182 return instance;
183 }
184
185 void Catalog::SystemPackageDirScanned() {
186 loaded_ = true;
187 for (auto& instance : instances_)
188 instance.second->CacheReady(system_cache_.get());
209 } 189 }
210 190
211 } // namespace catalog 191 } // namespace catalog
OLDNEW
« no previous file with comments | « services/catalog/catalog.h ('k') | services/catalog/entry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698