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

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

Issue 694303002: Allow local file to run though content handler. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Follow review 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
« no previous file with comments | « mojo/common/data_pipe_utils_unittest.cc ('k') | no next file » | 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/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"
11 #include "base/format_macros.h"
12 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h" 14 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
14 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
16 #include "mojo/common/common_type_converters.h" 19 #include "mojo/common/common_type_converters.h"
17 #include "mojo/common/data_pipe_utils.h" 20 #include "mojo/common/data_pipe_utils.h"
21 #include "mojo/public/cpp/system/data_pipe.h"
18 #include "mojo/services/public/interfaces/network/url_loader.mojom.h" 22 #include "mojo/services/public/interfaces/network/url_loader.mojom.h"
19 #include "mojo/shell/context.h" 23 #include "mojo/shell/context.h"
20 #include "mojo/shell/data_pipe_peek.h" 24 #include "mojo/shell/data_pipe_peek.h"
21 #include "mojo/shell/filename_util.h" 25 #include "mojo/shell/filename_util.h"
22 #include "mojo/shell/switches.h" 26 #include "mojo/shell/switches.h"
23 #include "url/url_util.h" 27 #include "url/url_util.h"
24 28
25 namespace mojo { 29 namespace mojo {
26 namespace shell { 30 namespace shell {
27 31
32 namespace {
33
34 static const char kMojoMagic[] = "#!mojo:";
35 static const size_t kMaxShebangLength = 2048;
36
37 void IgnoreResult(bool result) {
38 }
39
40 } // namespace
41
28 // Encapsulates loading and running one individual application. 42 // Encapsulates loading and running one individual application.
29 // 43 //
30 // Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must 44 // Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must
31 // ensure that all the parameters passed to Loader subclasses stay valid through 45 // ensure that all the parameters passed to Loader subclasses stay valid through
32 // Loader's lifetime. 46 // Loader's lifetime.
33 // 47 //
34 // Async operations are done with WeakPtr to protect against 48 // Async operations are done with WeakPtr to protect against
35 // DynamicApplicationLoader going away (and taking all the Loaders with it) 49 // DynamicApplicationLoader going away (and taking all the Loaders with it)
36 // while the async operation is outstanding. 50 // while the async operation is outstanding.
37 class DynamicApplicationLoader::Loader { 51 class DynamicApplicationLoader::Loader {
38 public: 52 public:
39 Loader(Context* context, 53 Loader(MimeTypeToURLMap* mime_type_to_url,
54 Context* context,
40 DynamicServiceRunnerFactory* runner_factory, 55 DynamicServiceRunnerFactory* runner_factory,
41 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks, 56 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
42 const LoaderCompleteCallback& loader_complete_callback) 57 const LoaderCompleteCallback& loader_complete_callback)
43 : load_callbacks_(load_callbacks), 58 : load_callbacks_(load_callbacks),
44 loader_complete_callback_(loader_complete_callback), 59 loader_complete_callback_(loader_complete_callback),
45 context_(context), 60 context_(context),
61 mime_type_to_url_(mime_type_to_url),
46 runner_factory_(runner_factory), 62 runner_factory_(runner_factory),
47 weak_ptr_factory_(this) {} 63 weak_ptr_factory_(this) {}
48 64
49 virtual ~Loader() {} 65 virtual ~Loader() {}
50 66
51 protected: 67 protected:
68 virtual URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
69 uint32_t skip) = 0;
70
71 virtual void AsPath(
72 base::TaskRunner* task_runner,
73 base::Callback<void(const base::FilePath&, bool)> callback) = 0;
74
75 virtual std::string MimeType() = 0;
76
77 virtual bool HasMojoMagic() = 0;
78
79 virtual bool PeekFirstLine(std::string* line) = 0;
80
81 void Load() {
82 // If the response begins with a #!mojo:<content-handler-url>, use it.
83 GURL url;
84 std::string shebang;
85 if (PeekContentHandler(&shebang, &url)) {
86 load_callbacks_->LoadWithContentHandler(
87 url, AsURLResponse(context_->task_runners()->blocking_pool(),
88 shebang.size()));
89 return;
90 }
91
92 MimeTypeToURLMap::iterator iter = mime_type_to_url_->find(MimeType());
93 if (iter != mime_type_to_url_->end()) {
94 load_callbacks_->LoadWithContentHandler(
95 iter->second,
96 AsURLResponse(context_->task_runners()->blocking_pool(), 0));
97 return;
98 }
99
100 // 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
102 // header, or looking for some specific mojo signature prepended to the
103 // library.
104
105 AsPath(context_->task_runners()->blocking_pool(),
106 base::Bind(&Loader::RunLibrary, weak_ptr_factory_.GetWeakPtr()));
107 }
108
109 void ReportComplete() { loader_complete_callback_.Run(this); }
110
111 private:
112 bool PeekContentHandler(std::string* mojo_shebang,
113 GURL* mojo_content_handler_url) {
114 std::string shebang;
115 if (HasMojoMagic() && PeekFirstLine(&shebang)) {
116 GURL url(shebang.substr(2, std::string::npos));
117 if (url.is_valid()) {
118 *mojo_shebang = shebang;
119 *mojo_content_handler_url = url;
120 return true;
121 }
122 }
123 return false;
124 }
125
52 void RunLibrary(const base::FilePath& path, bool path_exists) { 126 void RunLibrary(const base::FilePath& path, bool path_exists) {
53 ScopedMessagePipeHandle shell_handle = 127 ScopedMessagePipeHandle shell_handle =
54 load_callbacks_->RegisterApplication(); 128 load_callbacks_->RegisterApplication();
55 if (!shell_handle.is_valid()) { 129 if (!shell_handle.is_valid()) {
56 LoaderComplete(); 130 ReportComplete();
57 return; 131 return;
58 } 132 }
59 133
60 if (!path_exists) { 134 if (!path_exists) {
61 LOG(ERROR) << "Library not started because library path '" << path.value() 135 LOG(ERROR) << "Library not started because library path '" << path.value()
62 << "' does not exist."; 136 << "' does not exist.";
63 LoaderComplete(); 137 ReportComplete();
64 return; 138 return;
65 } 139 }
66 140
67 runner_ = runner_factory_->Create(context_); 141 runner_ = runner_factory_->Create(context_);
68 runner_->Start( 142 runner_->Start(
69 path, 143 path, shell_handle.Pass(),
70 shell_handle.Pass(), 144 base::Bind(&Loader::ReportComplete, weak_ptr_factory_.GetWeakPtr()));
71 base::Bind(&Loader::LoaderComplete, weak_ptr_factory_.GetWeakPtr()));
72 } 145 }
73 146
74 void LoaderComplete() { loader_complete_callback_.Run(this); }
75
76 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks_; 147 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks_;
77 LoaderCompleteCallback loader_complete_callback_; 148 LoaderCompleteCallback loader_complete_callback_;
78 Context* context_; 149 Context* context_;
79 150 MimeTypeToURLMap* mime_type_to_url_;
80 private:
81 DynamicServiceRunnerFactory* runner_factory_; 151 DynamicServiceRunnerFactory* runner_factory_;
82 scoped_ptr<DynamicServiceRunner> runner_; 152 scoped_ptr<DynamicServiceRunner> runner_;
83 base::WeakPtrFactory<Loader> weak_ptr_factory_; 153 base::WeakPtrFactory<Loader> weak_ptr_factory_;
84 }; 154 };
85 155
86 // A loader for local files. 156 // A loader for local files.
87 class DynamicApplicationLoader::LocalLoader : public Loader { 157 class DynamicApplicationLoader::LocalLoader : public Loader {
88 public: 158 public:
89 LocalLoader(const GURL& url, 159 LocalLoader(const GURL& url,
160 MimeTypeToURLMap* mime_type_to_url,
90 Context* context, 161 Context* context,
91 DynamicServiceRunnerFactory* runner_factory, 162 DynamicServiceRunnerFactory* runner_factory,
92 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks, 163 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
93 const LoaderCompleteCallback& loader_complete_callback) 164 const LoaderCompleteCallback& loader_complete_callback)
94 : Loader(context, 165 : Loader(mime_type_to_url,
166 context,
95 runner_factory, 167 runner_factory,
96 load_callbacks, 168 load_callbacks,
97 loader_complete_callback), 169 loader_complete_callback),
98 weak_ptr_factory_(this) { 170 url_(url),
171 path_(UrlToFile(url)) {
172 Load();
173 }
174
175 private:
176 static base::FilePath UrlToFile(const GURL& url) {
99 DCHECK(url.SchemeIsFile()); 177 DCHECK(url.SchemeIsFile());
100 url::RawCanonOutputW<1024> output; 178 url::RawCanonOutputW<1024> output;
101 url::DecodeURLEscapeSequences( 179 url::DecodeURLEscapeSequences(
102 url.path().data(), static_cast<int>(url.path().length()), &output); 180 url.path().data(), static_cast<int>(url.path().length()), &output);
103 base::string16 decoded_path = 181 base::string16 decoded_path =
104 base::string16(output.data(), output.length()); 182 base::string16(output.data(), output.length());
105 #if defined(OS_WIN) 183 #if defined(OS_WIN)
106 base::TrimString(decoded_path, L"/", &decoded_path); 184 base::TrimString(decoded_path, L"/", &decoded_path);
107 base::FilePath path(decoded_path); 185 base::FilePath path(decoded_path);
108 #else 186 #else
109 base::FilePath path(base::UTF16ToUTF8(decoded_path)); 187 base::FilePath path(base::UTF16ToUTF8(decoded_path));
110 #endif 188 #endif
189 return path;
190 }
111 191
192 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
193 uint32_t skip) override {
194 URLResponsePtr response(URLResponse::New());
195 response->url = String::From(url_);
196 DataPipe data_pipe;
197 response->body = data_pipe.consumer_handle.Pass();
198 int64 file_size;
199 if (base::GetFileSize(path_, &file_size)) {
200 response->headers = Array<String>(1);
201 response->headers[0] =
202 base::StringPrintf("Content-Length: %" PRId64, file_size);
203 }
204 common::CopyFromFile(path_, data_pipe.producer_handle.Pass(), skip,
205 task_runner, base::Bind(&IgnoreResult));
206 return response.Pass();
207 }
208
209 void AsPath(
210 base::TaskRunner* task_runner,
211 base::Callback<void(const base::FilePath&, bool)> callback) override {
112 // Async for consistency with network case. 212 // Async for consistency with network case.
113 base::MessageLoop::current()->PostTask( 213 base::MessageLoop::current()->PostTask(
114 FROM_HERE, 214 FROM_HERE, base::Bind(callback, path_, base::PathExists(path_)));
115 base::Bind(&LocalLoader::RunLibrary,
116 weak_ptr_factory_.GetWeakPtr(),
117 path,
118 base::PathExists(path)));
119 } 215 }
120 216
121 ~LocalLoader() override {} 217 std::string MimeType() override { return ""; }
122 218
123 private: 219 bool HasMojoMagic() override {
124 base::WeakPtrFactory<LocalLoader> weak_ptr_factory_; 220 std::string magic;
221 ReadFileToString(path_, &magic, strlen(kMojoMagic));
222 return magic == kMojoMagic;
223 }
224
225 bool PeekFirstLine(std::string* line) override {
226 std::string start_of_file;
227 ReadFileToString(path_, &start_of_file, kMaxShebangLength);
228 size_t return_position = start_of_file.find('\n');
229 if (return_position == std::string::npos)
230 return false;
231 *line = start_of_file.substr(0, return_position + 1);
232 return true;
233 }
234
235 GURL url_;
236 base::FilePath path_;
237
238 DISALLOW_COPY_AND_ASSIGN(LocalLoader);
125 }; 239 };
126 240
127 // A loader for network files. 241 // A loader for network files.
128 class DynamicApplicationLoader::NetworkLoader : public Loader { 242 class DynamicApplicationLoader::NetworkLoader : public Loader {
129 public: 243 public:
130 NetworkLoader(const GURL& url, 244 NetworkLoader(const GURL& url,
245 NetworkService* network_service,
131 MimeTypeToURLMap* mime_type_to_url, 246 MimeTypeToURLMap* mime_type_to_url,
132 Context* context, 247 Context* context,
133 DynamicServiceRunnerFactory* runner_factory, 248 DynamicServiceRunnerFactory* runner_factory,
134 NetworkService* network_service,
135 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks, 249 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
136 const LoaderCompleteCallback& loader_complete_callback) 250 const LoaderCompleteCallback& loader_complete_callback)
137 : Loader(context, 251 : Loader(mime_type_to_url,
252 context,
138 runner_factory, 253 runner_factory,
139 load_callbacks, 254 load_callbacks,
140 loader_complete_callback), 255 loader_complete_callback),
141 mime_type_to_url_(mime_type_to_url),
142 weak_ptr_factory_(this) { 256 weak_ptr_factory_(this) {
257 StartNetworkRequest(url, network_service);
258 }
259
260 ~NetworkLoader() override {
261 if (!path_.empty())
262 base::DeleteFile(path_, false);
263 }
264
265 private:
266 // TODO(hansmuller): Revisit this when a real peek operation is available.
267 static const MojoDeadline kPeekTimeout = MOJO_DEADLINE_INDEFINITE;
268
269 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
270 uint32_t skip) override {
271 if (skip != 0) {
272 MojoResult result = ReadDataRaw(
273 response_->body.get(), nullptr, &skip,
274 MOJO_READ_DATA_FLAG_ALL_OR_NONE | MOJO_READ_DATA_FLAG_DISCARD);
275 DCHECK_EQ(result, MOJO_RESULT_OK);
276 }
277 return response_.Pass();
278 }
279
280 void AsPath(
281 base::TaskRunner* task_runner,
282 base::Callback<void(const base::FilePath&, bool)> callback) override {
283 if (!path_.empty() || !response_) {
284 base::MessageLoop::current()->PostTask(
285 FROM_HERE, base::Bind(callback, path_, base::PathExists(path_)));
286 return;
287 }
288 base::CreateTemporaryFile(&path_);
289 common::CopyToFile(response_->body.Pass(), path_, task_runner,
290 base::Bind(callback, path_));
291 }
292
293 std::string MimeType() override {
294 DCHECK(response_);
295 return response_->mime_type;
296 }
297
298 bool HasMojoMagic() override {
299 std::string magic;
300 return BlockingPeekNBytes(response_->body.get(), &magic, strlen(kMojoMagic),
301 kPeekTimeout) &&
302 magic == kMojoMagic;
303 }
304
305 bool PeekFirstLine(std::string* line) override {
306 return BlockingPeekLine(response_->body.get(), line, kMaxShebangLength,
307 kPeekTimeout);
308 }
309
310 void StartNetworkRequest(const GURL& url, NetworkService* network_service) {
143 URLRequestPtr request(URLRequest::New()); 311 URLRequestPtr request(URLRequest::New());
144 request->url = String::From(url); 312 request->url = String::From(url);
145 request->auto_follow_redirects = true; 313 request->auto_follow_redirects = true;
146 314
147 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 315 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
148 switches::kDisableCache)) { 316 switches::kDisableCache)) {
149 request->bypass_cache = true; 317 request->bypass_cache = true;
150 } 318 }
151 319
152 network_service->CreateURLLoader(GetProxy(&url_loader_)); 320 network_service->CreateURLLoader(GetProxy(&url_loader_));
153 url_loader_->Start(request.Pass(), 321 url_loader_->Start(request.Pass(),
154 base::Bind(&NetworkLoader::OnLoadComplete, 322 base::Bind(&NetworkLoader::OnLoadComplete,
155 weak_ptr_factory_.GetWeakPtr())); 323 weak_ptr_factory_.GetWeakPtr()));
156 } 324 }
157 325
158 ~NetworkLoader() override {
159 if (!file_.empty())
160 base::DeleteFile(file_, false);
161 }
162
163 private:
164 bool PeekContentHandler(DataPipeConsumerHandle source,
165 std::string* mojo_shebang,
166 GURL* mojo_content_handler_url)
167 {
168 const char* kMojoMagic = "#!mojo:";
169 // TODO(hansmuller): Revisit this when a real peek operation is available.
170 const MojoDeadline kPeekTimeout = MOJO_DEADLINE_INDEFINITE;
171 const size_t kMaxShebangLength = 2048;
172
173 std::string magic;
174 std::string shebang;
175 if (BlockingPeekNBytes(source, &magic, strlen(kMojoMagic), kPeekTimeout) &&
176 magic == kMojoMagic &&
177 BlockingPeekLine(source, &shebang, kMaxShebangLength, kPeekTimeout)) {
178 GURL url(shebang.substr(2, std::string::npos));
179 if (url.is_valid()) {
180 *mojo_shebang = shebang;
181 *mojo_content_handler_url = url;
182 return true;
183 }
184 }
185 return false;
186 }
187
188 void OnLoadComplete(URLResponsePtr response) { 326 void OnLoadComplete(URLResponsePtr response) {
189 if (response->error) { 327 if (response->error) {
190 LOG(ERROR) << "Error (" << response->error->code << ": " 328 LOG(ERROR) << "Error (" << response->error->code << ": "
191 << response->error->description << ") while fetching " 329 << response->error->description << ") while fetching "
192 << response->url; 330 << response->url;
193 LoaderComplete(); 331 ReportComplete();
194 return; 332 return;
195 } 333 }
196 334 response_ = response.Pass();
197 // If the response begins with a #!mojo:<content-handler-url>, use it. 335 Load();
198 {
199 GURL url;
200 std::string shebang;
201 if (PeekContentHandler(response->body.get(), &shebang, &url)) {
202 uint32_t num_skip_bytes = shebang.size();
203 if (ReadDataRaw(response->body.get(),
204 nullptr,
205 &num_skip_bytes,
206 MOJO_READ_DATA_FLAG_ALL_OR_NONE |
207 MOJO_READ_DATA_FLAG_DISCARD) ==
208 MOJO_RESULT_OK) {
209 load_callbacks_->LoadWithContentHandler(url, response.Pass());
210 return;
211 }
212 }
213 }
214
215 MimeTypeToURLMap::iterator iter =
216 mime_type_to_url_->find(response->mime_type);
217 if (iter != mime_type_to_url_->end()) {
218 load_callbacks_->LoadWithContentHandler(iter->second, response.Pass());
219 return;
220 }
221
222 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo
223 // application. That could either mean looking for the platform-specific dll
224 // header, or looking for some specific mojo signature prepended to the
225 // library.
226
227 base::CreateTemporaryFile(&file_);
228 common::CopyToFile(
229 response->body.Pass(),
230 file_,
231 context_->task_runners()->blocking_pool(),
232 base::Bind(
233 &NetworkLoader::RunLibrary, weak_ptr_factory_.GetWeakPtr(), file_));
234 } 336 }
235 337
236 MimeTypeToURLMap* mime_type_to_url_;
237 URLLoaderPtr url_loader_; 338 URLLoaderPtr url_loader_;
238 base::FilePath file_; 339 URLResponsePtr response_;
340 base::FilePath path_;
239 base::WeakPtrFactory<NetworkLoader> weak_ptr_factory_; 341 base::WeakPtrFactory<NetworkLoader> weak_ptr_factory_;
342
343 DISALLOW_COPY_AND_ASSIGN(NetworkLoader);
240 }; 344 };
345
241 DynamicApplicationLoader::DynamicApplicationLoader( 346 DynamicApplicationLoader::DynamicApplicationLoader(
242 Context* context, 347 Context* context,
243 scoped_ptr<DynamicServiceRunnerFactory> runner_factory) 348 scoped_ptr<DynamicServiceRunnerFactory> runner_factory)
244 : context_(context), 349 : context_(context),
245 runner_factory_(runner_factory.Pass()), 350 runner_factory_(runner_factory.Pass()),
246 351
247 // Unretained() is correct here because DynamicApplicationLoader owns the 352 // Unretained() is correct here because DynamicApplicationLoader owns the
248 // loaders that we pass this callback to. 353 // loaders that we pass this callback to.
249 loader_complete_callback_( 354 loader_complete_callback_(
250 base::Bind(&DynamicApplicationLoader::LoaderComplete, 355 base::Bind(&DynamicApplicationLoader::LoaderComplete,
251 base::Unretained(this))) { 356 base::Unretained(this))) {
252 } 357 }
253 358
254 DynamicApplicationLoader::~DynamicApplicationLoader() { 359 DynamicApplicationLoader::~DynamicApplicationLoader() {
255 } 360 }
256 361
257 void DynamicApplicationLoader::RegisterContentHandler( 362 void DynamicApplicationLoader::RegisterContentHandler(
258 const std::string& mime_type, 363 const std::string& mime_type,
259 const GURL& content_handler_url) { 364 const GURL& content_handler_url) {
260 mime_type_to_url_[mime_type] = content_handler_url; 365 mime_type_to_url_[mime_type] = content_handler_url;
261 } 366 }
262 367
263 void DynamicApplicationLoader::Load( 368 void DynamicApplicationLoader::Load(
264 ApplicationManager* manager, 369 ApplicationManager* manager,
265 const GURL& url, 370 const GURL& url,
266 scoped_refptr<LoadCallbacks> load_callbacks) { 371 scoped_refptr<LoadCallbacks> load_callbacks) {
267 if (url.SchemeIsFile()) { 372 if (url.SchemeIsFile()) {
268 loaders_.push_back(new LocalLoader(url, 373 loaders_.push_back(new LocalLoader(url, &mime_type_to_url_, context_,
269 context_, 374 runner_factory_.get(), load_callbacks,
270 runner_factory_.get(),
271 load_callbacks,
272 loader_complete_callback_)); 375 loader_complete_callback_));
273 return; 376 return;
274 } 377 }
275 378
276 if (!network_service_) { 379 if (!network_service_) {
277 context_->application_manager()->ConnectToService( 380 context_->application_manager()->ConnectToService(
278 GURL("mojo:network_service"), &network_service_); 381 GURL("mojo:network_service"), &network_service_);
279 } 382 }
280 383
281 loaders_.push_back(new NetworkLoader(url, 384 loaders_.push_back(new NetworkLoader(
282 &mime_type_to_url_, 385 url, network_service_.get(), &mime_type_to_url_, context_,
283 context_, 386 runner_factory_.get(), load_callbacks, loader_complete_callback_));
284 runner_factory_.get(),
285 network_service_.get(),
286 load_callbacks,
287 loader_complete_callback_));
288 } 387 }
289 388
290 void DynamicApplicationLoader::OnApplicationError(ApplicationManager* manager, 389 void DynamicApplicationLoader::OnApplicationError(ApplicationManager* manager,
291 const GURL& url) { 390 const GURL& url) {
292 // TODO(darin): What should we do about service errors? This implies that 391 // TODO(darin): What should we do about service errors? This implies that
293 // the app closed its handle to the service manager. Maybe we don't care? 392 // the app closed its handle to the service manager. Maybe we don't care?
294 } 393 }
295 394
296 void DynamicApplicationLoader::LoaderComplete(Loader* loader) { 395 void DynamicApplicationLoader::LoaderComplete(Loader* loader) {
297 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader)); 396 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader));
298 } 397 }
299 398
300 } // namespace shell 399 } // namespace shell
301 } // namespace mojo 400 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/common/data_pipe_utils_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698