| 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/shell/application_instance.h" | 5 #include "mojo/shell/application_instance.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "mojo/application/public/interfaces/content_handler.mojom.h" | 9 #include "mojo/application/public/interfaces/content_handler.mojom.h" |
| 10 #include "mojo/common/common_type_converters.h" | 10 #include "mojo/common/common_type_converters.h" |
| 11 #include "mojo/common/url_type_converters.h" | 11 #include "mojo/common/url_type_converters.h" |
| 12 #include "mojo/shell/application_manager.h" | 12 #include "mojo/shell/application_manager.h" |
| 13 #include "mojo/shell/content_handler_connection.h" |
| 13 | 14 |
| 14 namespace mojo { | 15 namespace mojo { |
| 15 namespace shell { | 16 namespace shell { |
| 17 namespace { |
| 16 | 18 |
| 17 // It's valid to specify mojo: URLs in the filter either as mojo:foo or | 19 // It's valid to specify mojo: URLs in the filter either as mojo:foo or |
| 18 // mojo://foo/ - but we store the filter in the latter form. | 20 // mojo://foo/ - but we store the filter in the latter form. |
| 19 CapabilityFilter CanonicalizeFilter(const CapabilityFilter& filter) { | 21 CapabilityFilter CanonicalizeFilter(const CapabilityFilter& filter) { |
| 20 CapabilityFilter canonicalized; | 22 CapabilityFilter canonicalized; |
| 21 for (CapabilityFilter::const_iterator it = filter.begin(); | 23 for (CapabilityFilter::const_iterator it = filter.begin(); |
| 22 it != filter.end(); | 24 it != filter.end(); |
| 23 ++it) { | 25 ++it) { |
| 24 if (it->first == "*") | 26 if (it->first == "*") |
| 25 canonicalized[it->first] = it->second; | 27 canonicalized[it->first] = it->second; |
| 26 else | 28 else |
| 27 canonicalized[GURL(it->first).spec()] = it->second; | 29 canonicalized[GURL(it->first).spec()] = it->second; |
| 28 } | 30 } |
| 29 return canonicalized; | 31 return canonicalized; |
| 30 } | 32 } |
| 31 | 33 |
| 34 } // namespace |
| 35 |
| 32 ApplicationInstance::QueuedClientRequest::QueuedClientRequest() | 36 ApplicationInstance::QueuedClientRequest::QueuedClientRequest() |
| 33 : originator(nullptr) {} | 37 : originator(nullptr) {} |
| 34 | 38 |
| 35 ApplicationInstance::QueuedClientRequest::~QueuedClientRequest() { | 39 ApplicationInstance::QueuedClientRequest::~QueuedClientRequest() { |
| 36 } | 40 } |
| 37 | 41 |
| 38 ApplicationInstance::ApplicationInstance( | 42 ApplicationInstance::ApplicationInstance( |
| 39 ApplicationPtr application, | 43 ApplicationPtr application, |
| 40 ApplicationManager* manager, | 44 ApplicationManager* manager, |
| 41 const Identity& originator_identity, | 45 const Identity& originator_identity, |
| 42 const Identity& identity, | 46 const Identity& identity, |
| 43 const CapabilityFilter& filter, | 47 const CapabilityFilter& filter, |
| 48 uint32_t requesting_content_handler_id, |
| 44 const base::Closure& on_application_end) | 49 const base::Closure& on_application_end) |
| 45 : manager_(manager), | 50 : manager_(manager), |
| 46 originator_identity_(originator_identity), | 51 originator_identity_(originator_identity), |
| 47 identity_(identity), | 52 identity_(identity), |
| 48 filter_(CanonicalizeFilter(filter)), | 53 filter_(CanonicalizeFilter(filter)), |
| 49 allow_any_application_(filter.size() == 1 && filter.count("*") == 1), | 54 allow_any_application_(filter.size() == 1 && filter.count("*") == 1), |
| 55 requesting_content_handler_id_(requesting_content_handler_id), |
| 50 on_application_end_(on_application_end), | 56 on_application_end_(on_application_end), |
| 51 application_(application.Pass()), | 57 application_(application.Pass()), |
| 52 binding_(this), | 58 binding_(this), |
| 53 queue_requests_(false) { | 59 queue_requests_(false) { |
| 54 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); | 60 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); |
| 55 } | 61 } |
| 56 | 62 |
| 57 ApplicationInstance::~ApplicationInstance() { | 63 ApplicationInstance::~ApplicationInstance() { |
| 58 STLDeleteElements(&queued_client_requests_); | 64 STLDeleteElements(&queued_client_requests_); |
| 59 } | 65 } |
| 60 | 66 |
| 61 void ApplicationInstance::InitializeApplication() { | 67 void ApplicationInstance::InitializeApplication() { |
| 62 ShellPtr shell; | 68 ShellPtr shell; |
| 63 binding_.Bind(GetProxy(&shell)); | 69 binding_.Bind(GetProxy(&shell)); |
| 64 application_->Initialize(shell.Pass(), identity_.url.spec()); | 70 application_->Initialize(shell.Pass(), identity_.url.spec()); |
| 65 } | 71 } |
| 66 | 72 |
| 67 void ApplicationInstance::ConnectToClient( | 73 void ApplicationInstance::ConnectToClient( |
| 68 ApplicationInstance* originator, | 74 ApplicationInstance* originator, |
| 69 const GURL& requested_url, | 75 const GURL& requested_url, |
| 70 const GURL& requestor_url, | 76 const GURL& requestor_url, |
| 71 InterfaceRequest<ServiceProvider> services, | 77 InterfaceRequest<ServiceProvider> services, |
| 72 ServiceProviderPtr exposed_services, | 78 ServiceProviderPtr exposed_services, |
| 73 const CapabilityFilter& filter) { | 79 const CapabilityFilter& filter, |
| 80 const ConnectToApplicationCallback& callback) { |
| 81 callback.Run(requesting_content_handler_id_); |
| 74 if (queue_requests_) { | 82 if (queue_requests_) { |
| 75 QueuedClientRequest* queued_request = new QueuedClientRequest(); | 83 QueuedClientRequest* queued_request = new QueuedClientRequest(); |
| 76 queued_request->originator = originator; | 84 queued_request->originator = originator; |
| 77 queued_request->requested_url = requested_url; | 85 queued_request->requested_url = requested_url; |
| 78 queued_request->requestor_url = requestor_url; | 86 queued_request->requestor_url = requestor_url; |
| 79 queued_request->services = services.Pass(); | 87 queued_request->services = services.Pass(); |
| 80 queued_request->exposed_services = exposed_services.Pass(); | 88 queued_request->exposed_services = exposed_services.Pass(); |
| 81 queued_request->filter = filter; | 89 queued_request->filter = filter; |
| 82 queued_client_requests_.push_back(queued_request); | 90 queued_client_requests_.push_back(queued_request); |
| 83 return; | 91 return; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 101 | 109 |
| 102 // Finally, nothing is allowed. | 110 // Finally, nothing is allowed. |
| 103 return AllowedInterfaces(); | 111 return AllowedInterfaces(); |
| 104 } | 112 } |
| 105 | 113 |
| 106 // Shell implementation: | 114 // Shell implementation: |
| 107 void ApplicationInstance::ConnectToApplication( | 115 void ApplicationInstance::ConnectToApplication( |
| 108 URLRequestPtr app_request, | 116 URLRequestPtr app_request, |
| 109 InterfaceRequest<ServiceProvider> services, | 117 InterfaceRequest<ServiceProvider> services, |
| 110 ServiceProviderPtr exposed_services, | 118 ServiceProviderPtr exposed_services, |
| 111 CapabilityFilterPtr filter) { | 119 CapabilityFilterPtr filter, |
| 120 const ConnectToApplicationCallback& callback) { |
| 112 std::string url_string = app_request->url.To<std::string>(); | 121 std::string url_string = app_request->url.To<std::string>(); |
| 113 GURL url(url_string); | 122 GURL url(url_string); |
| 114 if (!url.is_valid()) { | 123 if (!url.is_valid()) { |
| 115 LOG(ERROR) << "Error: invalid URL: " << url_string; | 124 LOG(ERROR) << "Error: invalid URL: " << url_string; |
| 125 callback.Run(kInvalidContentHandlerID); |
| 116 return; | 126 return; |
| 117 } | 127 } |
| 118 if (allow_any_application_ || filter_.find(url.spec()) != filter_.end()) { | 128 if (allow_any_application_ || filter_.find(url.spec()) != filter_.end()) { |
| 119 CapabilityFilter capability_filter = GetPermissiveCapabilityFilter(); | 129 CapabilityFilter capability_filter = GetPermissiveCapabilityFilter(); |
| 120 if (!filter.is_null()) | 130 if (!filter.is_null()) |
| 121 capability_filter = filter->filter.To<CapabilityFilter>(); | 131 capability_filter = filter->filter.To<CapabilityFilter>(); |
| 122 manager_->ConnectToApplication(this, app_request.Pass(), std::string(), | 132 manager_->ConnectToApplication( |
| 123 identity_.url, services.Pass(), | 133 this, app_request.Pass(), std::string(), identity_.url, services.Pass(), |
| 124 exposed_services.Pass(), capability_filter, | 134 exposed_services.Pass(), capability_filter, base::Closure(), callback); |
| 125 base::Closure()); | |
| 126 } else { | 135 } else { |
| 127 LOG(WARNING) << "CapabilityFilter prevented connection from: " << | 136 LOG(WARNING) << "CapabilityFilter prevented connection from: " << |
| 128 identity_.url << " to: " << url.spec(); | 137 identity_.url << " to: " << url.spec(); |
| 138 callback.Run(kInvalidContentHandlerID); |
| 129 } | 139 } |
| 130 } | 140 } |
| 131 | 141 |
| 132 void ApplicationInstance::QuitApplication() { | 142 void ApplicationInstance::QuitApplication() { |
| 133 queue_requests_ = true; | 143 queue_requests_ = true; |
| 134 application_->OnQuitRequested( | 144 application_->OnQuitRequested( |
| 135 base::Bind(&ApplicationInstance::OnQuitRequestedResult, | 145 base::Bind(&ApplicationInstance::OnQuitRequestedResult, |
| 136 base::Unretained(this))); | 146 base::Unretained(this))); |
| 137 } | 147 } |
| 138 | 148 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 160 manager_->OnApplicationInstanceError(this); | 170 manager_->OnApplicationInstanceError(this); |
| 161 //|this| is deleted. | 171 //|this| is deleted. |
| 162 | 172 |
| 163 // If any queued requests came to shell during time it was shutting down, | 173 // If any queued requests came to shell during time it was shutting down, |
| 164 // start them now. | 174 // start them now. |
| 165 for (auto request : queued_client_requests) { | 175 for (auto request : queued_client_requests) { |
| 166 mojo::URLRequestPtr url(mojo::URLRequest::New()); | 176 mojo::URLRequestPtr url(mojo::URLRequest::New()); |
| 167 url->url = mojo::String::From(request->requested_url.spec()); | 177 url->url = mojo::String::From(request->requested_url.spec()); |
| 168 ApplicationInstance* originator = | 178 ApplicationInstance* originator = |
| 169 manager->GetApplicationInstance(originator_identity_); | 179 manager->GetApplicationInstance(originator_identity_); |
| 170 manager->ConnectToApplication(originator, url.Pass(), std::string(), | 180 manager->ConnectToApplication( |
| 171 request->requestor_url, | 181 originator, url.Pass(), std::string(), request->requestor_url, |
| 172 request->services.Pass(), | 182 request->services.Pass(), request->exposed_services.Pass(), |
| 173 request->exposed_services.Pass(), | 183 request->filter, base::Closure(), EmptyConnectCallback()); |
| 174 request->filter, | |
| 175 base::Closure()); | |
| 176 } | 184 } |
| 177 STLDeleteElements(&queued_client_requests); | 185 STLDeleteElements(&queued_client_requests); |
| 178 } | 186 } |
| 179 | 187 |
| 180 void ApplicationInstance::OnQuitRequestedResult(bool can_quit) { | 188 void ApplicationInstance::OnQuitRequestedResult(bool can_quit) { |
| 181 if (can_quit) | 189 if (can_quit) |
| 182 return; | 190 return; |
| 183 | 191 |
| 184 queue_requests_ = false; | 192 queue_requests_ = false; |
| 185 for (auto request : queued_client_requests_) { | 193 for (auto request : queued_client_requests_) { |
| 186 CallAcceptConnection(request->originator, | 194 CallAcceptConnection( |
| 187 request->requestor_url, | 195 request->originator, request->requestor_url, request->services.Pass(), |
| 188 request->services.Pass(), | 196 request->exposed_services.Pass(), request->requested_url); |
| 189 request->exposed_services.Pass(), | |
| 190 request->requested_url); | |
| 191 } | 197 } |
| 192 STLDeleteElements(&queued_client_requests_); | 198 STLDeleteElements(&queued_client_requests_); |
| 193 } | 199 } |
| 194 | 200 |
| 195 } // namespace shell | 201 } // namespace shell |
| 196 } // namespace mojo | 202 } // namespace mojo |
| OLD | NEW |