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

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

Issue 741453002: Make sure that Content Handled application can be connected multiple times. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Fix sky Created 6 years, 1 month 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 "mojo/shell/dynamic_application_loader.h" 5 #include "mojo/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_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 // Loader's lifetime. 46 // Loader's lifetime.
47 // 47 //
48 // Async operations are done with WeakPtr to protect against 48 // Async operations are done with WeakPtr to protect against
49 // DynamicApplicationLoader going away (and taking all the Loaders with it) 49 // DynamicApplicationLoader going away (and taking all the Loaders with it)
50 // while the async operation is outstanding. 50 // while the async operation is outstanding.
51 class DynamicApplicationLoader::Loader { 51 class DynamicApplicationLoader::Loader {
52 public: 52 public:
53 Loader(MimeTypeToURLMap* mime_type_to_url, 53 Loader(MimeTypeToURLMap* mime_type_to_url,
54 Context* context, 54 Context* context,
55 DynamicServiceRunnerFactory* runner_factory, 55 DynamicServiceRunnerFactory* runner_factory,
56 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks, 56 ScopedMessagePipeHandle shell_handle,
57 ApplicationLoader::LoadCallback load_callback,
57 const LoaderCompleteCallback& loader_complete_callback) 58 const LoaderCompleteCallback& loader_complete_callback)
58 : load_callbacks_(load_callbacks), 59 : shell_handle_(shell_handle.Pass()),
60 load_callback_(load_callback),
59 loader_complete_callback_(loader_complete_callback), 61 loader_complete_callback_(loader_complete_callback),
60 context_(context), 62 context_(context),
61 mime_type_to_url_(mime_type_to_url), 63 mime_type_to_url_(mime_type_to_url),
62 runner_factory_(runner_factory), 64 runner_factory_(runner_factory),
63 weak_ptr_factory_(this) {} 65 weak_ptr_factory_(this) {}
64 66
65 virtual ~Loader() {} 67 virtual ~Loader() {}
66 68
67 protected: 69 protected:
68 virtual URLResponsePtr AsURLResponse(base::TaskRunner* task_runner, 70 virtual URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
69 uint32_t skip) = 0; 71 uint32_t skip) = 0;
70 72
71 virtual void AsPath( 73 virtual void AsPath(
72 base::TaskRunner* task_runner, 74 base::TaskRunner* task_runner,
73 base::Callback<void(const base::FilePath&, bool)> callback) = 0; 75 base::Callback<void(const base::FilePath&, bool)> callback) = 0;
74 76
75 virtual std::string MimeType() = 0; 77 virtual std::string MimeType() = 0;
76 78
77 virtual bool HasMojoMagic() = 0; 79 virtual bool HasMojoMagic() = 0;
78 80
79 virtual bool PeekFirstLine(std::string* line) = 0; 81 virtual bool PeekFirstLine(std::string* line) = 0;
80 82
81 void Load() { 83 void Load() {
82 // If the response begins with a #!mojo:<content-handler-url>, use it. 84 // If the response begins with a #!mojo:<content-handler-url>, use it.
83 GURL url; 85 GURL url;
84 std::string shebang; 86 std::string shebang;
85 if (PeekContentHandler(&shebang, &url)) { 87 if (PeekContentHandler(&shebang, &url)) {
86 load_callbacks_->LoadWithContentHandler( 88 load_callback_.Run(
87 url, AsURLResponse(context_->task_runners()->blocking_pool(), 89 url, shell_handle_.Pass(),
88 static_cast<int>(shebang.size()))); 90 AsURLResponse(context_->task_runners()->blocking_pool(),
91 static_cast<int>(shebang.size())));
89 return; 92 return;
90 } 93 }
91 94
92 MimeTypeToURLMap::iterator iter = mime_type_to_url_->find(MimeType()); 95 MimeTypeToURLMap::iterator iter = mime_type_to_url_->find(MimeType());
93 if (iter != mime_type_to_url_->end()) { 96 if (iter != mime_type_to_url_->end()) {
94 load_callbacks_->LoadWithContentHandler( 97 load_callback_.Run(
95 iter->second, 98 iter->second, shell_handle_.Pass(),
96 AsURLResponse(context_->task_runners()->blocking_pool(), 0)); 99 AsURLResponse(context_->task_runners()->blocking_pool(), 0));
97 return; 100 return;
98 } 101 }
99 102
100 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo 103 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo
101 // application. That could either mean looking for the platform-specific dll 104 // application. That could either mean looking for the platform-specific dll
102 // header, or looking for some specific mojo signature prepended to the 105 // header, or looking for some specific mojo signature prepended to the
103 // library. 106 // library.
104 107
105 AsPath(context_->task_runners()->blocking_pool(), 108 AsPath(context_->task_runners()->blocking_pool(),
(...skipping 11 matching lines...) Expand all
117 if (url.is_valid()) { 120 if (url.is_valid()) {
118 *mojo_shebang = shebang; 121 *mojo_shebang = shebang;
119 *mojo_content_handler_url = url; 122 *mojo_content_handler_url = url;
120 return true; 123 return true;
121 } 124 }
122 } 125 }
123 return false; 126 return false;
124 } 127 }
125 128
126 void RunLibrary(const base::FilePath& path, bool path_exists) { 129 void RunLibrary(const base::FilePath& path, bool path_exists) {
127 ScopedMessagePipeHandle shell_handle = 130 DCHECK(shell_handle_.is_valid());
128 load_callbacks_->RegisterApplication();
129 if (!shell_handle.is_valid()) {
130 ReportComplete();
131 return;
132 }
133 131
134 if (!path_exists) { 132 if (!path_exists) {
135 LOG(ERROR) << "Library not started because library path '" << path.value() 133 LOG(ERROR) << "Library not started because library path '" << path.value()
136 << "' does not exist."; 134 << "' does not exist.";
137 ReportComplete(); 135 ReportComplete();
138 return; 136 return;
139 } 137 }
140 138
141 runner_ = runner_factory_->Create(context_); 139 runner_ = runner_factory_->Create(context_);
142 runner_->Start( 140 runner_->Start(
143 path, shell_handle.Pass(), 141 path, shell_handle_.Pass(),
144 base::Bind(&Loader::ReportComplete, weak_ptr_factory_.GetWeakPtr())); 142 base::Bind(&Loader::ReportComplete, weak_ptr_factory_.GetWeakPtr()));
145 } 143 }
146 144
147 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks_; 145 ScopedMessagePipeHandle shell_handle_;
146 ApplicationLoader::LoadCallback load_callback_;
148 LoaderCompleteCallback loader_complete_callback_; 147 LoaderCompleteCallback loader_complete_callback_;
149 Context* context_; 148 Context* context_;
150 MimeTypeToURLMap* mime_type_to_url_; 149 MimeTypeToURLMap* mime_type_to_url_;
151 DynamicServiceRunnerFactory* runner_factory_; 150 DynamicServiceRunnerFactory* runner_factory_;
152 scoped_ptr<DynamicServiceRunner> runner_; 151 scoped_ptr<DynamicServiceRunner> runner_;
153 base::WeakPtrFactory<Loader> weak_ptr_factory_; 152 base::WeakPtrFactory<Loader> weak_ptr_factory_;
154 }; 153 };
155 154
156 // A loader for local files. 155 // A loader for local files.
157 class DynamicApplicationLoader::LocalLoader : public Loader { 156 class DynamicApplicationLoader::LocalLoader : public Loader {
158 public: 157 public:
159 LocalLoader(const GURL& url, 158 LocalLoader(const GURL& url,
160 MimeTypeToURLMap* mime_type_to_url, 159 MimeTypeToURLMap* mime_type_to_url,
161 Context* context, 160 Context* context,
162 DynamicServiceRunnerFactory* runner_factory, 161 DynamicServiceRunnerFactory* runner_factory,
163 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks, 162 ScopedMessagePipeHandle shell_handle,
163 ApplicationLoader::LoadCallback load_callback,
164 const LoaderCompleteCallback& loader_complete_callback) 164 const LoaderCompleteCallback& loader_complete_callback)
165 : Loader(mime_type_to_url, 165 : Loader(mime_type_to_url,
166 context, 166 context,
167 runner_factory, 167 runner_factory,
168 load_callbacks, 168 shell_handle.Pass(),
169 load_callback,
169 loader_complete_callback), 170 loader_complete_callback),
170 url_(url), 171 url_(url),
171 path_(UrlToFile(url)) { 172 path_(UrlToFile(url)) {
172 Load(); 173 Load();
173 } 174 }
174 175
175 private: 176 private:
176 static base::FilePath UrlToFile(const GURL& url) { 177 static base::FilePath UrlToFile(const GURL& url) {
177 DCHECK(url.SchemeIsFile()); 178 DCHECK(url.SchemeIsFile());
178 url::RawCanonOutputW<1024> output; 179 url::RawCanonOutputW<1024> output;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 }; 240 };
240 241
241 // A loader for network files. 242 // A loader for network files.
242 class DynamicApplicationLoader::NetworkLoader : public Loader { 243 class DynamicApplicationLoader::NetworkLoader : public Loader {
243 public: 244 public:
244 NetworkLoader(const GURL& url, 245 NetworkLoader(const GURL& url,
245 NetworkService* network_service, 246 NetworkService* network_service,
246 MimeTypeToURLMap* mime_type_to_url, 247 MimeTypeToURLMap* mime_type_to_url,
247 Context* context, 248 Context* context,
248 DynamicServiceRunnerFactory* runner_factory, 249 DynamicServiceRunnerFactory* runner_factory,
249 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks, 250 ScopedMessagePipeHandle shell_handle,
251 ApplicationLoader::LoadCallback load_callback,
250 const LoaderCompleteCallback& loader_complete_callback) 252 const LoaderCompleteCallback& loader_complete_callback)
251 : Loader(mime_type_to_url, 253 : Loader(mime_type_to_url,
252 context, 254 context,
253 runner_factory, 255 runner_factory,
254 load_callbacks, 256 shell_handle.Pass(),
257 load_callback,
255 loader_complete_callback), 258 loader_complete_callback),
256 weak_ptr_factory_(this) { 259 weak_ptr_factory_(this) {
257 StartNetworkRequest(url, network_service); 260 StartNetworkRequest(url, network_service);
258 } 261 }
259 262
260 ~NetworkLoader() override { 263 ~NetworkLoader() override {
261 if (!path_.empty()) 264 if (!path_.empty())
262 base::DeleteFile(path_, false); 265 base::DeleteFile(path_, false);
263 } 266 }
264 267
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 361
359 DynamicApplicationLoader::~DynamicApplicationLoader() { 362 DynamicApplicationLoader::~DynamicApplicationLoader() {
360 } 363 }
361 364
362 void DynamicApplicationLoader::RegisterContentHandler( 365 void DynamicApplicationLoader::RegisterContentHandler(
363 const std::string& mime_type, 366 const std::string& mime_type,
364 const GURL& content_handler_url) { 367 const GURL& content_handler_url) {
365 mime_type_to_url_[mime_type] = content_handler_url; 368 mime_type_to_url_[mime_type] = content_handler_url;
366 } 369 }
367 370
368 void DynamicApplicationLoader::Load( 371 void DynamicApplicationLoader::Load(ApplicationManager* manager,
369 ApplicationManager* manager, 372 const GURL& url,
370 const GURL& url, 373 ScopedMessagePipeHandle shell_handle,
371 scoped_refptr<LoadCallbacks> load_callbacks) { 374 LoadCallback load_callback) {
372 if (url.SchemeIsFile()) { 375 if (url.SchemeIsFile()) {
373 loaders_.push_back(new LocalLoader(url, &mime_type_to_url_, context_, 376 loaders_.push_back(new LocalLoader(
374 runner_factory_.get(), load_callbacks, 377 url, &mime_type_to_url_, context_, runner_factory_.get(),
375 loader_complete_callback_)); 378 shell_handle.Pass(), load_callback, loader_complete_callback_));
376 return; 379 return;
377 } 380 }
378 381
379 if (!network_service_) { 382 if (!network_service_) {
380 context_->application_manager()->ConnectToService( 383 context_->application_manager()->ConnectToService(
381 GURL("mojo:network_service"), &network_service_); 384 GURL("mojo:network_service"), &network_service_);
382 } 385 }
383 386
384 loaders_.push_back(new NetworkLoader( 387 loaders_.push_back(
385 url, network_service_.get(), &mime_type_to_url_, context_, 388 new NetworkLoader(url, network_service_.get(), &mime_type_to_url_,
386 runner_factory_.get(), load_callbacks, loader_complete_callback_)); 389 context_, runner_factory_.get(), shell_handle.Pass(),
390 load_callback, loader_complete_callback_));
387 } 391 }
388 392
389 void DynamicApplicationLoader::OnApplicationError(ApplicationManager* manager, 393 void DynamicApplicationLoader::OnApplicationError(ApplicationManager* manager,
390 const GURL& url) { 394 const GURL& url) {
391 // TODO(darin): What should we do about service errors? This implies that 395 // TODO(darin): What should we do about service errors? This implies that
392 // the app closed its handle to the service manager. Maybe we don't care? 396 // the app closed its handle to the service manager. Maybe we don't care?
393 } 397 }
394 398
395 void DynamicApplicationLoader::LoaderComplete(Loader* loader) { 399 void DynamicApplicationLoader::LoaderComplete(Loader* loader) {
396 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader)); 400 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader));
397 } 401 }
398 402
399 } // namespace shell 403 } // namespace shell
400 } // namespace mojo 404 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/shell/dynamic_application_loader.h ('k') | mojo/shell/dynamic_application_loader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698