| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 // | 46 // |
| 47 // Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must | 47 // Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must |
| 48 // ensure that all the parameters passed to Loader subclasses stay valid through | 48 // ensure that all the parameters passed to Loader subclasses stay valid through |
| 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(DynamicServiceRunner::CleanupBehavior cleanup_behavior, |
| 57 MimeTypeToURLMap* mime_type_to_url, |
| 57 Context* context, | 58 Context* context, |
| 58 DynamicServiceRunnerFactory* runner_factory, | 59 DynamicServiceRunnerFactory* runner_factory, |
| 59 ScopedMessagePipeHandle shell_handle, | 60 ScopedMessagePipeHandle shell_handle, |
| 60 ApplicationLoader::LoadCallback load_callback, | 61 ApplicationLoader::LoadCallback load_callback, |
| 61 const LoaderCompleteCallback& loader_complete_callback) | 62 const LoaderCompleteCallback& loader_complete_callback) |
| 62 : shell_handle_(shell_handle.Pass()), | 63 : cleanup_behavior_(cleanup_behavior), |
| 64 shell_handle_(shell_handle.Pass()), |
| 63 load_callback_(load_callback), | 65 load_callback_(load_callback), |
| 64 loader_complete_callback_(loader_complete_callback), | 66 loader_complete_callback_(loader_complete_callback), |
| 65 context_(context), | 67 context_(context), |
| 66 mime_type_to_url_(mime_type_to_url), | 68 mime_type_to_url_(mime_type_to_url), |
| 67 runner_factory_(runner_factory), | 69 runner_factory_(runner_factory), |
| 68 weak_ptr_factory_(this) {} | 70 weak_ptr_factory_(this) {} |
| 69 | 71 |
| 70 virtual ~Loader() {} | 72 virtual ~Loader() {} |
| 71 | 73 |
| 72 protected: | 74 protected: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 | 107 |
| 106 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo | 108 // 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 | 109 // application. That could either mean looking for the platform-specific dll |
| 108 // header, or looking for some specific mojo signature prepended to the | 110 // header, or looking for some specific mojo signature prepended to the |
| 109 // library. | 111 // library. |
| 110 | 112 |
| 111 AsPath(context_->task_runners()->blocking_pool(), | 113 AsPath(context_->task_runners()->blocking_pool(), |
| 112 base::Bind(&Loader::RunLibrary, weak_ptr_factory_.GetWeakPtr())); | 114 base::Bind(&Loader::RunLibrary, weak_ptr_factory_.GetWeakPtr())); |
| 113 } | 115 } |
| 114 | 116 |
| 115 virtual void ReportComplete() { loader_complete_callback_.Run(this); } | 117 void ReportComplete() { loader_complete_callback_.Run(this); } |
| 116 | 118 |
| 117 private: | 119 private: |
| 118 bool PeekContentHandler(std::string* mojo_shebang, | 120 bool PeekContentHandler(std::string* mojo_shebang, |
| 119 GURL* mojo_content_handler_url) { | 121 GURL* mojo_content_handler_url) { |
| 120 std::string shebang; | 122 std::string shebang; |
| 121 if (HasMojoMagic() && PeekFirstLine(&shebang)) { | 123 if (HasMojoMagic() && PeekFirstLine(&shebang)) { |
| 122 GURL url(shebang.substr(arraysize(kMojoMagic) - 1, std::string::npos)); | 124 GURL url(shebang.substr(arraysize(kMojoMagic) - 1, std::string::npos)); |
| 123 if (url.is_valid()) { | 125 if (url.is_valid()) { |
| 124 *mojo_shebang = shebang; | 126 *mojo_shebang = shebang; |
| 125 *mojo_content_handler_url = url; | 127 *mojo_content_handler_url = url; |
| 126 return true; | 128 return true; |
| 127 } | 129 } |
| 128 } | 130 } |
| 129 return false; | 131 return false; |
| 130 } | 132 } |
| 131 | 133 |
| 132 void RunLibrary(const base::FilePath& path, bool path_exists) { | 134 void RunLibrary(const base::FilePath& path, bool path_exists) { |
| 133 DCHECK(shell_handle_.is_valid()); | 135 DCHECK(shell_handle_.is_valid()); |
| 134 | 136 |
| 135 if (!path_exists) { | 137 if (!path_exists) { |
| 136 LOG(ERROR) << "Library not started because library path '" << path.value() | 138 LOG(ERROR) << "Library not started because library path '" << path.value() |
| 137 << "' does not exist."; | 139 << "' does not exist."; |
| 138 ReportComplete(); | 140 ReportComplete(); |
| 139 return; | 141 return; |
| 140 } | 142 } |
| 141 | 143 |
| 142 runner_ = runner_factory_->Create(context_); | 144 runner_ = runner_factory_->Create(context_); |
| 143 runner_->Start( | 145 runner_->Start( |
| 144 path, shell_handle_.Pass(), | 146 path, cleanup_behavior_, shell_handle_.Pass(), |
| 145 base::Bind(&Loader::ReportComplete, weak_ptr_factory_.GetWeakPtr())); | 147 base::Bind(&Loader::ReportComplete, weak_ptr_factory_.GetWeakPtr())); |
| 146 } | 148 } |
| 147 | 149 |
| 150 DynamicServiceRunner::CleanupBehavior cleanup_behavior_; |
| 148 ScopedMessagePipeHandle shell_handle_; | 151 ScopedMessagePipeHandle shell_handle_; |
| 149 ApplicationLoader::LoadCallback load_callback_; | 152 ApplicationLoader::LoadCallback load_callback_; |
| 150 LoaderCompleteCallback loader_complete_callback_; | 153 LoaderCompleteCallback loader_complete_callback_; |
| 151 Context* context_; | 154 Context* context_; |
| 152 MimeTypeToURLMap* mime_type_to_url_; | 155 MimeTypeToURLMap* mime_type_to_url_; |
| 153 DynamicServiceRunnerFactory* runner_factory_; | 156 DynamicServiceRunnerFactory* runner_factory_; |
| 154 scoped_ptr<DynamicServiceRunner> runner_; | 157 scoped_ptr<DynamicServiceRunner> runner_; |
| 155 base::WeakPtrFactory<Loader> weak_ptr_factory_; | 158 base::WeakPtrFactory<Loader> weak_ptr_factory_; |
| 156 }; | 159 }; |
| 157 | 160 |
| 158 // A loader for local files. | 161 // A loader for local files. |
| 159 class DynamicApplicationLoader::LocalLoader : public Loader { | 162 class DynamicApplicationLoader::LocalLoader : public Loader { |
| 160 public: | 163 public: |
| 161 LocalLoader(const GURL& url, | 164 LocalLoader(const GURL& url, |
| 162 MimeTypeToURLMap* mime_type_to_url, | 165 MimeTypeToURLMap* mime_type_to_url, |
| 163 Context* context, | 166 Context* context, |
| 164 DynamicServiceRunnerFactory* runner_factory, | 167 DynamicServiceRunnerFactory* runner_factory, |
| 165 ScopedMessagePipeHandle shell_handle, | 168 ScopedMessagePipeHandle shell_handle, |
| 166 ApplicationLoader::LoadCallback load_callback, | 169 ApplicationLoader::LoadCallback load_callback, |
| 167 const LoaderCompleteCallback& loader_complete_callback) | 170 const LoaderCompleteCallback& loader_complete_callback) |
| 168 : Loader(mime_type_to_url, | 171 : Loader(DynamicServiceRunner::DontDeleteAppPath, |
| 172 mime_type_to_url, |
| 169 context, | 173 context, |
| 170 runner_factory, | 174 runner_factory, |
| 171 shell_handle.Pass(), | 175 shell_handle.Pass(), |
| 172 load_callback, | 176 load_callback, |
| 173 loader_complete_callback), | 177 loader_complete_callback), |
| 174 url_(url), | 178 url_(url), |
| 175 path_(UrlToFile(url)) { | 179 path_(UrlToFile(url)) { |
| 176 Load(); | 180 Load(); |
| 177 } | 181 } |
| 178 | 182 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 class DynamicApplicationLoader::NetworkLoader : public Loader { | 250 class DynamicApplicationLoader::NetworkLoader : public Loader { |
| 247 public: | 251 public: |
| 248 NetworkLoader(const GURL& url, | 252 NetworkLoader(const GURL& url, |
| 249 NetworkService* network_service, | 253 NetworkService* network_service, |
| 250 MimeTypeToURLMap* mime_type_to_url, | 254 MimeTypeToURLMap* mime_type_to_url, |
| 251 Context* context, | 255 Context* context, |
| 252 DynamicServiceRunnerFactory* runner_factory, | 256 DynamicServiceRunnerFactory* runner_factory, |
| 253 ScopedMessagePipeHandle shell_handle, | 257 ScopedMessagePipeHandle shell_handle, |
| 254 ApplicationLoader::LoadCallback load_callback, | 258 ApplicationLoader::LoadCallback load_callback, |
| 255 const LoaderCompleteCallback& loader_complete_callback) | 259 const LoaderCompleteCallback& loader_complete_callback) |
| 256 : Loader(mime_type_to_url, | 260 : Loader(DynamicServiceRunner::DeleteAppPath, |
| 261 mime_type_to_url, |
| 257 context, | 262 context, |
| 258 runner_factory, | 263 runner_factory, |
| 259 shell_handle.Pass(), | 264 shell_handle.Pass(), |
| 260 load_callback, | 265 load_callback, |
| 261 loader_complete_callback), | 266 loader_complete_callback), |
| 262 url_(url), | 267 url_(url), |
| 263 weak_ptr_factory_(this) { | 268 weak_ptr_factory_(this) { |
| 264 StartNetworkRequest(url, network_service); | 269 StartNetworkRequest(url, network_service); |
| 265 } | 270 } |
| 266 | 271 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 LOG(ERROR) << "Error (" << response->error->code << ": " | 426 LOG(ERROR) << "Error (" << response->error->code << ": " |
| 422 << response->error->description << ") while fetching " | 427 << response->error->description << ") while fetching " |
| 423 << response->url; | 428 << response->url; |
| 424 ReportComplete(); | 429 ReportComplete(); |
| 425 return; | 430 return; |
| 426 } | 431 } |
| 427 response_ = response.Pass(); | 432 response_ = response.Pass(); |
| 428 Load(); | 433 Load(); |
| 429 } | 434 } |
| 430 | 435 |
| 431 void ReportComplete() override { | |
| 432 Loader::ReportComplete(); | |
| 433 // As soon as we've loaded the library we can delete the cache file. | |
| 434 // Tools can read the mojo_shell.PID.maps file to find the original library. | |
| 435 if (!path_.empty()) | |
| 436 DeleteFile(path_, false); | |
| 437 } | |
| 438 | |
| 439 const GURL url_; | 436 const GURL url_; |
| 440 URLLoaderPtr url_loader_; | 437 URLLoaderPtr url_loader_; |
| 441 URLResponsePtr response_; | 438 URLResponsePtr response_; |
| 442 base::FilePath path_; | 439 base::FilePath path_; |
| 443 base::WeakPtrFactory<NetworkLoader> weak_ptr_factory_; | 440 base::WeakPtrFactory<NetworkLoader> weak_ptr_factory_; |
| 444 | 441 |
| 445 DISALLOW_COPY_AND_ASSIGN(NetworkLoader); | 442 DISALLOW_COPY_AND_ASSIGN(NetworkLoader); |
| 446 }; | 443 }; |
| 447 | 444 |
| 448 DynamicApplicationLoader::DynamicApplicationLoader( | 445 DynamicApplicationLoader::DynamicApplicationLoader( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 // TODO(darin): What should we do about service errors? This implies that | 493 // 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? | 494 // the app closed its handle to the service manager. Maybe we don't care? |
| 498 } | 495 } |
| 499 | 496 |
| 500 void DynamicApplicationLoader::LoaderComplete(Loader* loader) { | 497 void DynamicApplicationLoader::LoaderComplete(Loader* loader) { |
| 501 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader)); | 498 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader)); |
| 502 } | 499 } |
| 503 | 500 |
| 504 } // namespace shell | 501 } // namespace shell |
| 505 } // namespace mojo | 502 } // namespace mojo |
| OLD | NEW |