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 |