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

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: rebase + fix android 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 default_loader_.get())) { 153 default_loader_.get())) {
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, StripQueryFromURL(resolved_url),
152 base::Bind(callback, NativeRunner::DontDeleteAppPath)); 164 base::Bind(callback, NativeRunner::DontDeleteAppPath));
153 return; 165 return;
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, services->Pass(),
173 exposed_services->Pass()); 186 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& original_url,
195 const GURL& resolved_url, 208 const 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 GURL app_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, original_url, app_url);
203 url_to_shell_impl_[resolved_url] = shell; 218 url_to_shell_impl_[app_url] = shell;
204 shell->InitializeApplication(GetArgsForURL(requested_url)); 219 shell->InitializeApplication(GetArgsForURL(original_url));
205 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), 220 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(),
206 exposed_services.Pass()); 221 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) {
(...skipping 14 matching lines...) Expand all
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(), requestor_url, &services,
254 &exposed_services)) { 269 &exposed_services)) {
255 return; 270 return;
256 } 271 }
257 272
258 InterfaceRequest<Application> application_request( 273 InterfaceRequest<Application> request(
259 RegisterShell(requested_url, fetcher->GetURL(), requestor_url, 274 RegisterShell(requested_url, fetcher->GetURL(), requestor_url,
260 services.Pass(), exposed_services.Pass())); 275 services.Pass(), exposed_services.Pass()));
261 276
262 // If the response begins with a #!mojo <content-handler-url>, use it. 277 // If the response begins with a #!mojo <content-handler-url>, use it.
263 GURL content_handler_url; 278 GURL content_handler_url;
264 std::string shebang; 279 std::string shebang;
265 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { 280 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) {
266 LoadWithContentHandler( 281 LoadWithContentHandler(
267 content_handler_url, application_request.Pass(), 282 content_handler_url, request.Pass(),
268 fetcher->AsURLResponse(blocking_pool_, 283 fetcher->AsURLResponse(blocking_pool_,
269 static_cast<int>(shebang.size()))); 284 static_cast<int>(shebang.size())));
270 return; 285 return;
271 } 286 }
272 287
273 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); 288 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType());
274 if (iter != mime_type_to_url_.end()) { 289 if (iter != mime_type_to_url_.end()) {
275 LoadWithContentHandler(iter->second, application_request.Pass(), 290 LoadWithContentHandler(iter->second, request.Pass(),
276 fetcher->AsURLResponse(blocking_pool_, 0)); 291 fetcher->AsURLResponse(blocking_pool_, 0));
277 return; 292 return;
278 } 293 }
279 294
280 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo 295 // 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 296 // application. That could either mean looking for the platform-specific dll
282 // header, or looking for some specific mojo signature prepended to the 297 // header, or looking for some specific mojo signature prepended to the
283 // library. 298 // library.
284 299
285 fetcher->AsPath(blocking_pool_, 300 fetcher->AsPath(
286 base::Bind(&ApplicationManager::RunNativeApplication, 301 blocking_pool_,
287 weak_ptr_factory_.GetWeakPtr(), 302 base::Bind(&ApplicationManager::RunNativeApplication,
288 base::Passed(application_request.Pass()), 303 weak_ptr_factory_.GetWeakPtr(), base::Passed(request.Pass()),
289 cleanup_behavior, base::Passed(fetcher.Pass()))); 304 cleanup_behavior, base::Passed(fetcher.Pass())));
290 } 305 }
291 306
292 void ApplicationManager::RunNativeApplication( 307 void ApplicationManager::RunNativeApplication(
293 InterfaceRequest<Application> application_request, 308 InterfaceRequest<Application> application_request,
294 NativeRunner::CleanupBehavior cleanup_behavior, 309 NativeRunner::CleanupBehavior cleanup_behavior,
295 scoped_ptr<Fetcher> fetcher, 310 scoped_ptr<Fetcher> fetcher,
296 const base::FilePath& path, 311 const base::FilePath& path,
297 bool path_exists) { 312 bool path_exists) {
298 // We only passed fetcher to keep it alive. Done with it now. 313 // We only passed fetcher to keep it alive. Done with it now.
299 fetcher.reset(); 314 fetcher.reset();
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 return Array<String>::From(args_it->second); 438 return Array<String>::From(args_it->second);
424 return Array<String>(); 439 return Array<String>();
425 } 440 }
426 441
427 void ApplicationManager::CleanupRunner(NativeRunner* runner) { 442 void ApplicationManager::CleanupRunner(NativeRunner* runner) {
428 native_runners_.erase( 443 native_runners_.erase(
429 std::find(native_runners_.begin(), native_runners_.end(), runner)); 444 std::find(native_runners_.begin(), native_runners_.end(), runner));
430 } 445 }
431 446
432 } // namespace mojo 447 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698