Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: mojo/shell/application_instance.cc

Issue 1307273004: Group ConnectToApplication-related info into a params struct. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
(...skipping 15 matching lines...) Expand all
26 if (it->first == "*") 26 if (it->first == "*")
27 canonicalized[it->first] = it->second; 27 canonicalized[it->first] = it->second;
28 else 28 else
29 canonicalized[GURL(it->first).spec()] = it->second; 29 canonicalized[GURL(it->first).spec()] = it->second;
30 } 30 }
31 return canonicalized; 31 return canonicalized;
32 } 32 }
33 33
34 } // namespace 34 } // namespace
35 35
36 ApplicationInstance::QueuedClientRequest::QueuedClientRequest()
37 : originator(nullptr) {}
38
39 ApplicationInstance::QueuedClientRequest::~QueuedClientRequest() {
40 }
41
42 ApplicationInstance::ApplicationInstance( 36 ApplicationInstance::ApplicationInstance(
43 ApplicationPtr application, 37 ApplicationPtr application,
44 ApplicationManager* manager, 38 ApplicationManager* manager,
45 const Identity& originator_identity, 39 const Identity& originator_identity,
46 const Identity& identity, 40 const Identity& identity,
47 const CapabilityFilter& filter, 41 const CapabilityFilter& filter,
48 uint32_t requesting_content_handler_id, 42 uint32_t requesting_content_handler_id,
49 const base::Closure& on_application_end) 43 const base::Closure& on_application_end)
50 : manager_(manager), 44 : manager_(manager),
51 originator_identity_(originator_identity), 45 originator_identity_(originator_identity),
52 identity_(identity), 46 identity_(identity),
53 filter_(CanonicalizeFilter(filter)), 47 filter_(CanonicalizeFilter(filter)),
54 allow_any_application_(filter.size() == 1 && filter.count("*") == 1), 48 allow_any_application_(filter.size() == 1 && filter.count("*") == 1),
55 requesting_content_handler_id_(requesting_content_handler_id), 49 requesting_content_handler_id_(requesting_content_handler_id),
56 on_application_end_(on_application_end), 50 on_application_end_(on_application_end),
57 application_(application.Pass()), 51 application_(application.Pass()),
58 binding_(this), 52 binding_(this),
59 queue_requests_(false) { 53 queue_requests_(false) {
60 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); 54 binding_.set_connection_error_handler([this]() { OnConnectionError(); });
61 } 55 }
62 56
63 ApplicationInstance::~ApplicationInstance() { 57 ApplicationInstance::~ApplicationInstance() {
64 STLDeleteElements(&queued_client_requests_); 58 STLDeleteElements(&queued_client_requests_);
sky 2015/09/02 22:38:26 Do you need to also run the callbacks in queued_cl
yzshen1 2015/09/03 00:06:38 Good catch. :)
65 } 59 }
66 60
67 void ApplicationInstance::InitializeApplication() { 61 void ApplicationInstance::InitializeApplication() {
68 ShellPtr shell; 62 ShellPtr shell;
69 binding_.Bind(GetProxy(&shell)); 63 binding_.Bind(GetProxy(&shell));
70 application_->Initialize(shell.Pass(), identity_.url.spec()); 64 application_->Initialize(shell.Pass(), identity_.url.spec());
71 } 65 }
72 66
73 void ApplicationInstance::ConnectToClient( 67 void ApplicationInstance::ConnectToClient(
74 ApplicationInstance* originator, 68 scoped_ptr<ConnectToApplicationParams> params) {
75 const GURL& requested_url,
76 const GURL& requestor_url,
77 InterfaceRequest<ServiceProvider> services,
78 ServiceProviderPtr exposed_services,
79 const CapabilityFilter& filter,
80 const ConnectToApplicationCallback& callback) {
81 callback.Run(requesting_content_handler_id_);
82 if (queue_requests_) { 69 if (queue_requests_) {
83 QueuedClientRequest* queued_request = new QueuedClientRequest(); 70 queued_client_requests_.push_back(params.release());
84 queued_request->originator = originator;
85 queued_request->requested_url = requested_url;
86 queued_request->requestor_url = requestor_url;
87 queued_request->services = services.Pass();
88 queued_request->exposed_services = exposed_services.Pass();
89 queued_request->filter = filter;
90 queued_client_requests_.push_back(queued_request);
91 return; 71 return;
92 } 72 }
93 73
94 CallAcceptConnection(originator, requestor_url, services.Pass(), 74 CallAcceptConnection(params.Pass());
95 exposed_services.Pass(), requested_url);
96 }
97
98 AllowedInterfaces ApplicationInstance::GetAllowedInterfaces(
99 const Identity& identity) const {
100 // Start by looking for interfaces specific to the supplied identity.
101 auto it = filter_.find(identity.url.spec());
102 if (it != filter_.end())
103 return it->second;
104
105 // Fall back to looking for a wildcard rule.
106 it = filter_.find("*");
107 if (filter_.size() == 1 && it != filter_.end())
108 return it->second;
109
110 // Finally, nothing is allowed.
111 return AllowedInterfaces();
112 } 75 }
113 76
114 // Shell implementation: 77 // Shell implementation:
115 void ApplicationInstance::ConnectToApplication( 78 void ApplicationInstance::ConnectToApplication(
116 URLRequestPtr app_request, 79 URLRequestPtr app_request,
117 InterfaceRequest<ServiceProvider> services, 80 InterfaceRequest<ServiceProvider> services,
118 ServiceProviderPtr exposed_services, 81 ServiceProviderPtr exposed_services,
119 CapabilityFilterPtr filter, 82 CapabilityFilterPtr filter,
120 const ConnectToApplicationCallback& callback) { 83 const ConnectToApplicationCallback& callback) {
121 std::string url_string = app_request->url.To<std::string>(); 84 std::string url_string = app_request->url.To<std::string>();
(...skipping 18 matching lines...) Expand all
140 } 103 }
141 104
142 void ApplicationInstance::QuitApplication() { 105 void ApplicationInstance::QuitApplication() {
143 queue_requests_ = true; 106 queue_requests_ = true;
144 application_->OnQuitRequested( 107 application_->OnQuitRequested(
145 base::Bind(&ApplicationInstance::OnQuitRequestedResult, 108 base::Bind(&ApplicationInstance::OnQuitRequestedResult,
146 base::Unretained(this))); 109 base::Unretained(this)));
147 } 110 }
148 111
149 void ApplicationInstance::CallAcceptConnection( 112 void ApplicationInstance::CallAcceptConnection(
150 ApplicationInstance* originator, 113 scoped_ptr<ConnectToApplicationParams> params) {
151 const GURL& requestor_url, 114 params->connect_callback().Run(requesting_content_handler_id_);
152 InterfaceRequest<ServiceProvider> services,
153 ServiceProviderPtr exposed_services,
154 const GURL& requested_url) {
155 AllowedInterfaces interfaces; 115 AllowedInterfaces interfaces;
156 interfaces.insert("*"); 116 interfaces.insert("*");
157 if (originator) 117 if (!params->originator_identity().is_null())
158 interfaces = originator->GetAllowedInterfaces(identity_); 118 interfaces = GetAllowedInterfaces(params->originator_filter(), identity_);
159 application_->AcceptConnection(requestor_url.spec(), 119
160 services.Pass(), 120 application_->AcceptConnection(
161 exposed_services.Pass(), 121 params->originator_identity().url.spec(), params->TakeServices(),
162 Array<String>::From(interfaces).Pass(), 122 params->TakeExposedServices(), Array<String>::From(interfaces).Pass(),
163 requested_url.spec()); 123 params->app_url().spec());
164 } 124 }
165 125
166 void ApplicationInstance::OnConnectionError() { 126 void ApplicationInstance::OnConnectionError() {
167 std::vector<QueuedClientRequest*> queued_client_requests; 127 std::vector<ConnectToApplicationParams*> queued_client_requests;
168 queued_client_requests_.swap(queued_client_requests); 128 queued_client_requests_.swap(queued_client_requests);
169 auto manager = manager_; 129 auto manager = manager_;
170 manager_->OnApplicationInstanceError(this); 130 manager_->OnApplicationInstanceError(this);
171 //|this| is deleted. 131 //|this| is deleted.
172 132
173 // If any queued requests came to shell during time it was shutting down, 133 // If any queued requests came to shell during time it was shutting down,
174 // start them now. 134 // start them now.
175 for (auto request : queued_client_requests) { 135 for (auto request : queued_client_requests) {
176 mojo::URLRequestPtr url(mojo::URLRequest::New()); 136 // Unfortunately, it is possible that |request->original_request| is null at
177 url->url = mojo::String::From(request->requested_url.spec()); 137 // this point. Consider the following sequence:
178 ApplicationInstance* originator = 138 // 1) connect_request_1 arrives at the application manager; the manager
179 manager->GetApplicationInstance(originator_identity_); 139 // decides to fetch the app.
180 manager->ConnectToApplication( 140 // 2) connect_request_2 arrives for the same app; because the app is not
181 originator, url.Pass(), std::string(), request->requestor_url, 141 // running yet, the manager decides to fetch the app again.
182 request->services.Pass(), request->exposed_services.Pass(), 142 // 3) The fetch for step (1) completes and an application instance app_a is
183 request->filter, base::Closure(), EmptyConnectCallback()); 143 // registered.
144 // 4) app_a goes into two-phase shutdown.
145 // 5) The fetch for step (2) completes; the manager finds that there is a
146 // running app already, so it connects to app_a.
147 // 6) connect_request_2 is queued (and eventually gets here), but its
148 // original_request field was already lost to NetworkFetcher at step (2).
149 //
150 // TODO(yzshen): It seems we should register a pending application instance
151 // before starting the fetch. So at step (2) the application manager knows
152 // that it can wait for the first fetch to complete instead of doing a
153 // second one directly.
Ben Goodger (Google) 2015/09/02 22:20:33 sgtm
154 if (!request->app_url_request()) {
155 URLRequestPtr url_request = mojo::URLRequest::New();
156 url_request->url = request->app_url().spec();
157 request->SetURLInfo(url_request.Pass());
158 }
159 manager->ConnectToApplication(make_scoped_ptr(request));
184 } 160 }
161
185 STLDeleteElements(&queued_client_requests); 162 STLDeleteElements(&queued_client_requests);
186 } 163 }
187 164
188 void ApplicationInstance::OnQuitRequestedResult(bool can_quit) { 165 void ApplicationInstance::OnQuitRequestedResult(bool can_quit) {
189 if (can_quit) 166 if (can_quit)
190 return; 167 return;
191 168
192 queue_requests_ = false; 169 queue_requests_ = false;
193 for (auto request : queued_client_requests_) { 170 for (auto request : queued_client_requests_)
194 CallAcceptConnection( 171 CallAcceptConnection(make_scoped_ptr(request));
195 request->originator, request->requestor_url, request->services.Pass(), 172
196 request->exposed_services.Pass(), request->requested_url);
197 }
198 STLDeleteElements(&queued_client_requests_); 173 STLDeleteElements(&queued_client_requests_);
sky 2015/09/02 22:38:26 Shouldn't you remove this line now since the call
yzshen1 2015/09/03 00:06:39 Wow... good catch++.
199 } 174 }
200 175
201 } // namespace shell 176 } // namespace shell
202 } // namespace mojo 177 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698