OLD | NEW |
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/dynamic_application_loader.h" | 5 #include "shell/dynamic_application_loader.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/files/file.h" | 9 #include "base/files/file.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 // Loader's lifetime. | 49 // Loader's lifetime. |
50 // | 50 // |
51 // Async operations are done with WeakPtr to protect against | 51 // Async operations are done with WeakPtr to protect against |
52 // DynamicApplicationLoader going away (and taking all the Loaders with it) | 52 // DynamicApplicationLoader going away (and taking all the Loaders with it) |
53 // while the async operation is outstanding. | 53 // while the async operation is outstanding. |
54 class DynamicApplicationLoader::Loader { | 54 class DynamicApplicationLoader::Loader { |
55 public: | 55 public: |
56 Loader(MimeTypeToURLMap* mime_type_to_url, | 56 Loader(MimeTypeToURLMap* mime_type_to_url, |
57 Context* context, | 57 Context* context, |
58 DynamicServiceRunnerFactory* runner_factory, | 58 DynamicServiceRunnerFactory* runner_factory, |
59 ScopedMessagePipeHandle shell_handle, | 59 InterfaceRequest<Application> application_request, |
60 ApplicationLoader::LoadCallback load_callback, | 60 ApplicationLoader::LoadCallback load_callback, |
61 const LoaderCompleteCallback& loader_complete_callback) | 61 const LoaderCompleteCallback& loader_complete_callback) |
62 : shell_handle_(shell_handle.Pass()), | 62 : application_request_(application_request.Pass()), |
63 load_callback_(load_callback), | 63 load_callback_(load_callback), |
64 loader_complete_callback_(loader_complete_callback), | 64 loader_complete_callback_(loader_complete_callback), |
65 context_(context), | 65 context_(context), |
66 mime_type_to_url_(mime_type_to_url), | 66 mime_type_to_url_(mime_type_to_url), |
67 runner_factory_(runner_factory), | 67 runner_factory_(runner_factory), |
68 weak_ptr_factory_(this) {} | 68 weak_ptr_factory_(this) {} |
69 | 69 |
70 virtual ~Loader() {} | 70 virtual ~Loader() {} |
71 | 71 |
72 protected: | 72 protected: |
73 virtual URLResponsePtr AsURLResponse(base::TaskRunner* task_runner, | 73 virtual URLResponsePtr AsURLResponse(base::TaskRunner* task_runner, |
74 uint32_t skip) = 0; | 74 uint32_t skip) = 0; |
75 | 75 |
76 virtual void AsPath( | 76 virtual void AsPath( |
77 base::TaskRunner* task_runner, | 77 base::TaskRunner* task_runner, |
78 base::Callback<void(const base::FilePath&, bool)> callback) = 0; | 78 base::Callback<void(const base::FilePath&, bool)> callback) = 0; |
79 | 79 |
80 virtual std::string MimeType() = 0; | 80 virtual std::string MimeType() = 0; |
81 | 81 |
82 virtual bool HasMojoMagic() = 0; | 82 virtual bool HasMojoMagic() = 0; |
83 | 83 |
84 virtual bool PeekFirstLine(std::string* line) = 0; | 84 virtual bool PeekFirstLine(std::string* line) = 0; |
85 | 85 |
86 void Load() { | 86 void Load() { |
87 // If the response begins with a #!mojo <content-handler-url>, use it. | 87 // If the response begins with a #!mojo <content-handler-url>, use it. |
88 GURL url; | 88 GURL url; |
89 std::string shebang; | 89 std::string shebang; |
90 if (PeekContentHandler(&shebang, &url)) { | 90 if (PeekContentHandler(&shebang, &url)) { |
91 load_callback_.Run( | 91 load_callback_.Run( |
92 url, shell_handle_.Pass(), | 92 url, application_request_.Pass(), |
93 AsURLResponse(context_->task_runners()->blocking_pool(), | 93 AsURLResponse(context_->task_runners()->blocking_pool(), |
94 static_cast<int>(shebang.size()))); | 94 static_cast<int>(shebang.size()))); |
95 return; | 95 return; |
96 } | 96 } |
97 | 97 |
98 MimeTypeToURLMap::iterator iter = mime_type_to_url_->find(MimeType()); | 98 MimeTypeToURLMap::iterator iter = mime_type_to_url_->find(MimeType()); |
99 if (iter != mime_type_to_url_->end()) { | 99 if (iter != mime_type_to_url_->end()) { |
100 load_callback_.Run( | 100 load_callback_.Run( |
101 iter->second, shell_handle_.Pass(), | 101 iter->second, application_request_.Pass(), |
102 AsURLResponse(context_->task_runners()->blocking_pool(), 0)); | 102 AsURLResponse(context_->task_runners()->blocking_pool(), 0)); |
103 return; | 103 return; |
104 } | 104 } |
105 | 105 |
106 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo | 106 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo |
107 // application. That could either mean looking for the platform-specific dll | 107 // application. That could either mean looking for the platform-specific dll |
108 // header, or looking for some specific mojo signature prepended to the | 108 // header, or looking for some specific mojo signature prepended to the |
109 // library. | 109 // library. |
110 | 110 |
111 AsPath(context_->task_runners()->blocking_pool(), | 111 AsPath(context_->task_runners()->blocking_pool(), |
(...skipping 11 matching lines...) Expand all Loading... |
123 if (url.is_valid()) { | 123 if (url.is_valid()) { |
124 *mojo_shebang = shebang; | 124 *mojo_shebang = shebang; |
125 *mojo_content_handler_url = url; | 125 *mojo_content_handler_url = url; |
126 return true; | 126 return true; |
127 } | 127 } |
128 } | 128 } |
129 return false; | 129 return false; |
130 } | 130 } |
131 | 131 |
132 void RunLibrary(const base::FilePath& path, bool path_exists) { | 132 void RunLibrary(const base::FilePath& path, bool path_exists) { |
133 DCHECK(shell_handle_.is_valid()); | 133 DCHECK(application_request_.is_pending()); |
134 | 134 |
135 if (!path_exists) { | 135 if (!path_exists) { |
136 LOG(ERROR) << "Library not started because library path '" << path.value() | 136 LOG(ERROR) << "Library not started because library path '" << path.value() |
137 << "' does not exist."; | 137 << "' does not exist."; |
138 ReportComplete(); | 138 ReportComplete(); |
139 return; | 139 return; |
140 } | 140 } |
141 | 141 |
142 runner_ = runner_factory_->Create(context_); | 142 runner_ = runner_factory_->Create(context_); |
143 runner_->Start( | 143 runner_->Start( |
144 path, shell_handle_.Pass(), | 144 path, application_request_.Pass(), |
145 base::Bind(&Loader::ReportComplete, weak_ptr_factory_.GetWeakPtr())); | 145 base::Bind(&Loader::ReportComplete, weak_ptr_factory_.GetWeakPtr())); |
146 } | 146 } |
147 | 147 |
148 ScopedMessagePipeHandle shell_handle_; | 148 InterfaceRequest<Application> application_request_; |
149 ApplicationLoader::LoadCallback load_callback_; | 149 ApplicationLoader::LoadCallback load_callback_; |
150 LoaderCompleteCallback loader_complete_callback_; | 150 LoaderCompleteCallback loader_complete_callback_; |
151 Context* context_; | 151 Context* context_; |
152 MimeTypeToURLMap* mime_type_to_url_; | 152 MimeTypeToURLMap* mime_type_to_url_; |
153 DynamicServiceRunnerFactory* runner_factory_; | 153 DynamicServiceRunnerFactory* runner_factory_; |
154 scoped_ptr<DynamicServiceRunner> runner_; | 154 scoped_ptr<DynamicServiceRunner> runner_; |
155 base::WeakPtrFactory<Loader> weak_ptr_factory_; | 155 base::WeakPtrFactory<Loader> weak_ptr_factory_; |
156 }; | 156 }; |
157 | 157 |
158 // A loader for local files. | 158 // A loader for local files. |
159 class DynamicApplicationLoader::LocalLoader : public Loader { | 159 class DynamicApplicationLoader::LocalLoader : public Loader { |
160 public: | 160 public: |
161 LocalLoader(const GURL& url, | 161 LocalLoader(const GURL& url, |
162 MimeTypeToURLMap* mime_type_to_url, | 162 MimeTypeToURLMap* mime_type_to_url, |
163 Context* context, | 163 Context* context, |
164 DynamicServiceRunnerFactory* runner_factory, | 164 DynamicServiceRunnerFactory* runner_factory, |
165 ScopedMessagePipeHandle shell_handle, | 165 InterfaceRequest<Application> application_request, |
166 ApplicationLoader::LoadCallback load_callback, | 166 ApplicationLoader::LoadCallback load_callback, |
167 const LoaderCompleteCallback& loader_complete_callback) | 167 const LoaderCompleteCallback& loader_complete_callback) |
168 : Loader(mime_type_to_url, | 168 : Loader(mime_type_to_url, |
169 context, | 169 context, |
170 runner_factory, | 170 runner_factory, |
171 shell_handle.Pass(), | 171 application_request.Pass(), |
172 load_callback, | 172 load_callback, |
173 loader_complete_callback), | 173 loader_complete_callback), |
174 url_(url), | 174 url_(url), |
175 path_(UrlToFile(url)) { | 175 path_(UrlToFile(url)) { |
176 Load(); | 176 Load(); |
177 } | 177 } |
178 | 178 |
179 private: | 179 private: |
180 static base::FilePath UrlToFile(const GURL& url) { | 180 static base::FilePath UrlToFile(const GURL& url) { |
181 DCHECK(url.SchemeIsFile()); | 181 DCHECK(url.SchemeIsFile()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 }; | 243 }; |
244 | 244 |
245 // A loader for network files. | 245 // A loader for network files. |
246 class DynamicApplicationLoader::NetworkLoader : public Loader { | 246 class DynamicApplicationLoader::NetworkLoader : public Loader { |
247 public: | 247 public: |
248 NetworkLoader(const GURL& url, | 248 NetworkLoader(const GURL& url, |
249 NetworkService* network_service, | 249 NetworkService* network_service, |
250 MimeTypeToURLMap* mime_type_to_url, | 250 MimeTypeToURLMap* mime_type_to_url, |
251 Context* context, | 251 Context* context, |
252 DynamicServiceRunnerFactory* runner_factory, | 252 DynamicServiceRunnerFactory* runner_factory, |
253 ScopedMessagePipeHandle shell_handle, | 253 InterfaceRequest<Application> application_request, |
254 ApplicationLoader::LoadCallback load_callback, | 254 ApplicationLoader::LoadCallback load_callback, |
255 const LoaderCompleteCallback& loader_complete_callback) | 255 const LoaderCompleteCallback& loader_complete_callback) |
256 : Loader(mime_type_to_url, | 256 : Loader(mime_type_to_url, |
257 context, | 257 context, |
258 runner_factory, | 258 runner_factory, |
259 shell_handle.Pass(), | 259 application_request.Pass(), |
260 load_callback, | 260 load_callback, |
261 loader_complete_callback), | 261 loader_complete_callback), |
262 url_(url), | 262 url_(url), |
263 weak_ptr_factory_(this) { | 263 weak_ptr_factory_(this) { |
264 StartNetworkRequest(url, network_service); | 264 StartNetworkRequest(url, network_service); |
265 } | 265 } |
266 | 266 |
267 ~NetworkLoader() override { | 267 ~NetworkLoader() override { |
268 if (!path_.empty()) | 268 if (!path_.empty()) |
269 base::DeleteFile(path_, false); | 269 base::DeleteFile(path_, false); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 } | 462 } |
463 | 463 |
464 void DynamicApplicationLoader::RegisterContentHandler( | 464 void DynamicApplicationLoader::RegisterContentHandler( |
465 const std::string& mime_type, | 465 const std::string& mime_type, |
466 const GURL& content_handler_url) { | 466 const GURL& content_handler_url) { |
467 DCHECK(content_handler_url.is_valid()) | 467 DCHECK(content_handler_url.is_valid()) |
468 << "Content handler URL is invalid for mime type " << mime_type; | 468 << "Content handler URL is invalid for mime type " << mime_type; |
469 mime_type_to_url_[mime_type] = content_handler_url; | 469 mime_type_to_url_[mime_type] = content_handler_url; |
470 } | 470 } |
471 | 471 |
472 void DynamicApplicationLoader::Load(ApplicationManager* manager, | 472 void DynamicApplicationLoader::Load( |
473 const GURL& url, | 473 ApplicationManager* manager, |
474 ShellPtr shell, | 474 const GURL& url, |
475 LoadCallback load_callback) { | 475 InterfaceRequest<Application> application_request, |
| 476 LoadCallback load_callback) { |
476 if (url.SchemeIsFile()) { | 477 if (url.SchemeIsFile()) { |
477 loaders_.push_back(new LocalLoader( | 478 loaders_.push_back(new LocalLoader( |
478 url, &mime_type_to_url_, context_, runner_factory_.get(), | 479 url, &mime_type_to_url_, context_, runner_factory_.get(), |
479 shell.PassMessagePipe(), load_callback, loader_complete_callback_)); | 480 application_request.Pass(), load_callback, loader_complete_callback_)); |
480 return; | 481 return; |
481 } | 482 } |
482 | 483 |
483 if (!network_service_) { | 484 if (!network_service_) { |
484 context_->application_manager()->ConnectToService( | 485 context_->application_manager()->ConnectToService( |
485 GURL("mojo:network_service"), &network_service_); | 486 GURL("mojo:network_service"), &network_service_); |
486 } | 487 } |
487 | 488 |
488 loaders_.push_back(new NetworkLoader( | 489 loaders_.push_back(new NetworkLoader( |
489 url, network_service_.get(), &mime_type_to_url_, context_, | 490 url, network_service_.get(), &mime_type_to_url_, context_, |
490 runner_factory_.get(), shell.PassMessagePipe(), load_callback, | 491 runner_factory_.get(), application_request.Pass(), load_callback, |
491 loader_complete_callback_)); | 492 loader_complete_callback_)); |
492 } | 493 } |
493 | 494 |
494 void DynamicApplicationLoader::OnApplicationError(ApplicationManager* manager, | 495 void DynamicApplicationLoader::OnApplicationError(ApplicationManager* manager, |
495 const GURL& url) { | 496 const GURL& url) { |
496 // TODO(darin): What should we do about service errors? This implies that | 497 // TODO(darin): What should we do about service errors? This implies that |
497 // the app closed its handle to the service manager. Maybe we don't care? | 498 // the app closed its handle to the service manager. Maybe we don't care? |
498 } | 499 } |
499 | 500 |
500 void DynamicApplicationLoader::LoaderComplete(Loader* loader) { | 501 void DynamicApplicationLoader::LoaderComplete(Loader* loader) { |
501 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader)); | 502 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader)); |
502 } | 503 } |
503 | 504 |
504 } // namespace shell | 505 } // namespace shell |
505 } // namespace mojo | 506 } // namespace mojo |
OLD | NEW |