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

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: 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 return; 154 return;
143 } 155 }
144 156
145 auto callback = base::Bind(&ApplicationManager::HandleFetchCallback, 157 auto callback = base::Bind(&ApplicationManager::HandleFetchCallback,
146 weak_ptr_factory_.GetWeakPtr(), requested_url, 158 weak_ptr_factory_.GetWeakPtr(), requested_url,
147 requestor_url, base::Passed(services.Pass()), 159 requestor_url, base::Passed(services.Pass()),
148 base::Passed(exposed_services.Pass())); 160 base::Passed(exposed_services.Pass()));
149 161
150 if (resolved_url.SchemeIsFile()) { 162 if (resolved_url.SchemeIsFile()) {
151 new LocalFetcher(resolved_url, 163 new LocalFetcher(resolved_url,
164 StripQueryFromURL(resolved_url),
152 base::Bind(callback, NativeRunner::DontDeleteAppPath)); 165 base::Bind(callback, NativeRunner::DontDeleteAppPath));
153 return; 166 return;
154 } 167 }
155 168
156 if (!network_service_) 169 if (!network_service_)
157 ConnectToService(GURL("mojo:network_service"), &network_service_); 170 ConnectToService(GURL("mojo:network_service"), &network_service_);
158 171
159 new NetworkFetcher(disable_cache_, resolved_url, network_service_.get(), 172 new NetworkFetcher(disable_cache_, resolved_url, network_service_.get(),
160 base::Bind(callback, NativeRunner::DeleteAppPath)); 173 base::Bind(callback, NativeRunner::DeleteAppPath));
161 } 174 }
162 175
163 bool ApplicationManager::ConnectToRunningApplication( 176 bool ApplicationManager::ConnectToRunningApplication(
164 const GURL& application_url, 177 const GURL& resolved_url,
165 const GURL& requestor_url, 178 const GURL& requestor_url,
166 InterfaceRequest<ServiceProvider>* services, 179 InterfaceRequest<ServiceProvider>* services,
167 ServiceProviderPtr* exposed_services) { 180 ServiceProviderPtr* exposed_services) {
181 GURL application_url = StripQueryFromURL(resolved_url);
168 ShellImpl* shell_impl = GetShellImpl(application_url); 182 ShellImpl* shell_impl = GetShellImpl(application_url);
169 if (!shell_impl) 183 if (!shell_impl)
170 return false; 184 return false;
171 185
172 ConnectToClient(shell_impl, application_url, requestor_url, services->Pass(), 186 ConnectToClient(shell_impl, resolved_url, requestor_url, services->Pass(),
173 exposed_services->Pass()); 187 exposed_services->Pass());
174 return true; 188 return true;
175 } 189 }
176 190
177 bool ApplicationManager::ConnectToApplicationWithLoader( 191 bool ApplicationManager::ConnectToApplicationWithLoader(
178 const GURL& requested_url, 192 const GURL& requested_url,
179 const GURL& resolved_url, 193 const GURL& resolved_url,
180 const GURL& requestor_url, 194 const GURL& requestor_url,
181 InterfaceRequest<ServiceProvider>* services, 195 InterfaceRequest<ServiceProvider>* services,
182 ServiceProviderPtr* exposed_services, 196 ServiceProviderPtr* exposed_services,
183 ApplicationLoader* loader) { 197 ApplicationLoader* loader) {
184 if (!loader) 198 if (!loader)
185 return false; 199 return false;
186 200
187 loader->Load(resolved_url, 201 loader->Load(resolved_url,
188 RegisterShell(requested_url, resolved_url, requestor_url, 202 RegisterShell(requested_url, resolved_url, requestor_url,
189 services->Pass(), exposed_services->Pass())); 203 services->Pass(), exposed_services->Pass()));
190 return true; 204 return true;
191 } 205 }
192 206
193 InterfaceRequest<Application> ApplicationManager::RegisterShell( 207 InterfaceRequest<Application> ApplicationManager::RegisterShell(
194 const GURL& requested_url, 208 const GURL& original_url,
195 const GURL& resolved_url, 209 const GURL& resolved_url,
196 const GURL& requestor_url, 210 const GURL& requestor_url,
197 InterfaceRequest<ServiceProvider> services, 211 InterfaceRequest<ServiceProvider> services,
198 ServiceProviderPtr exposed_services) { 212 ServiceProviderPtr exposed_services) {
213 GURL app_url = StripQueryFromURL(resolved_url);
214
199 ApplicationPtr application; 215 ApplicationPtr application;
200 InterfaceRequest<Application> application_request = GetProxy(&application); 216 InterfaceRequest<Application> application_request = GetProxy(&application);
201 ShellImpl* shell = 217 ShellImpl* shell =
202 new ShellImpl(application.Pass(), this, requested_url, resolved_url); 218 new ShellImpl(application.Pass(), this, original_url, app_url);
203 url_to_shell_impl_[resolved_url] = shell; 219 url_to_shell_impl_[app_url] = shell;
204 shell->InitializeApplication(GetArgsForURL(requested_url)); 220 shell->InitializeApplication(GetArgsForURL(original_url));
qsr 2015/03/02 08:51:31 Should that be app_url? We only initialize an app
Aaron Boodman 2015/03/02 15:36:36 Yes it should be app_url. Even before this change
205 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), 221 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(),
206 exposed_services.Pass()); 222 exposed_services.Pass());
207 return application_request.Pass(); 223 return application_request.Pass();
208 } 224 }
209 225
210 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { 226 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) {
211 const auto& shell_it = url_to_shell_impl_.find(url); 227 const auto& shell_it = url_to_shell_impl_.find(url);
212 if (shell_it != url_to_shell_impl_.end()) 228 if (shell_it != url_to_shell_impl_.end())
213 return shell_it->second; 229 return shell_it->second;
214 return nullptr; 230 return nullptr;
215 } 231 }
216 232
217 void ApplicationManager::ConnectToClient( 233 void ApplicationManager::ConnectToClient(
218 ShellImpl* shell_impl, 234 ShellImpl* shell_impl,
219 const GURL& url, 235 const GURL& resolved_url,
220 const GURL& requestor_url, 236 const GURL& requestor_url,
221 InterfaceRequest<ServiceProvider> services, 237 InterfaceRequest<ServiceProvider> services,
222 ServiceProviderPtr exposed_services) { 238 ServiceProviderPtr exposed_services) {
223 shell_impl->ConnectToClient(requestor_url, services.Pass(), 239 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(),
224 exposed_services.Pass()); 240 exposed_services.Pass());
225 } 241 }
226 242
227 void ApplicationManager::HandleFetchCallback( 243 void ApplicationManager::HandleFetchCallback(
228 const GURL& requested_url, 244 const GURL& requested_url,
229 const GURL& requestor_url, 245 const GURL& requestor_url,
230 InterfaceRequest<ServiceProvider> services, 246 InterfaceRequest<ServiceProvider> services,
231 ServiceProviderPtr exposed_services, 247 ServiceProviderPtr exposed_services,
232 NativeRunner::CleanupBehavior cleanup_behavior, 248 NativeRunner::CleanupBehavior cleanup_behavior,
233 scoped_ptr<Fetcher> fetcher) { 249 scoped_ptr<Fetcher> fetcher) {
(...skipping 14 matching lines...) Expand all
248 // it might have started while the fetch was outstanding. We don't want to 264 // 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. 265 // have two copies of the app running, so check again.
250 // 266 //
251 // Also, it's possible the original URL was redirected to an app that is 267 // Also, it's possible the original URL was redirected to an app that is
252 // already running. 268 // already running.
253 if (ConnectToRunningApplication(fetcher->GetURL(), requestor_url, &services, 269 if (ConnectToRunningApplication(fetcher->GetURL(), 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