Chromium Code Reviews| 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...) Expand 10 before | Expand all | Expand 10 after 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 |