| 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 |