OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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/package_manager/package_manager_impl.h" | 5 #include "mojo/package_manager/package_manager_impl.h" |
6 | 6 |
7 #include "base/bind.h" | |
8 #include "mojo/application/public/interfaces/content_handler.mojom.h" | |
7 #include "mojo/fetcher/about_fetcher.h" | 9 #include "mojo/fetcher/about_fetcher.h" |
8 #include "mojo/fetcher/data_fetcher.h" | 10 #include "mojo/fetcher/data_fetcher.h" |
9 #include "mojo/fetcher/local_fetcher.h" | 11 #include "mojo/fetcher/local_fetcher.h" |
10 #include "mojo/fetcher/network_fetcher.h" | 12 #include "mojo/fetcher/network_fetcher.h" |
11 #include "mojo/fetcher/switches.h" | 13 #include "mojo/fetcher/switches.h" |
12 #include "mojo/fetcher/update_fetcher.h" | 14 #include "mojo/fetcher/update_fetcher.h" |
15 #include "mojo/package_manager/content_handler_connection.h" | |
13 #include "mojo/shell/application_manager.h" | 16 #include "mojo/shell/application_manager.h" |
14 #include "mojo/shell/connect_util.h" | 17 #include "mojo/shell/connect_util.h" |
15 #include "mojo/shell/query_util.h" | 18 #include "mojo/shell/query_util.h" |
16 #include "mojo/shell/switches.h" | 19 #include "mojo/shell/switches.h" |
17 #include "mojo/util/filename_util.h" | 20 #include "mojo/util/filename_util.h" |
18 #include "url/gurl.h" | 21 #include "url/gurl.h" |
19 | 22 |
20 namespace mojo { | 23 namespace mojo { |
21 namespace package_manager { | 24 namespace package_manager { |
22 | 25 |
23 PackageManagerImpl::PackageManagerImpl( | 26 PackageManagerImpl::PackageManagerImpl( |
24 const base::FilePath& shell_file_root) | 27 const base::FilePath& shell_file_root, |
28 base::TaskRunner* task_runner) | |
25 : application_manager_(nullptr), | 29 : application_manager_(nullptr), |
26 disable_cache_(base::CommandLine::ForCurrentProcess()->HasSwitch( | 30 disable_cache_(base::CommandLine::ForCurrentProcess()->HasSwitch( |
27 switches::kDisableCache)) { | 31 switches::kDisableCache)), |
32 content_handler_id_counter_(0u), | |
33 task_runner_(task_runner) { | |
28 if (!shell_file_root.empty()) { | 34 if (!shell_file_root.empty()) { |
29 GURL mojo_root_file_url = | 35 GURL mojo_root_file_url = |
30 util::FilePathToFileURL(shell_file_root).Resolve(std::string()); | 36 util::FilePathToFileURL(shell_file_root).Resolve(std::string()); |
31 url_resolver_.reset(new fetcher::URLResolver(mojo_root_file_url)); | 37 url_resolver_.reset(new fetcher::URLResolver(mojo_root_file_url)); |
32 } | 38 } |
33 } | 39 } |
34 | 40 |
35 PackageManagerImpl::~PackageManagerImpl() { | 41 PackageManagerImpl::~PackageManagerImpl() { |
42 IdentityToContentHandlerMap identity_to_content_handler( | |
43 identity_to_content_handler_); | |
44 for (auto& pair : identity_to_content_handler) | |
45 pair.second->CloseConnection(); | |
36 } | 46 } |
37 | 47 |
38 void PackageManagerImpl::RegisterContentHandler( | 48 void PackageManagerImpl::RegisterContentHandler( |
39 const std::string& mime_type, | 49 const std::string& mime_type, |
40 const GURL& content_handler_url) { | 50 const GURL& content_handler_url) { |
41 DCHECK(content_handler_url.is_valid()) | 51 DCHECK(content_handler_url.is_valid()) |
42 << "Content handler URL is invalid for mime type " << mime_type; | 52 << "Content handler URL is invalid for mime type " << mime_type; |
43 mime_type_to_url_[mime_type] = content_handler_url; | 53 mime_type_to_url_[mime_type] = content_handler_url; |
44 } | 54 } |
45 | 55 |
(...skipping 62 matching lines...) Loading... | |
108 shell::ConnectToService(application_manager_, GURL("mojo:network_service"), | 118 shell::ConnectToService(application_manager_, GURL("mojo:network_service"), |
109 &url_loader_factory_); | 119 &url_loader_factory_); |
110 } | 120 } |
111 | 121 |
112 // Ownership of this object is transferred to |loader_callback|. | 122 // Ownership of this object is transferred to |loader_callback|. |
113 // TODO(beng): this is eff'n weird. | 123 // TODO(beng): this is eff'n weird. |
114 new fetcher::NetworkFetcher(disable_cache_, request.Pass(), | 124 new fetcher::NetworkFetcher(disable_cache_, request.Pass(), |
115 url_loader_factory_.get(), loader_callback); | 125 url_loader_factory_.get(), loader_callback); |
116 } | 126 } |
117 | 127 |
118 bool PackageManagerImpl::HandleWithContentHandler(shell::Fetcher* fetcher, | 128 uint32_t PackageManagerImpl::HandleWithContentHandler( |
119 const GURL& url, | 129 shell::Fetcher* fetcher, |
120 base::TaskRunner* task_runner, | 130 const shell::Identity& source, |
121 URLResponsePtr* new_response, | 131 const GURL& target_url, |
122 GURL* content_handler_url, | 132 const shell::CapabilityFilter& target_filter, |
123 std::string* qualifier) { | 133 InterfaceRequest<Application>* application_request) { |
134 shell::Identity content_handler_identity; | |
135 URLResponsePtr response; | |
136 if (ShouldHandleWithContentHandler(fetcher, | |
137 target_url, | |
138 target_filter, | |
139 &content_handler_identity, | |
140 &response)) { | |
141 ContentHandlerConnection* connection = | |
142 GetContentHandler(content_handler_identity, source); | |
143 connection->content_handler()->StartApplication(application_request->Pass(), | |
144 response.Pass()); | |
145 return connection->id(); | |
146 } | |
147 return Shell::kInvalidContentHandlerID; | |
148 } | |
149 | |
150 GURL PackageManagerImpl::ResolveURL(const GURL& url) { | |
151 return url_resolver_.get() ? url_resolver_->ResolveMojoURL(url) : url; | |
152 } | |
153 | |
154 bool PackageManagerImpl::ShouldHandleWithContentHandler( | |
155 shell::Fetcher* fetcher, | |
156 const GURL& target_url, | |
157 const shell::CapabilityFilter& target_filter, | |
158 shell::Identity* content_handler_identity, | |
159 URLResponsePtr* response) const { | |
124 // TODO(beng): it seems like some delegate should/would want to have a say in | 160 // TODO(beng): it seems like some delegate should/would want to have a say in |
125 // configuring the qualifier also. | 161 // configuring the qualifier also. |
126 bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( | 162 bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( |
127 switches::kEnableMultiprocess); | 163 switches::kEnableMultiprocess); |
128 | 164 |
165 GURL content_handler_url; | |
129 // The response begins with a #!mojo <content-handler-url>. | 166 // The response begins with a #!mojo <content-handler-url>. |
130 std::string shebang; | 167 std::string shebang; |
131 if (fetcher->PeekContentHandler(&shebang, content_handler_url)) { | 168 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { |
132 *new_response = fetcher->AsURLResponse( | 169 *response = fetcher->AsURLResponse(task_runner_, |
133 task_runner, static_cast<int>(shebang.size())); | 170 static_cast<int>(shebang.size())); |
134 *qualifier = enable_multi_process ? (*new_response)->site.To<std::string>() | 171 *content_handler_identity = shell::Identity( |
135 : std::string(); | 172 content_handler_url, |
173 enable_multi_process ? (*response)->site.To<std::string>() | |
174 : std::string(), | |
175 target_filter); | |
136 return true; | 176 return true; |
137 } | 177 } |
138 | 178 |
139 // The response MIME type matches a registered content handler. | 179 // The response MIME type matches a registered content handler. |
140 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); | 180 auto iter = mime_type_to_url_.find(fetcher->MimeType()); |
141 if (iter != mime_type_to_url_.end()) { | 181 if (iter != mime_type_to_url_.end()) { |
142 *new_response = fetcher->AsURLResponse(task_runner, 0); | 182 *response = fetcher->AsURLResponse(task_runner_, 0); |
143 *content_handler_url = iter->second; | 183 *content_handler_identity = shell::Identity( |
144 *qualifier = enable_multi_process ? (*new_response)->site.To<std::string>() | 184 iter->second, |
145 : std::string(); | 185 enable_multi_process ? (*response)->site.To<std::string>() |
186 : std::string(), | |
187 target_filter); | |
146 return true; | 188 return true; |
147 } | 189 } |
148 | 190 |
149 // The response URL matches a registered content handler. | 191 // The response URL matches a registered content handler. |
150 auto alias_iter = application_package_alias_.find(url); | 192 auto alias_iter = application_package_alias_.find(target_url); |
151 if (alias_iter != application_package_alias_.end()) { | 193 if (alias_iter != application_package_alias_.end()) { |
152 // We replace the qualifier with the one our package alias requested. | 194 // We replace the qualifier with the one our package alias requested. |
153 *new_response = URLResponse::New(); | 195 *response = URLResponse::New(); |
154 (*new_response)->url = url.spec(); | 196 (*response)->url = target_url.spec(); |
155 | 197 |
156 // Why can't we use this in single process mode? Because of | 198 // Why can't we use this in single process mode? Because of |
yzshen1
2015/09/23 16:53:46
Because this comment seems to apply to all the thr
| |
157 // base::AtExitManager. If you link in ApplicationRunner into your code, and | 199 // base::AtExitManager. If you link in ApplicationRunner into your code, and |
158 // then we make initialize multiple copies of the application, we end up | 200 // then we make initialize multiple copies of the application, we end up |
159 // with multiple AtExitManagers and will check on the second one being | 201 // with multiple AtExitManagers and will check on the second one being |
160 // created. | 202 // created. |
161 // | 203 // |
162 // Why doesn't that happen when running different apps? Because | 204 // Why doesn't that happen when running different apps? Because |
163 // your_thing.mojo!base::AtExitManager and | 205 // your_thing.mojo!base::AtExitManager and |
164 // my_thing.mojo!base::AtExitManager are different symbols. | 206 // my_thing.mojo!base::AtExitManager are different symbols. |
165 *qualifier = enable_multi_process ? alias_iter->second.second | 207 *content_handler_identity = shell::Identity( |
166 : std::string(); | 208 alias_iter->second.first, |
167 *content_handler_url = alias_iter->second.first; | 209 enable_multi_process ? alias_iter->second.second |
210 : std::string(), | |
211 target_filter); | |
168 return true; | 212 return true; |
169 } | 213 } |
170 | 214 |
171 return false; | 215 return false; |
172 } | 216 } |
173 | 217 |
174 GURL PackageManagerImpl::ResolveURL(const GURL& url) { | 218 ContentHandlerConnection* PackageManagerImpl::GetContentHandler( |
175 return url_resolver_.get() ? url_resolver_->ResolveMojoURL(url) : url; | 219 const shell::Identity& content_handler_identity, |
220 const shell::Identity& source_identity) { | |
221 auto it = identity_to_content_handler_.find(content_handler_identity); | |
222 if (it != identity_to_content_handler_.end()) | |
223 return it->second; | |
224 | |
225 ContentHandlerConnection* connection = new ContentHandlerConnection( | |
226 application_manager_, source_identity, | |
227 content_handler_identity, | |
228 ++content_handler_id_counter_, | |
229 base::Bind(&PackageManagerImpl::OnContentHandlerConnectionClosed, | |
230 base::Unretained(this))); | |
231 identity_to_content_handler_[content_handler_identity] = connection; | |
232 return connection; | |
233 } | |
234 | |
235 void PackageManagerImpl::OnContentHandlerConnectionClosed( | |
236 ContentHandlerConnection* connection) { | |
237 // Remove the mapping. | |
238 auto it = identity_to_content_handler_.find(connection->identity()); | |
239 DCHECK(it != identity_to_content_handler_.end()); | |
240 identity_to_content_handler_.erase(it); | |
176 } | 241 } |
177 | 242 |
178 } // namespace package_manager | 243 } // namespace package_manager |
179 } // namespace mojo | 244 } // namespace mojo |
OLD | NEW |