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

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

Issue 1358533004: Move more of ContentHandler handling 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"
15 #include "mojo/public/cpp/bindings/binding.h" 14 #include "mojo/public/cpp/bindings/binding.h"
16 #include "mojo/shell/application_instance.h" 15 #include "mojo/shell/application_instance.h"
17 #include "mojo/shell/content_handler_connection.h"
18 #include "mojo/shell/fetcher.h" 16 #include "mojo/shell/fetcher.h"
19 #include "mojo/shell/package_manager.h" 17 #include "mojo/shell/package_manager.h"
20 #include "mojo/shell/query_util.h" 18 #include "mojo/shell/query_util.h"
21 #include "mojo/shell/switches.h" 19 #include "mojo/shell/switches.h"
22 20
23 namespace mojo { 21 namespace mojo {
24 namespace shell { 22 namespace shell {
25 23
26 namespace { 24 namespace {
27 25
(...skipping 18 matching lines...) Expand all
46 44
47 bool ApplicationManager::TestAPI::HasRunningInstanceForURL( 45 bool ApplicationManager::TestAPI::HasRunningInstanceForURL(
48 const GURL& url) const { 46 const GURL& url) const {
49 return manager_->identity_to_instance_.find(Identity(url)) != 47 return manager_->identity_to_instance_.find(Identity(url)) !=
50 manager_->identity_to_instance_.end(); 48 manager_->identity_to_instance_.end();
51 } 49 }
52 50
53 ApplicationManager::ApplicationManager( 51 ApplicationManager::ApplicationManager(
54 scoped_ptr<PackageManager> package_manager) 52 scoped_ptr<PackageManager> package_manager)
55 : package_manager_(package_manager.Pass()), 53 : package_manager_(package_manager.Pass()),
56 content_handler_id_counter_(0u), 54 task_runner_(nullptr),
55 weak_ptr_factory_(this) {
56 package_manager_->SetApplicationManager(this);
57 }
58
59 ApplicationManager::ApplicationManager(
60 scoped_ptr<PackageManager> package_manager,
61 scoped_ptr<NativeRunnerFactory> native_runner_factory,
62 base::TaskRunner* task_runner)
63 : package_manager_(package_manager.Pass()),
64 task_runner_(task_runner),
65 native_runner_factory_(native_runner_factory.Pass()),
57 weak_ptr_factory_(this) { 66 weak_ptr_factory_(this) {
58 package_manager_->SetApplicationManager(this); 67 package_manager_->SetApplicationManager(this);
59 } 68 }
60 69
61 ApplicationManager::~ApplicationManager() { 70 ApplicationManager::~ApplicationManager() {
62 IdentityToContentHandlerMap identity_to_content_handler(
63 identity_to_content_handler_);
64 for (auto& pair : identity_to_content_handler)
65 pair.second->CloseConnection();
66 TerminateShellConnections(); 71 TerminateShellConnections();
67 STLDeleteValues(&url_to_loader_); 72 STLDeleteValues(&url_to_loader_);
68 } 73 }
69 74
70 void ApplicationManager::TerminateShellConnections() { 75 void ApplicationManager::TerminateShellConnections() {
71 STLDeleteValues(&identity_to_instance_); 76 STLDeleteValues(&identity_to_instance_);
72 } 77 }
73 78
74 void ApplicationManager::ConnectToApplication( 79 void ApplicationManager::ConnectToApplication(
75 scoped_ptr<ConnectToApplicationParams> params) { 80 scoped_ptr<ConnectToApplicationParams> params) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 return; 167 return;
163 168
164 Identity source = params->source(); 169 Identity source = params->source();
165 Identity target = params->target(); 170 Identity target = params->target();
166 Shell::ConnectToApplicationCallback connect_callback = 171 Shell::ConnectToApplicationCallback connect_callback =
167 params->connect_callback(); 172 params->connect_callback();
168 params->set_connect_callback(EmptyConnectCallback()); 173 params->set_connect_callback(EmptyConnectCallback());
169 ApplicationInstance* app = nullptr; 174 ApplicationInstance* app = nullptr;
170 InterfaceRequest<Application> request(CreateInstance(params.Pass(), &app)); 175 InterfaceRequest<Application> request(CreateInstance(params.Pass(), &app));
171 176
177 uint32_t content_handler_id = package_manager_->HandleWithContentHandler(
178 fetcher.get(), source, target.url(), target.filter(), &request);
179 if (content_handler_id != Shell::kInvalidContentHandlerID) {
180 app->set_requesting_content_handler_id(content_handler_id);
181 connect_callback.Run(content_handler_id);
182 return;
183 }
172 184
173 GURL content_handler_url; 185 // TODO(erg): Have a better way of switching the sandbox on. For now, switch
174 URLResponsePtr new_response; 186 // it on hard coded when we're using some of the sandboxable core services.
175 std::string qualifier; 187 bool start_sandboxed = false;
176 if (package_manager_->HandleWithContentHandler(fetcher.get(), 188 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
177 target.url(), 189 switches::kMojoNoSandbox)) {
178 blocking_pool_, 190 start_sandboxed = (target.url() == GURL("mojo://core_services/") &&
179 &new_response, 191 target.qualifier() == "Core") ||
180 &content_handler_url, 192 target.url() == GURL("mojo://html_viewer/");
181 &qualifier)) { 193 }
182 Identity content_handler(content_handler_url, qualifier, target.filter());
183 LoadWithContentHandler(source, content_handler, connect_callback, app,
184 request.Pass(), new_response.Pass());
185 } else {
186 // TODO(erg): Have a better way of switching the sandbox on. For now, switch
187 // it on hard coded when we're using some of the sandboxable core services.
188 bool start_sandboxed = false;
189 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
190 switches::kMojoNoSandbox)) {
191 start_sandboxed = (target.url() == GURL("mojo://core_services/") &&
192 target.qualifier() == "Core") ||
193 target.url() == GURL("mojo://html_viewer/");
194 }
195 194
196 connect_callback.Run(Shell::kInvalidContentHandlerID); 195 connect_callback.Run(Shell::kInvalidContentHandlerID);
197 196
198 fetcher->AsPath(blocking_pool_, 197 fetcher->AsPath(task_runner_,
199 base::Bind(&ApplicationManager::RunNativeApplication, 198 base::Bind(&ApplicationManager::RunNativeApplication,
200 weak_ptr_factory_.GetWeakPtr(), 199 weak_ptr_factory_.GetWeakPtr(),
201 base::Passed(request.Pass()), start_sandboxed, 200 base::Passed(request.Pass()), start_sandboxed,
202 base::Passed(fetcher.Pass()))); 201 base::Passed(fetcher.Pass())));
203 }
204 } 202 }
205 203
206 void ApplicationManager::RunNativeApplication( 204 void ApplicationManager::RunNativeApplication(
207 InterfaceRequest<Application> application_request, 205 InterfaceRequest<Application> application_request,
208 bool start_sandboxed, 206 bool start_sandboxed,
209 scoped_ptr<Fetcher> fetcher, 207 scoped_ptr<Fetcher> fetcher,
210 const base::FilePath& path, 208 const base::FilePath& path,
211 bool path_exists) { 209 bool path_exists) {
212 // We only passed fetcher to keep it alive. Done with it now. 210 // We only passed fetcher to keep it alive. Done with it now.
213 fetcher.reset(); 211 fetcher.reset();
214 212
215 DCHECK(application_request.is_pending()); 213 DCHECK(application_request.is_pending());
216 214
217 if (!path_exists) { 215 if (!path_exists) {
218 LOG(ERROR) << "Library not started because library path '" << path.value() 216 LOG(ERROR) << "Library not started because library path '" << path.value()
219 << "' does not exist."; 217 << "' does not exist.";
220 return; 218 return;
221 } 219 }
222 220
223 TRACE_EVENT1("mojo_shell", "ApplicationManager::RunNativeApplication", "path", 221 TRACE_EVENT1("mojo_shell", "ApplicationManager::RunNativeApplication", "path",
224 path.AsUTF8Unsafe()); 222 path.AsUTF8Unsafe());
225 NativeRunner* runner = native_runner_factory_->Create().release(); 223 NativeRunner* runner = native_runner_factory_->Create().release();
226 native_runners_.push_back(runner); 224 native_runners_.push_back(runner);
227 runner->Start(path, start_sandboxed, application_request.Pass(), 225 runner->Start(path, start_sandboxed, application_request.Pass(),
228 base::Bind(&ApplicationManager::CleanupRunner, 226 base::Bind(&ApplicationManager::CleanupRunner,
229 weak_ptr_factory_.GetWeakPtr(), runner)); 227 weak_ptr_factory_.GetWeakPtr(), runner));
230 } 228 }
231 229
232 void ApplicationManager::LoadWithContentHandler(
233 const Identity& source,
234 const Identity& content_handler,
235 const Shell::ConnectToApplicationCallback& connect_callback,
236 ApplicationInstance* app,
237 InterfaceRequest<Application> application_request,
238 URLResponsePtr url_response) {
239 ContentHandlerConnection* connection = nullptr;
240 // TODO(beng): Figure out the extent to which capability filter should be
241 // factored into handler identity.
242 IdentityToContentHandlerMap::iterator iter =
243 identity_to_content_handler_.find(content_handler);
244 if (iter != identity_to_content_handler_.end()) {
245 connection = iter->second;
246 } else {
247 connection = new ContentHandlerConnection(
248 this, source, content_handler, ++content_handler_id_counter_);
249 identity_to_content_handler_[content_handler] = connection;
250 }
251
252 app->set_requesting_content_handler_id(connection->id());
253 connection->content_handler()->StartApplication(application_request.Pass(),
254 url_response.Pass());
255 connect_callback.Run(connection->id());
256 }
257
258 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, 230 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader,
259 const GURL& url) { 231 const GURL& url) {
260 URLToLoaderMap::iterator it = url_to_loader_.find(url); 232 URLToLoaderMap::iterator it = url_to_loader_.find(url);
261 if (it != url_to_loader_.end()) 233 if (it != url_to_loader_.end())
262 delete it->second; 234 delete it->second;
263 url_to_loader_[url] = loader.release(); 235 url_to_loader_[url] = loader.release();
264 } 236 }
265 237
266 ApplicationLoader* ApplicationManager::GetLoaderForURL(const GURL& url) { 238 ApplicationLoader* ApplicationManager::GetLoaderForURL(const GURL& url) {
267 auto url_it = url_to_loader_.find(GetBaseURLAndQuery(url, nullptr)); 239 auto url_it = url_to_loader_.find(GetBaseURLAndQuery(url, nullptr));
268 if (url_it != url_to_loader_.end()) 240 if (url_it != url_to_loader_.end())
269 return url_it->second; 241 return url_it->second;
270 return default_loader_.get(); 242 return default_loader_.get();
271 } 243 }
272 244
273 void ApplicationManager::OnApplicationInstanceError( 245 void ApplicationManager::OnApplicationInstanceError(
274 ApplicationInstance* instance) { 246 ApplicationInstance* instance) {
275 // Called from ~ApplicationInstance, so we do not need to call Destroy here. 247 // Called from ~ApplicationInstance, so we do not need to call Destroy here.
276 const Identity identity = instance->identity(); 248 const Identity identity = instance->identity();
277 base::Closure on_application_end = instance->on_application_end(); 249 base::Closure on_application_end = instance->on_application_end();
278 // Remove the shell. 250 // Remove the shell.
279 auto it = identity_to_instance_.find(identity); 251 auto it = identity_to_instance_.find(identity);
280 DCHECK(it != identity_to_instance_.end()); 252 DCHECK(it != identity_to_instance_.end());
281 delete it->second; 253 delete it->second;
282 identity_to_instance_.erase(it); 254 identity_to_instance_.erase(it);
283 if (!on_application_end.is_null()) 255 if (!on_application_end.is_null())
284 on_application_end.Run(); 256 on_application_end.Run();
285 } 257 }
286 258
287 void ApplicationManager::OnContentHandlerConnectionClosed(
288 ContentHandlerConnection* content_handler) {
289 // Remove the mapping to the content handler.
290 auto it = identity_to_content_handler_.find(content_handler->identity());
291 DCHECK(it != identity_to_content_handler_.end());
292 identity_to_content_handler_.erase(it);
293 }
294
295 void ApplicationManager::CleanupRunner(NativeRunner* runner) { 259 void ApplicationManager::CleanupRunner(NativeRunner* runner) {
296 native_runners_.erase( 260 native_runners_.erase(
297 std::find(native_runners_.begin(), native_runners_.end(), runner)); 261 std::find(native_runners_.begin(), native_runners_.end(), runner));
298 } 262 }
299 263
300 Shell::ConnectToApplicationCallback EmptyConnectCallback() { 264 Shell::ConnectToApplicationCallback EmptyConnectCallback() {
301 return base::Bind(&OnEmptyOnConnectCallback); 265 return base::Bind(&OnEmptyOnConnectCallback);
302 } 266 }
303 267
304 } // namespace shell 268 } // namespace shell
305 } // namespace mojo 269 } // 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