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

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

Issue 943053003: Simple multi-url support for mojo apps (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: hate Created 5 years, 9 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
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 "shell/application_manager/application_manager.h" 5 #include "shell/application_manager/application_manager.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/string_util.h"
14 #include "mojo/public/cpp/bindings/binding.h" 15 #include "mojo/public/cpp/bindings/binding.h"
15 #include "mojo/public/cpp/bindings/error_handler.h" 16 #include "mojo/public/cpp/bindings/error_handler.h"
16 #include "mojo/public/interfaces/application/shell.mojom.h" 17 #include "mojo/public/interfaces/application/shell.mojom.h"
17 #include "mojo/services/content_handler/public/interfaces/content_handler.mojom. h" 18 #include "mojo/services/content_handler/public/interfaces/content_handler.mojom. h"
18 #include "shell/application_manager/fetcher.h" 19 #include "shell/application_manager/fetcher.h"
19 #include "shell/application_manager/local_fetcher.h" 20 #include "shell/application_manager/local_fetcher.h"
20 #include "shell/application_manager/network_fetcher.h" 21 #include "shell/application_manager/network_fetcher.h"
21 22
22 namespace mojo { 23 namespace mojo {
23 24
24 namespace { 25 namespace {
25 // Used by TestAPI. 26 // Used by TestAPI.
26 bool has_created_instance = false; 27 bool has_created_instance = false;
28
29 GURL StripQueryFromURL(const GURL& url) {
30 GURL::Replacements repl;
31 repl.SetQueryStr("");
32 std::string result = url.ReplaceComponents(repl).spec();
33
34 // Remove the dangling '?' because it's ugly.
35 base::ReplaceChars(result, "?", "", &result);
36 return GURL(result);
37 }
38
27 } // namespace 39 } // namespace
28 40
29 ApplicationManager::Delegate::~Delegate() { 41 ApplicationManager::Delegate::~Delegate() {
30 } 42 }
31 43
32 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { 44 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) {
33 LOG(ERROR) << "Communication error with application: " << url.spec(); 45 LOG(ERROR) << "Communication error with application: " << url.spec();
34 } 46 }
35 47
36 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { 48 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 void ApplicationManager::ConnectToApplication( 117 void ApplicationManager::ConnectToApplication(
106 const GURL& requested_url, 118 const GURL& requested_url,
107 const GURL& requestor_url, 119 const GURL& requestor_url,
108 InterfaceRequest<ServiceProvider> services, 120 InterfaceRequest<ServiceProvider> services,
109 ServiceProviderPtr exposed_services) { 121 ServiceProviderPtr exposed_services) {
110 DCHECK(requested_url.is_valid()); 122 DCHECK(requested_url.is_valid());
111 123
112 // We check both the mapped and resolved urls for existing shell_impls because 124 // We check both the mapped and resolved urls for existing shell_impls because
113 // external applications can be registered for the unresolved mojo:foo urls. 125 // external applications can be registered for the unresolved mojo:foo urls.
114 126
115 GURL mapped_url = delegate_->ResolveMappings(requested_url); 127 GURL mapped_url = delegate_->ResolveMappings(requested_url);
qsr 2015/02/27 17:17:43 Don't you need to modify those methods to keep the
Aaron Boodman 2015/02/28 19:08:23 I don't follow you.
qsr 2015/03/02 08:51:31 I think URLResolver::ApplyMappings needs to be upd
Aaron Boodman 2015/03/02 15:36:36 Perhaps. I think that should be a separate change
116 if (ConnectToRunningApplication(mapped_url, requestor_url, &services, 128 if (ConnectToRunningApplication(mapped_url, requestor_url,
117 &exposed_services)) { 129 &services, &exposed_services)) {
118 return; 130 return;
119 } 131 }
120 132
121 GURL resolved_url = delegate_->ResolveURL(mapped_url); 133 GURL resolved_url = delegate_->ResolveURL(mapped_url);
122 if (ConnectToRunningApplication(resolved_url, requestor_url, &services, 134 if (ConnectToRunningApplication(resolved_url, requestor_url,
123 &exposed_services)) { 135 &services, &exposed_services)) {
124 return; 136 return;
125 } 137 }
126 138
127 if (ConnectToApplicationWithLoader(requested_url, mapped_url, requestor_url, 139 if (ConnectToApplicationWithLoader(requested_url, mapped_url, requestor_url,
128 &services, &exposed_services, 140 &services, &exposed_services,
129 GetLoaderForURL(mapped_url))) { 141 GetLoaderForURL(mapped_url))) {
130 return; 142 return;
131 } 143 }
132 144
133 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, 145 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url,
(...skipping 20 matching lines...) Expand all
154 } 166 }
155 167
156 if (!network_service_) 168 if (!network_service_)
157 ConnectToService(GURL("mojo:network_service"), &network_service_); 169 ConnectToService(GURL("mojo:network_service"), &network_service_);
158 170
159 new NetworkFetcher(disable_cache_, resolved_url, network_service_.get(), 171 new NetworkFetcher(disable_cache_, resolved_url, network_service_.get(),
160 base::Bind(callback, NativeRunner::DeleteAppPath)); 172 base::Bind(callback, NativeRunner::DeleteAppPath));
161 } 173 }
162 174
163 bool ApplicationManager::ConnectToRunningApplication( 175 bool ApplicationManager::ConnectToRunningApplication(
164 const GURL& application_url, 176 const GURL& resolved_url,
165 const GURL& requestor_url, 177 const GURL& requestor_url,
166 InterfaceRequest<ServiceProvider>* services, 178 InterfaceRequest<ServiceProvider>* services,
167 ServiceProviderPtr* exposed_services) { 179 ServiceProviderPtr* exposed_services) {
180 GURL application_url = StripQueryFromURL(resolved_url);
168 ShellImpl* shell_impl = GetShellImpl(application_url); 181 ShellImpl* shell_impl = GetShellImpl(application_url);
169 if (!shell_impl) 182 if (!shell_impl)
170 return false; 183 return false;
171 184
172 ConnectToClient(shell_impl, application_url, requestor_url, services->Pass(), 185 ConnectToClient(shell_impl, resolved_url, requestor_url,
173 exposed_services->Pass()); 186 services->Pass(), exposed_services->Pass());
174 return true; 187 return true;
175 } 188 }
176 189
177 bool ApplicationManager::ConnectToApplicationWithLoader( 190 bool ApplicationManager::ConnectToApplicationWithLoader(
178 const GURL& requested_url, 191 const GURL& requested_url,
179 const GURL& resolved_url, 192 const GURL& resolved_url,
180 const GURL& requestor_url, 193 const GURL& requestor_url,
181 InterfaceRequest<ServiceProvider>* services, 194 InterfaceRequest<ServiceProvider>* services,
182 ServiceProviderPtr* exposed_services, 195 ServiceProviderPtr* exposed_services,
183 ApplicationLoader* loader) { 196 ApplicationLoader* loader) {
184 if (!loader) 197 if (!loader)
185 return false; 198 return false;
186 199
187 loader->Load(resolved_url, 200 loader->Load(resolved_url,
188 RegisterShell(requested_url, resolved_url, requestor_url, 201 RegisterShell(requested_url, resolved_url, requestor_url,
189 services->Pass(), exposed_services->Pass())); 202 services->Pass(), exposed_services->Pass()));
190 return true; 203 return true;
191 } 204 }
192 205
193 InterfaceRequest<Application> ApplicationManager::RegisterShell( 206 InterfaceRequest<Application> ApplicationManager::RegisterShell(
194 const GURL& requested_url, 207 const GURL& requested_url,
195 const GURL& resolved_url, 208 GURL resolved_url,
196 const GURL& requestor_url, 209 const GURL& requestor_url,
197 InterfaceRequest<ServiceProvider> services, 210 InterfaceRequest<ServiceProvider> services,
198 ServiceProviderPtr exposed_services) { 211 ServiceProviderPtr exposed_services) {
212 resolved_url = StripQueryFromURL(resolved_url);
213
199 ApplicationPtr application; 214 ApplicationPtr application;
200 InterfaceRequest<Application> application_request = GetProxy(&application); 215 InterfaceRequest<Application> application_request = GetProxy(&application);
201 ShellImpl* shell = 216 ShellImpl* shell =
202 new ShellImpl(application.Pass(), this, requested_url, resolved_url); 217 new ShellImpl(application.Pass(), this, requested_url, resolved_url);
203 url_to_shell_impl_[resolved_url] = shell; 218 url_to_shell_impl_[resolved_url] = shell;
204 shell->InitializeApplication(GetArgsForURL(requested_url)); 219 shell->InitializeApplication(GetArgsForURL(requested_url));
205 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), 220 ConnectToClient(shell, resolved_url, requestor_url,
206 exposed_services.Pass()); 221 services.Pass(), exposed_services.Pass());
207 return application_request.Pass(); 222 return application_request.Pass();
208 } 223 }
209 224
210 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { 225 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) {
211 const auto& shell_it = url_to_shell_impl_.find(url); 226 const auto& shell_it = url_to_shell_impl_.find(url);
212 if (shell_it != url_to_shell_impl_.end()) 227 if (shell_it != url_to_shell_impl_.end())
213 return shell_it->second; 228 return shell_it->second;
214 return nullptr; 229 return nullptr;
215 } 230 }
216 231
217 void ApplicationManager::ConnectToClient( 232 void ApplicationManager::ConnectToClient(
218 ShellImpl* shell_impl, 233 ShellImpl* shell_impl,
219 const GURL& url, 234 const GURL& resolved_url,
220 const GURL& requestor_url, 235 const GURL& requestor_url,
221 InterfaceRequest<ServiceProvider> services, 236 InterfaceRequest<ServiceProvider> services,
222 ServiceProviderPtr exposed_services) { 237 ServiceProviderPtr exposed_services) {
223 shell_impl->ConnectToClient(requestor_url, services.Pass(), 238 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(),
224 exposed_services.Pass()); 239 exposed_services.Pass());
225 } 240 }
226 241
227 void ApplicationManager::HandleFetchCallback( 242 void ApplicationManager::HandleFetchCallback(
228 const GURL& requested_url, 243 const GURL& requested_url,
229 const GURL& requestor_url, 244 const GURL& requestor_url,
230 InterfaceRequest<ServiceProvider> services, 245 InterfaceRequest<ServiceProvider> services,
231 ServiceProviderPtr exposed_services, 246 ServiceProviderPtr exposed_services,
232 NativeRunner::CleanupBehavior cleanup_behavior, 247 NativeRunner::CleanupBehavior cleanup_behavior,
233 scoped_ptr<Fetcher> fetcher) { 248 scoped_ptr<Fetcher> fetcher) {
234 if (!fetcher) { 249 if (!fetcher) {
235 // Network error. Drop |application_request| to tell requestor. 250 // Network error. Drop |application_request| to tell requestor.
236 return; 251 return;
237 } 252 }
238 253
239 GURL redirect_url = fetcher->GetRedirectURL(); 254 GURL redirect_url = fetcher->GetRedirectURL();
240 if (!redirect_url.is_empty()) { 255 if (!redirect_url.is_empty()) {
241 // And around we go again... Whee! 256 // And around we go again... Whee!
242 ConnectToApplication(redirect_url, requestor_url, services.Pass(), 257 ConnectToApplication(redirect_url, requestor_url, services.Pass(),
243 exposed_services.Pass()); 258 exposed_services.Pass());
244 return; 259 return;
245 } 260 }
246 261
247 // We already checked if the application was running before we fetched it, but 262 // We already checked if the application was running before we fetched it, but
248 // it might have started while the fetch was outstanding. We don't want to 263 // it might have started while the fetch was outstanding. We don't want to
249 // have two copies of the app running, so check again. 264 // have two copies of the app running, so check again.
250 // 265 //
251 // Also, it's possible the original URL was redirected to an app that is 266 // Also, it's possible the original URL was redirected to an app that is
252 // already running. 267 // already running.
253 if (ConnectToRunningApplication(fetcher->GetURL(), requestor_url, &services, 268 if (ConnectToRunningApplication(fetcher->GetURL(),
269 requestor_url, &services,
254 &exposed_services)) { 270 &exposed_services)) {
255 return; 271 return;
256 } 272 }
257 273
258 InterfaceRequest<Application> application_request( 274 InterfaceRequest<Application> request(
259 RegisterShell(requested_url, fetcher->GetURL(), requestor_url, 275 RegisterShell(requested_url, fetcher->GetURL(), requestor_url,
260 services.Pass(), exposed_services.Pass())); 276 services.Pass(), exposed_services.Pass()));
261 277
262 // If the response begins with a #!mojo <content-handler-url>, use it. 278 // If the response begins with a #!mojo <content-handler-url>, use it.
263 GURL content_handler_url; 279 GURL content_handler_url;
264 std::string shebang; 280 std::string shebang;
265 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { 281 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) {
266 LoadWithContentHandler( 282 LoadWithContentHandler(
267 content_handler_url, application_request.Pass(), 283 content_handler_url, request.Pass(),
268 fetcher->AsURLResponse(blocking_pool_, 284 fetcher->AsURLResponse(blocking_pool_,
269 static_cast<int>(shebang.size()))); 285 static_cast<int>(shebang.size())));
270 return; 286 return;
271 } 287 }
272 288
273 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); 289 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType());
274 if (iter != mime_type_to_url_.end()) { 290 if (iter != mime_type_to_url_.end()) {
275 LoadWithContentHandler(iter->second, application_request.Pass(), 291 LoadWithContentHandler(iter->second, request.Pass(),
276 fetcher->AsURLResponse(blocking_pool_, 0)); 292 fetcher->AsURLResponse(blocking_pool_, 0));
277 return; 293 return;
278 } 294 }
279 295
280 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo 296 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo
281 // application. That could either mean looking for the platform-specific dll 297 // application. That could either mean looking for the platform-specific dll
282 // header, or looking for some specific mojo signature prepended to the 298 // header, or looking for some specific mojo signature prepended to the
283 // library. 299 // library.
284 300
285 fetcher->AsPath(blocking_pool_, 301 fetcher->AsPath(
286 base::Bind(&ApplicationManager::RunNativeApplication, 302 blocking_pool_,
287 weak_ptr_factory_.GetWeakPtr(), 303 base::Bind(&ApplicationManager::RunNativeApplication,
288 base::Passed(application_request.Pass()), 304 weak_ptr_factory_.GetWeakPtr(), base::Passed(request.Pass()),
289 cleanup_behavior, base::Passed(fetcher.Pass()))); 305 cleanup_behavior, base::Passed(fetcher.Pass())));
290 } 306 }
291 307
292 void ApplicationManager::RunNativeApplication( 308 void ApplicationManager::RunNativeApplication(
293 InterfaceRequest<Application> application_request, 309 InterfaceRequest<Application> application_request,
294 NativeRunner::CleanupBehavior cleanup_behavior, 310 NativeRunner::CleanupBehavior cleanup_behavior,
295 scoped_ptr<Fetcher> fetcher, 311 scoped_ptr<Fetcher> fetcher,
296 const base::FilePath& path, 312 const base::FilePath& path,
297 bool path_exists) { 313 bool path_exists) {
298 // We only passed fetcher to keep it alive. Done with it now. 314 // We only passed fetcher to keep it alive. Done with it now.
299 fetcher.reset(); 315 fetcher.reset();
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 return Array<String>::From(args_it->second); 439 return Array<String>::From(args_it->second);
424 return Array<String>(); 440 return Array<String>();
425 } 441 }
426 442
427 void ApplicationManager::CleanupRunner(NativeRunner* runner) { 443 void ApplicationManager::CleanupRunner(NativeRunner* runner) {
428 native_runners_.erase( 444 native_runners_.erase(
429 std::find(native_runners_.begin(), native_runners_.end(), runner)); 445 std::find(native_runners_.begin(), native_runners_.end(), runner));
430 } 446 }
431 447
432 } // namespace mojo 448 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698