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

Side by Side Diff: mojo/shell/application_manager.cc

Issue 1352663002: Extract some stuff into PackageManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 3 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/shell/application_manager.h ('k') | mojo/shell/application_manager_unittest.cc » ('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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/shell/application_manager.h" 5 #include "mojo/shell/application_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/trace_event/trace_event.h" 13 #include "base/trace_event/trace_event.h"
14 #include "mojo/application/public/interfaces/content_handler.mojom.h" 14 #include "mojo/application/public/interfaces/content_handler.mojom.h"
15 #include "mojo/public/cpp/bindings/binding.h" 15 #include "mojo/public/cpp/bindings/binding.h"
16 #include "mojo/shell/application_fetcher.h"
17 #include "mojo/shell/application_instance.h" 16 #include "mojo/shell/application_instance.h"
18 #include "mojo/shell/content_handler_connection.h" 17 #include "mojo/shell/content_handler_connection.h"
19 #include "mojo/shell/fetcher.h" 18 #include "mojo/shell/fetcher.h"
19 #include "mojo/shell/package_manager.h"
20 #include "mojo/shell/query_util.h" 20 #include "mojo/shell/query_util.h"
21 #include "mojo/shell/switches.h" 21 #include "mojo/shell/switches.h"
22 22
23 namespace mojo { 23 namespace mojo {
24 namespace shell { 24 namespace shell {
25 25
26 namespace { 26 namespace {
27 27
28 // Used by TestAPI. 28 // Used by TestAPI.
29 bool has_created_instance = false; 29 bool has_created_instance = false;
(...skipping 13 matching lines...) Expand all
43 bool ApplicationManager::TestAPI::HasCreatedInstance() { 43 bool ApplicationManager::TestAPI::HasCreatedInstance() {
44 return has_created_instance; 44 return has_created_instance;
45 } 45 }
46 46
47 bool ApplicationManager::TestAPI::HasRunningInstanceForURL( 47 bool ApplicationManager::TestAPI::HasRunningInstanceForURL(
48 const GURL& url) const { 48 const GURL& url) const {
49 return manager_->identity_to_instance_.find(Identity(url)) != 49 return manager_->identity_to_instance_.find(Identity(url)) !=
50 manager_->identity_to_instance_.end(); 50 manager_->identity_to_instance_.end();
51 } 51 }
52 52
53 ApplicationManager::ApplicationManager(scoped_ptr<ApplicationFetcher> fetcher) 53 ApplicationManager::ApplicationManager(
54 : fetcher_(fetcher.Pass()), 54 scoped_ptr<PackageManager> package_manager)
55 : package_manager_(package_manager.Pass()),
55 content_handler_id_counter_(0u), 56 content_handler_id_counter_(0u),
56 weak_ptr_factory_(this) { 57 weak_ptr_factory_(this) {
57 fetcher_->SetApplicationManager(this); 58 package_manager_->SetApplicationManager(this);
58 } 59 }
59 60
60 ApplicationManager::~ApplicationManager() { 61 ApplicationManager::~ApplicationManager() {
61 URLToContentHandlerMap url_to_content_handler(url_to_content_handler_); 62 URLToContentHandlerMap url_to_content_handler(url_to_content_handler_);
62 for (auto& pair : url_to_content_handler) 63 for (auto& pair : url_to_content_handler)
63 pair.second->CloseConnection(); 64 pair.second->CloseConnection();
64 TerminateShellConnections(); 65 TerminateShellConnections();
65 STLDeleteValues(&url_to_loader_); 66 STLDeleteValues(&url_to_loader_);
66 } 67 }
67 68
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 TRACE_EVENT_SCOPE_THREAD, "original_url", 101 TRACE_EVENT_SCOPE_THREAD, "original_url",
101 original_url.spec()); 102 original_url.spec());
102 DCHECK(original_url.is_valid()); 103 DCHECK(original_url.is_valid());
103 DCHECK(original_url_request); 104 DCHECK(original_url_request);
104 105
105 // We need to look for running instances based on both the unresolved and 106 // We need to look for running instances based on both the unresolved and
106 // resolved urls. 107 // resolved urls.
107 if (ConnectToRunningApplication(&params)) 108 if (ConnectToRunningApplication(&params))
108 return; 109 return;
109 110
110 GURL resolved_url = fetcher_->ResolveURL(original_url); 111 GURL resolved_url = package_manager_->ResolveURL(original_url);
111 params->SetURLInfo(resolved_url); 112 params->SetURLInfo(resolved_url);
112 if (ConnectToRunningApplication(&params)) 113 if (ConnectToRunningApplication(&params))
113 return; 114 return;
114 115
115 // The application is not running, let's compute the parameters. 116 // The application is not running, let's compute the parameters.
116 // NOTE: Set URL info using |original_url_request| instead of |original_url| 117 // NOTE: Set URL info using |original_url_request| instead of |original_url|
117 // because it may contain more information (e.g., it is a POST request). 118 // because it may contain more information (e.g., it is a POST request).
118 params->SetURLInfo(original_url_request.Pass()); 119 params->SetURLInfo(original_url_request.Pass());
119 ApplicationLoader* loader = GetLoaderForURL(resolved_url); 120 ApplicationLoader* loader = GetLoaderForURL(resolved_url);
120 if (loader) { 121 if (loader) {
121 ConnectToApplicationWithLoader(&params, resolved_url, loader); 122 ConnectToApplicationWithLoader(&params, resolved_url, loader);
122 return; 123 return;
123 } 124 }
124 125
125 original_url_request = params->TakeAppURLRequest(); 126 original_url_request = params->TakeAppURLRequest();
126 auto callback = 127 auto callback =
127 base::Bind(&ApplicationManager::HandleFetchCallback, 128 base::Bind(&ApplicationManager::HandleFetchCallback,
128 weak_ptr_factory_.GetWeakPtr(), base::Passed(&params)); 129 weak_ptr_factory_.GetWeakPtr(), base::Passed(&params));
129 fetcher_->FetchRequest(original_url_request.Pass(), callback); 130 package_manager_->FetchRequest(original_url_request.Pass(), callback);
130 } 131 }
131 132
132 bool ApplicationManager::ConnectToRunningApplication( 133 bool ApplicationManager::ConnectToRunningApplication(
133 scoped_ptr<ConnectToApplicationParams>* params) { 134 scoped_ptr<ConnectToApplicationParams>* params) {
134 ApplicationInstance* instance = GetApplicationInstance( 135 ApplicationInstance* instance = GetApplicationInstance(
135 Identity((*params)->app_url(), (*params)->qualifier())); 136 Identity((*params)->app_url(), (*params)->qualifier()));
136 if (!instance) 137 if (!instance)
137 return false; 138 return false;
138 139
139 instance->ConnectToClient(params->Pass()); 140 instance->ConnectToClient(params->Pass());
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 CapabilityFilter originator_filter = params->originator_filter(); 220 CapabilityFilter originator_filter = params->originator_filter();
220 CapabilityFilter filter = params->filter(); 221 CapabilityFilter filter = params->filter();
221 GURL app_url = params->app_url(); 222 GURL app_url = params->app_url();
222 std::string qualifier = params->qualifier(); 223 std::string qualifier = params->qualifier();
223 Shell::ConnectToApplicationCallback connect_callback = 224 Shell::ConnectToApplicationCallback connect_callback =
224 params->connect_callback(); 225 params->connect_callback();
225 params->set_connect_callback(EmptyConnectCallback()); 226 params->set_connect_callback(EmptyConnectCallback());
226 ApplicationInstance* app = nullptr; 227 ApplicationInstance* app = nullptr;
227 InterfaceRequest<Application> request(RegisterInstance(params.Pass(), &app)); 228 InterfaceRequest<Application> request(RegisterInstance(params.Pass(), &app));
228 229
229 // For resources that are loaded with content handlers, we group app instances
230 // by site.
231 230
232 // If the response begins with a #!mojo <content-handler-url>, use it.
233 GURL content_handler_url; 231 GURL content_handler_url;
234 std::string shebang; 232 URLResponsePtr new_response;
235 // TODO(beng): it seems like some delegate should/would want to have a say in 233 if (package_manager_->HandleWithContentHandler(fetcher.get(),
236 // configuring the qualifier also. 234 app_url,
237 bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( 235 blocking_pool_,
238 switches::kEnableMultiprocess); 236 &new_response,
239 237 &content_handler_url,
240 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { 238 &qualifier)) {
241 URLResponsePtr response(fetcher->AsURLResponse(
242 blocking_pool_, static_cast<int>(shebang.size())));
243 std::string site =
244 enable_multi_process ? response->site.To<std::string>() : std::string();
245 LoadWithContentHandler(originator_identity, originator_filter, 239 LoadWithContentHandler(originator_identity, originator_filter,
246 content_handler_url, site, filter, connect_callback, 240 content_handler_url, qualifier, filter,
247 app, request.Pass(), response.Pass()); 241 connect_callback, app, request.Pass(),
248 return; 242 new_response.Pass());
249 } 243 } else {
250 244 // TODO(erg): Have a better way of switching the sandbox on. For now, switch
251 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); 245 // it on hard coded when we're using some of the sandboxable core services.
252 if (iter != mime_type_to_url_.end()) { 246 bool start_sandboxed = false;
253 URLResponsePtr response(fetcher->AsURLResponse(blocking_pool_, 0)); 247 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
254 std::string site = 248 switches::kMojoNoSandbox)) {
255 enable_multi_process ? response->site.To<std::string>() : std::string(); 249 if (app_url == GURL("mojo://core_services/") && qualifier == "Core")
256 LoadWithContentHandler(originator_identity, originator_filter, iter->second, 250 start_sandboxed = true;
257 site, filter, connect_callback, app, request.Pass(), 251 else if (app_url == GURL("mojo://html_viewer/"))
258 response.Pass()); 252 start_sandboxed = true;
259 return;
260 }
261
262 auto alias_iter = application_package_alias_.find(app_url);
263 if (alias_iter != application_package_alias_.end()) {
264 // We replace the qualifier with the one our package alias requested.
265 URLResponsePtr response(URLResponse::New());
266 response->url = app_url.spec();
267
268 std::string qualifier;
269 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
270 switches::kEnableMultiprocess)) {
271 // Why can't we use this in single process mode? Because of
272 // base::AtExitManager. If you link in ApplicationRunner into
273 // your code, and then we make initialize multiple copies of the
274 // application, we end up with multiple AtExitManagers and will check on
275 // the second one being created.
276 //
277 // Why doesn't that happen when running different apps? Because
278 // your_thing.mojo!base::AtExitManager and
279 // my_thing.mojo!base::AtExitManager are different symbols.
280 qualifier = alias_iter->second.second;
281 } 253 }
282 254
283 LoadWithContentHandler(originator_identity, originator_filter, 255 connect_callback.Run(Shell::kInvalidContentHandlerID);
284 alias_iter->second.first, qualifier, filter, 256
285 connect_callback, app, request.Pass(), 257 fetcher->AsPath(blocking_pool_,
286 response.Pass()); 258 base::Bind(&ApplicationManager::RunNativeApplication,
287 return; 259 weak_ptr_factory_.GetWeakPtr(),
260 base::Passed(request.Pass()), start_sandboxed,
261 base::Passed(fetcher.Pass())));
288 } 262 }
289
290 // TODO(erg): Have a better way of switching the sandbox on. For now, switch
291 // it on hard coded when we're using some of the sandboxable core services.
292 bool start_sandboxed = false;
293 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
294 switches::kMojoNoSandbox)) {
295 if (app_url == GURL("mojo://core_services/") && qualifier == "Core")
296 start_sandboxed = true;
297 else if (app_url == GURL("mojo://html_viewer/"))
298 start_sandboxed = true;
299 }
300
301 connect_callback.Run(Shell::kInvalidContentHandlerID);
302
303 fetcher->AsPath(blocking_pool_,
304 base::Bind(&ApplicationManager::RunNativeApplication,
305 weak_ptr_factory_.GetWeakPtr(),
306 base::Passed(request.Pass()), start_sandboxed,
307 base::Passed(fetcher.Pass())));
308 } 263 }
309 264
310 void ApplicationManager::RunNativeApplication( 265 void ApplicationManager::RunNativeApplication(
311 InterfaceRequest<Application> application_request, 266 InterfaceRequest<Application> application_request,
312 bool start_sandboxed, 267 bool start_sandboxed,
313 scoped_ptr<Fetcher> fetcher, 268 scoped_ptr<Fetcher> fetcher,
314 const base::FilePath& path, 269 const base::FilePath& path,
315 bool path_exists) { 270 bool path_exists) {
316 // We only passed fetcher to keep it alive. Done with it now. 271 // We only passed fetcher to keep it alive. Done with it now.
317 fetcher.reset(); 272 fetcher.reset();
318 273
319 DCHECK(application_request.is_pending()); 274 DCHECK(application_request.is_pending());
320 275
321 if (!path_exists) { 276 if (!path_exists) {
322 LOG(ERROR) << "Library not started because library path '" << path.value() 277 LOG(ERROR) << "Library not started because library path '" << path.value()
323 << "' does not exist."; 278 << "' does not exist.";
324 return; 279 return;
325 } 280 }
326 281
327 TRACE_EVENT1("mojo_shell", "ApplicationManager::RunNativeApplication", "path", 282 TRACE_EVENT1("mojo_shell", "ApplicationManager::RunNativeApplication", "path",
328 path.AsUTF8Unsafe()); 283 path.AsUTF8Unsafe());
329 NativeRunner* runner = native_runner_factory_->Create().release(); 284 NativeRunner* runner = native_runner_factory_->Create().release();
330 native_runners_.push_back(runner); 285 native_runners_.push_back(runner);
331 runner->Start(path, start_sandboxed, application_request.Pass(), 286 runner->Start(path, start_sandboxed, application_request.Pass(),
332 base::Bind(&ApplicationManager::CleanupRunner, 287 base::Bind(&ApplicationManager::CleanupRunner,
333 weak_ptr_factory_.GetWeakPtr(), runner)); 288 weak_ptr_factory_.GetWeakPtr(), runner));
334 } 289 }
335 290
336 void ApplicationManager::RegisterContentHandler(
337 const std::string& mime_type,
338 const GURL& content_handler_url) {
339 DCHECK(content_handler_url.is_valid())
340 << "Content handler URL is invalid for mime type " << mime_type;
341 mime_type_to_url_[mime_type] = content_handler_url;
342 }
343
344 void ApplicationManager::RegisterApplicationPackageAlias(
345 const GURL& alias,
346 const GURL& content_handler_package,
347 const std::string& qualifier) {
348 application_package_alias_[alias] =
349 std::make_pair(content_handler_package, qualifier);
350 }
351
352 void ApplicationManager::LoadWithContentHandler( 291 void ApplicationManager::LoadWithContentHandler(
353 const Identity& originator_identity, 292 const Identity& originator_identity,
354 const CapabilityFilter& originator_filter, 293 const CapabilityFilter& originator_filter,
355 const GURL& content_handler_url, 294 const GURL& content_handler_url,
356 const std::string& qualifier, 295 const std::string& qualifier,
357 const CapabilityFilter& filter, 296 const CapabilityFilter& filter,
358 const Shell::ConnectToApplicationCallback& connect_callback, 297 const Shell::ConnectToApplicationCallback& connect_callback,
359 ApplicationInstance* app, 298 ApplicationInstance* app,
360 InterfaceRequest<Application> application_request, 299 InterfaceRequest<Application> application_request,
361 URLResponsePtr url_response) { 300 URLResponsePtr url_response) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 services->ConnectToService(interface_name, pipe.handle1.Pass()); 375 services->ConnectToService(interface_name, pipe.handle1.Pass());
437 return pipe.handle0.Pass(); 376 return pipe.handle0.Pass();
438 } 377 }
439 378
440 Shell::ConnectToApplicationCallback EmptyConnectCallback() { 379 Shell::ConnectToApplicationCallback EmptyConnectCallback() {
441 return base::Bind(&OnEmptyOnConnectCallback); 380 return base::Bind(&OnEmptyOnConnectCallback);
442 } 381 }
443 382
444 } // namespace shell 383 } // namespace shell
445 } // namespace mojo 384 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/shell/application_manager.h ('k') | mojo/shell/application_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698