OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "mojo/package_manager/package_manager_impl.h" | |
6 | |
7 #include "mojo/fetcher/about_fetcher.h" | |
8 #include "mojo/fetcher/local_fetcher.h" | |
9 #include "mojo/fetcher/network_fetcher.h" | |
10 #include "mojo/fetcher/switches.h" | |
11 #include "mojo/fetcher/update_fetcher.h" | |
12 #include "mojo/shell/application_manager.h" | |
13 #include "mojo/shell/query_util.h" | |
14 #include "mojo/shell/switches.h" | |
15 #include "mojo/util/filename_util.h" | |
16 #include "url/gurl.h" | |
17 | |
18 namespace mojo { | |
19 namespace package_manager { | |
20 | |
21 PackageManagerImpl::PackageManagerImpl( | |
22 const base::FilePath& shell_file_root) | |
23 : application_manager_(nullptr), | |
24 disable_cache_(base::CommandLine::ForCurrentProcess()->HasSwitch( | |
25 switches::kDisableCache)) { | |
26 if (!shell_file_root.empty()) { | |
27 GURL mojo_root_file_url = | |
28 util::FilePathToFileURL(shell_file_root).Resolve(std::string()); | |
29 url_resolver_.reset(new fetcher::URLResolver(mojo_root_file_url)); | |
30 } | |
31 } | |
32 | |
33 PackageManagerImpl::~PackageManagerImpl() { | |
34 } | |
35 | |
36 void PackageManagerImpl::RegisterContentHandler( | |
37 const std::string& mime_type, | |
38 const GURL& content_handler_url) { | |
39 DCHECK(content_handler_url.is_valid()) | |
40 << "Content handler URL is invalid for mime type " << mime_type; | |
41 mime_type_to_url_[mime_type] = content_handler_url; | |
42 } | |
43 | |
44 void PackageManagerImpl::RegisterApplicationPackageAlias( | |
45 const GURL& alias, | |
46 const GURL& content_handler_package, | |
47 const std::string& qualifier) { | |
48 application_package_alias_[alias] = | |
49 std::make_pair(content_handler_package, qualifier); | |
50 } | |
51 | |
52 void PackageManagerImpl::SetApplicationManager( | |
53 shell::ApplicationManager* manager) { | |
54 application_manager_ = manager; | |
55 } | |
56 | |
57 GURL PackageManagerImpl::ResolveURL(const GURL& url) { | |
58 return url_resolver_.get() ? url_resolver_->ResolveMojoURL(url) : url; | |
59 } | |
60 | |
61 void PackageManagerImpl::FetchRequest( | |
62 URLRequestPtr request, | |
63 const shell::Fetcher::FetchCallback& loader_callback) { | |
64 GURL url(request->url); | |
65 if (url.SchemeIs(fetcher::AboutFetcher::kAboutScheme)) { | |
66 fetcher::AboutFetcher::Start(url, loader_callback); | |
67 return; | |
68 } | |
69 | |
70 GURL resolved_url = ResolveURL(url); | |
71 | |
72 if (resolved_url.SchemeIsFile()) { | |
73 // LocalFetcher uses the network service to infer MIME types from URLs. | |
74 // Skip this for mojo URLs to avoid recursively loading the network service. | |
75 if (!network_service_ && !url.SchemeIs("mojo")) { | |
76 application_manager_->ConnectToService(GURL("mojo:network_service"), | |
77 &network_service_); | |
78 } | |
79 // Ownership of this object is transferred to |loader_callback|. | |
80 // TODO(beng): this is eff'n weird. | |
81 new fetcher::LocalFetcher( | |
82 network_service_.get(), resolved_url, | |
83 shell::GetBaseURLAndQuery(resolved_url, nullptr), | |
84 loader_callback); | |
85 return; | |
86 } | |
87 | |
88 #if 0 | |
89 // TODO(beng): figure out how this should be integrated now that mapped_url | |
90 // is toast. | |
91 // TODO(scottmg): to quote someone I know, if you liked this you shouldda put | |
92 // a test on it. | |
93 if (url.SchemeIs("mojo") && | |
94 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
95 switches::kUseUpdater)) { | |
96 application_manager_->ConnectToService(GURL("mojo:updater"), &updater_); | |
97 // Ownership of this object is transferred to |loader_callback|. | |
98 // TODO(beng): this is eff'n weird. | |
99 new fetcher::UpdateFetcher(url, updater_.get(), loader_callback); | |
100 return; | |
101 } | |
102 #endif | |
103 | |
104 if (!url_loader_factory_) { | |
105 application_manager_->ConnectToService(GURL("mojo:network_service"), | |
106 &url_loader_factory_); | |
107 } | |
108 | |
109 // Ownership of this object is transferred to |loader_callback|. | |
110 // TODO(beng): this is eff'n weird. | |
111 new fetcher::NetworkFetcher(disable_cache_, request.Pass(), | |
112 url_loader_factory_.get(), loader_callback); | |
113 } | |
114 | |
115 bool PackageManagerImpl::HandleWithContentHandler(shell::Fetcher* fetcher, | |
116 const GURL& unresolved_url, | |
117 base::TaskRunner* task_runner, | |
118 URLResponsePtr* new_response, | |
119 GURL* content_handler_url, | |
120 std::string* qualifier) { | |
121 // TODO(beng): it seems like some delegate should/would want to have a say in | |
122 // configuring the qualifier also. | |
123 bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( | |
124 switches::kEnableMultiprocess); | |
125 | |
126 // The response begins with a #!mojo <content-handler-url>. | |
127 std::string shebang; | |
128 if (fetcher->PeekContentHandler(&shebang, content_handler_url)) { | |
129 *new_response = fetcher->AsURLResponse( | |
130 task_runner, static_cast<int>(shebang.size())); | |
131 *qualifier = enable_multi_process ? (*new_response)->site.To<std::string>() | |
132 : std::string(); | |
133 return true; | |
134 } | |
135 | |
136 // The response MIME type matches a registered content handler. | |
137 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); | |
138 if (iter != mime_type_to_url_.end()) { | |
139 *new_response = fetcher->AsURLResponse(task_runner, 0); | |
140 *content_handler_url = iter->second; | |
141 *qualifier = enable_multi_process ? (*new_response)->site.To<std::string>() | |
142 : std::string(); | |
143 return true; | |
144 } | |
145 | |
146 // The response URL matches a registered content handler. | |
147 auto alias_iter = application_package_alias_.find(unresolved_url); | |
148 if (alias_iter != application_package_alias_.end()) { | |
149 // We replace the qualifier with the one our package alias requested. | |
150 *new_response = URLResponse::New(); | |
151 (*new_response)->url = unresolved_url.spec(); | |
152 | |
153 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
154 switches::kEnableMultiprocess)) { | |
155 // Why can't we use this in single process mode? Because of | |
156 // base::AtExitManager. If you link in ApplicationRunner into | |
157 // your code, and then we make initialize multiple copies of the | |
158 // application, we end up with multiple AtExitManagers and will check on | |
159 // the second one being created. | |
160 // | |
161 // Why doesn't that happen when running different apps? Because | |
162 // your_thing.mojo!base::AtExitManager and | |
163 // my_thing.mojo!base::AtExitManager are different symbols. | |
164 *qualifier = alias_iter->second.second; | |
yzshen1
2015/09/16 23:47:20
Please consider explicitly setting |*qualifier| to
| |
165 } | |
166 | |
167 *content_handler_url = alias_iter->second.first; | |
168 return true; | |
169 } | |
170 | |
171 return false; | |
172 } | |
173 | |
174 } // namespace package_manager | |
175 } // namespace mojo | |
OLD | NEW |