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

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

Issue 983113002: ApplicationManager: Use callback to get notified on application shutdown. (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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 13 matching lines...) Expand all
24 namespace { 24 namespace {
25 25
26 // Used by TestAPI. 26 // Used by TestAPI.
27 bool has_created_instance = false; 27 bool has_created_instance = false;
28 28
29 } // namespace 29 } // namespace
30 30
31 ApplicationManager::Delegate::~Delegate() { 31 ApplicationManager::Delegate::~Delegate() {
32 } 32 }
33 33
34 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) {
35 LOG(ERROR) << "Communication error with application: " << url.spec();
36 }
37
38 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { 34 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) {
39 return url; 35 return url;
40 } 36 }
41 37
42 GURL ApplicationManager::Delegate::ResolveMappings(const GURL& url) { 38 GURL ApplicationManager::Delegate::ResolveMappings(const GURL& url) {
43 return url; 39 return url;
44 } 40 }
45 41
46 class ApplicationManager::ContentHandlerConnection : public ErrorHandler { 42 class ApplicationManager::ContentHandlerConnection : public ErrorHandler {
47 public: 43 public:
48 ContentHandlerConnection(ApplicationManager* manager, 44 ContentHandlerConnection(ApplicationManager* manager,
49 const GURL& content_handler_url) 45 const GURL& content_handler_url)
50 : manager_(manager), content_handler_url_(content_handler_url) { 46 : manager_(manager), content_handler_url_(content_handler_url) {
51 ServiceProviderPtr services; 47 ServiceProviderPtr services;
52 manager->ConnectToApplication(content_handler_url, GURL(), 48 manager->ConnectToApplication(content_handler_url, GURL(),
53 GetProxy(&services), nullptr); 49 GetProxy(&services), nullptr,
50 base::Closure());
54 MessagePipe pipe; 51 MessagePipe pipe;
55 content_handler_.Bind(pipe.handle0.Pass()); 52 content_handler_.Bind(pipe.handle0.Pass());
56 services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass()); 53 services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass());
57 content_handler_.set_error_handler(this); 54 content_handler_.set_error_handler(this);
58 } 55 }
59 56
60 ContentHandler* content_handler() { return content_handler_.get(); } 57 ContentHandler* content_handler() { return content_handler_.get(); }
61 58
62 GURL content_handler_url() { return content_handler_url_; } 59 GURL content_handler_url() { return content_handler_url_; }
63 60
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 } 98 }
102 99
103 void ApplicationManager::TerminateShellConnections() { 100 void ApplicationManager::TerminateShellConnections() {
104 STLDeleteValues(&url_to_shell_impl_); 101 STLDeleteValues(&url_to_shell_impl_);
105 } 102 }
106 103
107 void ApplicationManager::ConnectToApplication( 104 void ApplicationManager::ConnectToApplication(
108 const GURL& requested_url, 105 const GURL& requested_url,
109 const GURL& requestor_url, 106 const GURL& requestor_url,
110 InterfaceRequest<ServiceProvider> services, 107 InterfaceRequest<ServiceProvider> services,
111 ServiceProviderPtr exposed_services) { 108 ServiceProviderPtr exposed_services,
109 const base::Closure& on_application_end) {
112 DCHECK(requested_url.is_valid()); 110 DCHECK(requested_url.is_valid());
113 111
114 // We check both the mapped and resolved urls for existing shell_impls because 112 // We check both the mapped and resolved urls for existing shell_impls because
115 // external applications can be registered for the unresolved mojo:foo urls. 113 // external applications can be registered for the unresolved mojo:foo urls.
116 114
117 GURL mapped_url = delegate_->ResolveMappings(requested_url); 115 GURL mapped_url = delegate_->ResolveMappings(requested_url);
118 if (ConnectToRunningApplication(mapped_url, requestor_url, &services, 116 if (ConnectToRunningApplication(mapped_url, requestor_url, &services,
119 &exposed_services)) { 117 &exposed_services)) {
120 return; 118 return;
121 } 119 }
122 120
123 GURL resolved_url = delegate_->ResolveURL(mapped_url); 121 GURL resolved_url = delegate_->ResolveURL(mapped_url);
124 if (ConnectToRunningApplication(resolved_url, requestor_url, &services, 122 if (ConnectToRunningApplication(resolved_url, requestor_url, &services,
125 &exposed_services)) { 123 &exposed_services)) {
126 return; 124 return;
127 } 125 }
128 126
129 if (ConnectToApplicationWithLoader(requested_url, mapped_url, requestor_url, 127 if (ConnectToApplicationWithLoader(mapped_url, requestor_url, &services,
130 &services, &exposed_services, 128 &exposed_services, on_application_end,
131 GetLoaderForURL(mapped_url))) { 129 GetLoaderForURL(mapped_url))) {
132 return; 130 return;
133 } 131 }
134 132
135 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, 133 if (ConnectToApplicationWithLoader(resolved_url, requestor_url, &services,
136 &services, &exposed_services, 134 &exposed_services, on_application_end,
137 GetLoaderForURL(resolved_url))) { 135 GetLoaderForURL(resolved_url))) {
138 return; 136 return;
139 } 137 }
140 138
141 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, 139 if (ConnectToApplicationWithLoader(resolved_url, requestor_url, &services,
142 &services, &exposed_services, 140 &exposed_services, on_application_end,
143 default_loader_.get())) { 141 default_loader_.get())) {
144 return; 142 return;
145 } 143 }
146 144
147 auto callback = base::Bind(&ApplicationManager::HandleFetchCallback, 145 auto callback = base::Bind(
148 weak_ptr_factory_.GetWeakPtr(), requested_url, 146 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(),
149 requestor_url, base::Passed(services.Pass()), 147 requestor_url, base::Passed(services.Pass()),
150 base::Passed(exposed_services.Pass())); 148 base::Passed(exposed_services.Pass()), on_application_end);
151 149
152 if (resolved_url.SchemeIsFile()) { 150 if (resolved_url.SchemeIsFile()) {
153 new LocalFetcher(resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), 151 new LocalFetcher(resolved_url, GetBaseURLAndQuery(resolved_url, nullptr),
154 base::Bind(callback, NativeRunner::DontDeleteAppPath)); 152 base::Bind(callback, NativeRunner::DontDeleteAppPath));
155 return; 153 return;
156 } 154 }
157 155
158 if (!network_service_) 156 if (!network_service_)
159 ConnectToService(GURL("mojo:network_service"), &network_service_); 157 ConnectToService(GURL("mojo:network_service"), &network_service_);
160 158
(...skipping 10 matching lines...) Expand all
171 ShellImpl* shell_impl = GetShellImpl(application_url); 169 ShellImpl* shell_impl = GetShellImpl(application_url);
172 if (!shell_impl) 170 if (!shell_impl)
173 return false; 171 return false;
174 172
175 ConnectToClient(shell_impl, resolved_url, requestor_url, services->Pass(), 173 ConnectToClient(shell_impl, resolved_url, requestor_url, services->Pass(),
176 exposed_services->Pass()); 174 exposed_services->Pass());
177 return true; 175 return true;
178 } 176 }
179 177
180 bool ApplicationManager::ConnectToApplicationWithLoader( 178 bool ApplicationManager::ConnectToApplicationWithLoader(
181 const GURL& requested_url,
182 const GURL& resolved_url, 179 const GURL& resolved_url,
183 const GURL& requestor_url, 180 const GURL& requestor_url,
184 InterfaceRequest<ServiceProvider>* services, 181 InterfaceRequest<ServiceProvider>* services,
185 ServiceProviderPtr* exposed_services, 182 ServiceProviderPtr* exposed_services,
183 const base::Closure& on_application_end,
186 ApplicationLoader* loader) { 184 ApplicationLoader* loader) {
187 if (!loader) 185 if (!loader)
188 return false; 186 return false;
189 187
190 loader->Load(resolved_url, 188 loader->Load(resolved_url,
191 RegisterShell(requested_url, resolved_url, requestor_url, 189 RegisterShell(resolved_url, requestor_url, services->Pass(),
192 services->Pass(), exposed_services->Pass())); 190 exposed_services->Pass(), on_application_end));
193 return true; 191 return true;
194 } 192 }
195 193
196 InterfaceRequest<Application> ApplicationManager::RegisterShell( 194 InterfaceRequest<Application> ApplicationManager::RegisterShell(
197 const GURL& original_url,
198 const GURL& resolved_url, 195 const GURL& resolved_url,
199 const GURL& requestor_url, 196 const GURL& requestor_url,
200 InterfaceRequest<ServiceProvider> services, 197 InterfaceRequest<ServiceProvider> services,
201 ServiceProviderPtr exposed_services) { 198 ServiceProviderPtr exposed_services,
199 const base::Closure& on_application_end) {
202 GURL app_url = GetBaseURLAndQuery(resolved_url, nullptr); 200 GURL app_url = GetBaseURLAndQuery(resolved_url, nullptr);
203 201
204 ApplicationPtr application; 202 ApplicationPtr application;
205 InterfaceRequest<Application> application_request = GetProxy(&application); 203 InterfaceRequest<Application> application_request = GetProxy(&application);
206 ShellImpl* shell = 204 ShellImpl* shell =
207 new ShellImpl(application.Pass(), this, original_url, app_url); 205 new ShellImpl(application.Pass(), this, app_url, on_application_end);
208 url_to_shell_impl_[app_url] = shell; 206 url_to_shell_impl_[app_url] = shell;
209 shell->InitializeApplication(GetArgsForURL(original_url)); 207 shell->InitializeApplication(GetArgsForURL(app_url));
qsr 2015/03/09 16:50:21 I cannot push this until this is fixed -> this cha
210 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), 208 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(),
211 exposed_services.Pass()); 209 exposed_services.Pass());
212 return application_request.Pass(); 210 return application_request.Pass();
213 } 211 }
214 212
215 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { 213 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) {
216 const auto& shell_it = url_to_shell_impl_.find(url); 214 const auto& shell_it = url_to_shell_impl_.find(url);
217 if (shell_it != url_to_shell_impl_.end()) 215 if (shell_it != url_to_shell_impl_.end())
218 return shell_it->second; 216 return shell_it->second;
219 return nullptr; 217 return nullptr;
220 } 218 }
221 219
222 void ApplicationManager::ConnectToClient( 220 void ApplicationManager::ConnectToClient(
223 ShellImpl* shell_impl, 221 ShellImpl* shell_impl,
224 const GURL& resolved_url, 222 const GURL& resolved_url,
225 const GURL& requestor_url, 223 const GURL& requestor_url,
226 InterfaceRequest<ServiceProvider> services, 224 InterfaceRequest<ServiceProvider> services,
227 ServiceProviderPtr exposed_services) { 225 ServiceProviderPtr exposed_services) {
228 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(), 226 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(),
229 exposed_services.Pass()); 227 exposed_services.Pass());
230 } 228 }
231 229
232 void ApplicationManager::HandleFetchCallback( 230 void ApplicationManager::HandleFetchCallback(
233 const GURL& requested_url,
234 const GURL& requestor_url, 231 const GURL& requestor_url,
235 InterfaceRequest<ServiceProvider> services, 232 InterfaceRequest<ServiceProvider> services,
236 ServiceProviderPtr exposed_services, 233 ServiceProviderPtr exposed_services,
234 const base::Closure& on_application_end,
237 NativeRunner::CleanupBehavior cleanup_behavior, 235 NativeRunner::CleanupBehavior cleanup_behavior,
238 scoped_ptr<Fetcher> fetcher) { 236 scoped_ptr<Fetcher> fetcher) {
239 if (!fetcher) { 237 if (!fetcher) {
240 // Network error. Drop |application_request| to tell requestor. 238 // Network error. Drop |application_request| to tell requestor.
241 return; 239 return;
242 } 240 }
243 241
244 GURL redirect_url = fetcher->GetRedirectURL(); 242 GURL redirect_url = fetcher->GetRedirectURL();
245 if (!redirect_url.is_empty()) { 243 if (!redirect_url.is_empty()) {
246 // And around we go again... Whee! 244 // And around we go again... Whee!
247 ConnectToApplication(redirect_url, requestor_url, services.Pass(), 245 ConnectToApplication(redirect_url, requestor_url, services.Pass(),
248 exposed_services.Pass()); 246 exposed_services.Pass(), on_application_end);
249 return; 247 return;
250 } 248 }
251 249
252 // We already checked if the application was running before we fetched it, but 250 // We already checked if the application was running before we fetched it, but
253 // it might have started while the fetch was outstanding. We don't want to 251 // it might have started while the fetch was outstanding. We don't want to
254 // have two copies of the app running, so check again. 252 // have two copies of the app running, so check again.
255 // 253 //
256 // Also, it's possible the original URL was redirected to an app that is 254 // Also, it's possible the original URL was redirected to an app that is
257 // already running. 255 // already running.
258 if (ConnectToRunningApplication(fetcher->GetURL(), requestor_url, &services, 256 if (ConnectToRunningApplication(fetcher->GetURL(), requestor_url, &services,
259 &exposed_services)) { 257 &exposed_services)) {
260 return; 258 return;
261 } 259 }
262 260
263 InterfaceRequest<Application> request( 261 InterfaceRequest<Application> request(
264 RegisterShell(requested_url, fetcher->GetURL(), requestor_url, 262 RegisterShell(fetcher->GetURL(), requestor_url, services.Pass(),
265 services.Pass(), exposed_services.Pass())); 263 exposed_services.Pass(), on_application_end));
266 264
267 // If the response begins with a #!mojo <content-handler-url>, use it. 265 // If the response begins with a #!mojo <content-handler-url>, use it.
268 GURL content_handler_url; 266 GURL content_handler_url;
269 std::string shebang; 267 std::string shebang;
270 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { 268 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) {
271 LoadWithContentHandler( 269 LoadWithContentHandler(
272 content_handler_url, request.Pass(), 270 content_handler_url, request.Pass(),
273 fetcher->AsURLResponse(blocking_pool_, 271 fetcher->AsURLResponse(blocking_pool_,
274 static_cast<int>(shebang.size()))); 272 static_cast<int>(shebang.size())));
275 return; 273 return;
276 } 274 }
277 275
278 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); 276 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType());
279 if (iter != mime_type_to_url_.end()) { 277 if (iter != mime_type_to_url_.end()) {
280 LoadWithContentHandler(iter->second, request.Pass(), 278 LoadWithContentHandler(iter->second, request.Pass(),
281 fetcher->AsURLResponse(blocking_pool_, 0)); 279 fetcher->AsURLResponse(blocking_pool_, 0));
282 return; 280 return;
283 } 281 }
284 282
285 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo 283 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo
286 // application. That could either mean looking for the platform-specific dll 284 // application. That could either mean looking for the platform-specific dll
287 // header, or looking for some specific mojo signature prepended to the 285 // header, or looking for some specific mojo signature prepended to the
288 // library. 286 // library.
289 // TODO(vtl): (Maybe this should be done by the factory/runner?) 287 // TODO(vtl): (Maybe this should be done by the factory/runner?)
290 288
291 NativeRunnerFactory::Options options; 289 NativeRunnerFactory::Options options;
292 if (url_to_native_options_.find(fetcher->GetURL()) != 290 if (url_to_native_options_.find(fetcher->GetURL()) !=
293 url_to_native_options_.end()) { 291 url_to_native_options_.end()) {
294 DVLOG(2) << "Applying stored native options to resolved URL " 292 DVLOG(2) << "Applying stored native options to resolved URL "
295 << fetcher->GetURL() << " (requested URL " << requested_url << ")"; 293 << fetcher->GetURL();
296 options = url_to_native_options_[fetcher->GetURL()]; 294 options = url_to_native_options_[fetcher->GetURL()];
297 } 295 }
298 296
299 fetcher->AsPath( 297 fetcher->AsPath(
300 blocking_pool_, 298 blocking_pool_,
301 base::Bind(&ApplicationManager::RunNativeApplication, 299 base::Bind(&ApplicationManager::RunNativeApplication,
302 weak_ptr_factory_.GetWeakPtr(), base::Passed(request.Pass()), 300 weak_ptr_factory_.GetWeakPtr(), base::Passed(request.Pass()),
303 options, cleanup_behavior, base::Passed(fetcher.Pass()))); 301 options, cleanup_behavior, base::Passed(fetcher.Pass())));
304 } 302 }
305 303
(...skipping 24 matching lines...) Expand all
330 328
331 void ApplicationManager::RegisterExternalApplication( 329 void ApplicationManager::RegisterExternalApplication(
332 const GURL& url, 330 const GURL& url,
333 const std::vector<std::string>& args, 331 const std::vector<std::string>& args,
334 ApplicationPtr application) { 332 ApplicationPtr application) {
335 const auto& args_it = url_to_args_.find(url); 333 const auto& args_it = url_to_args_.find(url);
336 if (args_it != url_to_args_.end()) { 334 if (args_it != url_to_args_.end()) {
337 LOG(WARNING) << "--args-for provided for external application " << url 335 LOG(WARNING) << "--args-for provided for external application " << url
338 << " <ignored>"; 336 << " <ignored>";
339 } 337 }
340 ShellImpl* shell_impl = new ShellImpl(application.Pass(), this, url, url); 338 ShellImpl* shell_impl =
339 new ShellImpl(application.Pass(), this, url, base::Closure());
341 url_to_shell_impl_[url] = shell_impl; 340 url_to_shell_impl_[url] = shell_impl;
342 shell_impl->InitializeApplication(Array<String>::From(args)); 341 shell_impl->InitializeApplication(Array<String>::From(args));
343 } 342 }
344 343
345 void ApplicationManager::RegisterContentHandler( 344 void ApplicationManager::RegisterContentHandler(
346 const std::string& mime_type, 345 const std::string& mime_type,
347 const GURL& content_handler_url) { 346 const GURL& content_handler_url) {
348 DCHECK(content_handler_url.is_valid()) 347 DCHECK(content_handler_url.is_valid())
349 << "Content handler URL is invalid for mime type " << mime_type; 348 << "Content handler URL is invalid for mime type " << mime_type;
350 mime_type_to_url_[mime_type] = content_handler_url; 349 mime_type_to_url_[mime_type] = content_handler_url;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 return url_it->second; 407 return url_it->second;
409 auto scheme_it = scheme_to_loader_.find(url.scheme()); 408 auto scheme_it = scheme_to_loader_.find(url.scheme());
410 if (scheme_it != scheme_to_loader_.end()) 409 if (scheme_it != scheme_to_loader_.end())
411 return scheme_it->second; 410 return scheme_it->second;
412 return nullptr; 411 return nullptr;
413 } 412 }
414 413
415 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { 414 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) {
416 // Called from ~ShellImpl, so we do not need to call Destroy here. 415 // Called from ~ShellImpl, so we do not need to call Destroy here.
417 const GURL url = shell_impl->url(); 416 const GURL url = shell_impl->url();
418 const GURL requested_url = shell_impl->requested_url(); 417 base::Closure on_application_end = shell_impl->on_application_end();
419 // Remove the shell. 418 // Remove the shell.
420 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); 419 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url);
421 DCHECK(it != url_to_shell_impl_.end()); 420 DCHECK(it != url_to_shell_impl_.end());
422 delete it->second; 421 delete it->second;
423 url_to_shell_impl_.erase(it); 422 url_to_shell_impl_.erase(it);
424 delegate_->OnApplicationError(requested_url); 423 if (!on_application_end.is_null())
424 on_application_end.Run();
425 } 425 }
426 426
427 void ApplicationManager::OnContentHandlerError( 427 void ApplicationManager::OnContentHandlerError(
428 ContentHandlerConnection* content_handler) { 428 ContentHandlerConnection* content_handler) {
429 // Remove the mapping to the content handler. 429 // Remove the mapping to the content handler.
430 auto it = 430 auto it =
431 url_to_content_handler_.find(content_handler->content_handler_url()); 431 url_to_content_handler_.find(content_handler->content_handler_url());
432 DCHECK(it != url_to_content_handler_.end()); 432 DCHECK(it != url_to_content_handler_.end());
433 delete it->second; 433 delete it->second;
434 url_to_content_handler_.erase(it); 434 url_to_content_handler_.erase(it);
435 } 435 }
436 436
437 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( 437 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName(
438 const GURL& application_url, 438 const GURL& application_url,
439 const std::string& interface_name) { 439 const std::string& interface_name) {
440 ServiceProviderPtr services; 440 ServiceProviderPtr services;
441 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr); 441 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr,
442 base::Closure());
442 MessagePipe pipe; 443 MessagePipe pipe;
443 services->ConnectToService(interface_name, pipe.handle1.Pass()); 444 services->ConnectToService(interface_name, pipe.handle1.Pass());
444 return pipe.handle0.Pass(); 445 return pipe.handle0.Pass();
445 } 446 }
446 447
447 Array<String> ApplicationManager::GetArgsForURL(const GURL& url) { 448 Array<String> ApplicationManager::GetArgsForURL(const GURL& url) {
448 const auto& args_it = url_to_args_.find(url); 449 const auto& args_it = url_to_args_.find(url);
449 if (args_it != url_to_args_.end()) 450 if (args_it != url_to_args_.end())
450 return Array<String>::From(args_it->second); 451 return Array<String>::From(args_it->second);
451 return Array<String>(); 452 return Array<String>();
452 } 453 }
453 454
454 void ApplicationManager::CleanupRunner(NativeRunner* runner) { 455 void ApplicationManager::CleanupRunner(NativeRunner* runner) {
455 native_runners_.erase( 456 native_runners_.erase(
456 std::find(native_runners_.begin(), native_runners_.end(), runner)); 457 std::find(native_runners_.begin(), native_runners_.end(), runner));
457 } 458 }
458 459
459 } // namespace shell 460 } // namespace shell
460 } // namespace mojo 461 } // namespace mojo
OLDNEW
« no previous file with comments | « shell/application_manager/application_manager.h ('k') | shell/application_manager/application_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698