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 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 107 |
102 // Finally, nothing is allowed. | 108 // Finally, nothing is allowed. |
103 return AllowedInterfaces(); | 109 return AllowedInterfaces(); |
104 } | 110 } |
105 | 111 |
106 // Shell implementation: | 112 // Shell implementation: |
107 void ApplicationInstance::ConnectToApplication( | 113 void ApplicationInstance::ConnectToApplication( |
108 URLRequestPtr app_request, | 114 URLRequestPtr app_request, |
109 InterfaceRequest<ServiceProvider> services, | 115 InterfaceRequest<ServiceProvider> services, |
110 ServiceProviderPtr exposed_services, | 116 ServiceProviderPtr exposed_services, |
111 CapabilityFilterPtr filter) { | 117 CapabilityFilterPtr filter, |
| 118 const ConnectToApplicationCallback& callback) { |
112 std::string url_string = app_request->url.To<std::string>(); | 119 std::string url_string = app_request->url.To<std::string>(); |
113 GURL url(url_string); | 120 GURL url(url_string); |
114 if (!url.is_valid()) { | 121 if (!url.is_valid()) { |
115 LOG(ERROR) << "Error: invalid URL: " << url_string; | 122 LOG(ERROR) << "Error: invalid URL: " << url_string; |
| 123 callback.Run(ApplicationManager::kInvalidContentHandlerID); |
116 return; | 124 return; |
117 } | 125 } |
118 if (allow_any_application_ || filter_.find(url.spec()) != filter_.end()) { | 126 if (allow_any_application_ || filter_.find(url.spec()) != filter_.end()) { |
119 CapabilityFilter capability_filter = GetPermissiveCapabilityFilter(); | 127 CapabilityFilter capability_filter = GetPermissiveCapabilityFilter(); |
120 if (!filter.is_null()) | 128 if (!filter.is_null()) |
121 capability_filter = filter->filter.To<CapabilityFilter>(); | 129 capability_filter = filter->filter.To<CapabilityFilter>(); |
122 manager_->ConnectToApplication(this, app_request.Pass(), std::string(), | 130 manager_->ConnectToApplication( |
123 identity_.url, services.Pass(), | 131 this, app_request.Pass(), std::string(), identity_.url, |
124 exposed_services.Pass(), capability_filter, | 132 ApplicationManager::kInvalidContentHandlerID, services.Pass(), |
125 base::Closure()); | 133 exposed_services.Pass(), capability_filter, base::Closure(), callback); |
126 } else { | 134 } else { |
127 LOG(WARNING) << "CapabilityFilter prevented connection from: " << | 135 LOG(WARNING) << "CapabilityFilter prevented connection from: " << |
128 identity_.url << " to: " << url.spec(); | 136 identity_.url << " to: " << url.spec(); |
| 137 callback.Run(ApplicationManager::kInvalidContentHandlerID); |
129 } | 138 } |
130 } | 139 } |
131 | 140 |
132 void ApplicationInstance::QuitApplication() { | 141 void ApplicationInstance::QuitApplication() { |
133 queue_requests_ = true; | 142 queue_requests_ = true; |
134 application_->OnQuitRequested( | 143 application_->OnQuitRequested( |
135 base::Bind(&ApplicationInstance::OnQuitRequestedResult, | 144 base::Bind(&ApplicationInstance::OnQuitRequestedResult, |
136 base::Unretained(this))); | 145 base::Unretained(this))); |
137 } | 146 } |
138 | 147 |
(...skipping 21 matching lines...) Expand all Loading... |
160 manager_->OnApplicationInstanceError(this); | 169 manager_->OnApplicationInstanceError(this); |
161 //|this| is deleted. | 170 //|this| is deleted. |
162 | 171 |
163 // If any queued requests came to shell during time it was shutting down, | 172 // If any queued requests came to shell during time it was shutting down, |
164 // start them now. | 173 // start them now. |
165 for (auto request : queued_client_requests) { | 174 for (auto request : queued_client_requests) { |
166 mojo::URLRequestPtr url(mojo::URLRequest::New()); | 175 mojo::URLRequestPtr url(mojo::URLRequest::New()); |
167 url->url = mojo::String::From(request->requested_url.spec()); | 176 url->url = mojo::String::From(request->requested_url.spec()); |
168 ApplicationInstance* originator = | 177 ApplicationInstance* originator = |
169 manager->GetApplicationInstance(originator_identity_); | 178 manager->GetApplicationInstance(originator_identity_); |
170 manager->ConnectToApplication(originator, url.Pass(), std::string(), | 179 manager->ConnectToApplication( |
171 request->requestor_url, | 180 originator, url.Pass(), std::string(), request->requestor_url, |
172 request->services.Pass(), | 181 ApplicationManager::kInvalidContentHandlerID, request->services.Pass(), |
173 request->exposed_services.Pass(), | 182 request->exposed_services.Pass(), request->filter, base::Closure(), |
174 request->filter, | 183 EmptyConnectCallback()); |
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 |