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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/atomic_sequence_num.h" | 11 #include "base/atomic_sequence_num.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "mojo/common/common_type_converters.h" | 14 #include "mojo/common/common_type_converters.h" |
15 #include "mojo/common/url_type_converters.h" | 15 #include "mojo/common/url_type_converters.h" |
16 #include "mojo/shell/application_manager.h" | 16 #include "mojo/shell/application_manager.h" |
17 #include "mojo/shell/public/interfaces/content_handler.mojom.h" | 17 #include "mojo/shell/public/interfaces/content_handler.mojom.h" |
18 | 18 |
19 namespace mojo { | 19 namespace mojo { |
20 namespace shell { | 20 namespace shell { |
21 namespace { | |
22 | |
23 base::StaticAtomicSequenceNumber g_instance_id; | |
24 | |
25 const int kInvalidInstanceId = -1; | |
26 | |
27 } // namespace | |
28 | 21 |
29 ApplicationInstance::ApplicationInstance( | 22 ApplicationInstance::ApplicationInstance( |
30 ApplicationPtr application, | 23 ApplicationPtr application, |
31 ApplicationManager* manager, | 24 ApplicationManager* manager, |
32 const Identity& identity, | 25 const Identity& identity, |
33 uint32_t requesting_content_handler_id, | 26 uint32_t requesting_content_handler_id, |
34 const base::Closure& on_application_end) | 27 const base::Closure& on_application_end) |
35 : manager_(manager), | 28 : manager_(manager), |
36 id_(GenerateUniqueID()), | 29 id_(GenerateUniqueID()), |
37 identity_(identity), | 30 identity_(identity), |
38 allow_any_application_(identity.filter().size() == 1 && | 31 allow_any_application_(identity.filter().size() == 1 && |
39 identity.filter().count("*") == 1), | 32 identity.filter().count("*") == 1), |
40 requesting_content_handler_id_(requesting_content_handler_id), | 33 requesting_content_handler_id_(requesting_content_handler_id), |
41 on_application_end_(on_application_end), | 34 on_application_end_(on_application_end), |
42 application_(std::move(application)), | 35 application_(std::move(application)), |
43 binding_(this), | 36 binding_(this), |
44 pid_receiver_binding_(this), | 37 pid_receiver_binding_(this), |
45 queue_requests_(false), | 38 queue_requests_(false), |
46 native_runner_(nullptr), | 39 native_runner_(nullptr), |
47 pid_(base::kNullProcessId) {} | 40 pid_(base::kNullProcessId) { |
| 41 DCHECK_NE(Shell::kInvalidApplicationID, id_); |
| 42 } |
48 | 43 |
49 ApplicationInstance::~ApplicationInstance() { | 44 ApplicationInstance::~ApplicationInstance() { |
50 for (auto request : queued_client_requests_) | 45 for (auto request : queued_client_requests_) { |
51 request->connect_callback().Run(kInvalidContentHandlerID); | 46 request->connect_callback().Run(kInvalidApplicationID, |
| 47 kInvalidApplicationID); |
| 48 } |
52 STLDeleteElements(&queued_client_requests_); | 49 STLDeleteElements(&queued_client_requests_); |
53 } | 50 } |
54 | 51 |
55 void ApplicationInstance::InitializeApplication() { | 52 void ApplicationInstance::InitializeApplication() { |
56 application_->Initialize(binding_.CreateInterfacePtrAndBind(), | 53 application_->Initialize(binding_.CreateInterfacePtrAndBind(), |
57 identity_.url().spec()); | 54 identity_.url().spec(), id_); |
58 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); | 55 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); |
59 } | 56 } |
60 | 57 |
61 void ApplicationInstance::ConnectToClient( | 58 void ApplicationInstance::ConnectToClient( |
62 scoped_ptr<ConnectToApplicationParams> params) { | 59 scoped_ptr<ConnectToApplicationParams> params) { |
63 if (queue_requests_) { | 60 if (queue_requests_) { |
64 queued_client_requests_.push_back(params.release()); | 61 queued_client_requests_.push_back(params.release()); |
65 return; | 62 return; |
66 } | 63 } |
67 | 64 |
(...skipping 13 matching lines...) Expand all Loading... |
81 void ApplicationInstance::ConnectToApplication( | 78 void ApplicationInstance::ConnectToApplication( |
82 URLRequestPtr app_request, | 79 URLRequestPtr app_request, |
83 InterfaceRequest<ServiceProvider> services, | 80 InterfaceRequest<ServiceProvider> services, |
84 ServiceProviderPtr exposed_services, | 81 ServiceProviderPtr exposed_services, |
85 CapabilityFilterPtr filter, | 82 CapabilityFilterPtr filter, |
86 const ConnectToApplicationCallback& callback) { | 83 const ConnectToApplicationCallback& callback) { |
87 std::string url_string = app_request->url.To<std::string>(); | 84 std::string url_string = app_request->url.To<std::string>(); |
88 GURL url(url_string); | 85 GURL url(url_string); |
89 if (!url.is_valid()) { | 86 if (!url.is_valid()) { |
90 LOG(ERROR) << "Error: invalid URL: " << url_string; | 87 LOG(ERROR) << "Error: invalid URL: " << url_string; |
91 callback.Run(kInvalidContentHandlerID); | 88 callback.Run(kInvalidApplicationID, kInvalidApplicationID); |
92 return; | 89 return; |
93 } | 90 } |
94 if (allow_any_application_ || | 91 if (allow_any_application_ || |
95 identity_.filter().find(url.spec()) != identity_.filter().end()) { | 92 identity_.filter().find(url.spec()) != identity_.filter().end()) { |
96 CapabilityFilter capability_filter = GetPermissiveCapabilityFilter(); | 93 CapabilityFilter capability_filter = GetPermissiveCapabilityFilter(); |
97 if (!filter.is_null()) | 94 if (!filter.is_null()) |
98 capability_filter = filter->filter.To<CapabilityFilter>(); | 95 capability_filter = filter->filter.To<CapabilityFilter>(); |
99 | 96 |
100 scoped_ptr<ConnectToApplicationParams> params( | 97 scoped_ptr<ConnectToApplicationParams> params( |
101 new ConnectToApplicationParams); | 98 new ConnectToApplicationParams); |
102 params->SetSource(this); | 99 params->SetSource(this); |
103 GURL app_url(app_request->url.get()); | 100 GURL app_url(app_request->url.get()); |
104 params->SetTargetURLRequest( | 101 params->SetTargetURLRequest( |
105 std::move(app_request), | 102 std::move(app_request), |
106 Identity(app_url, std::string(), capability_filter)); | 103 Identity(app_url, std::string(), capability_filter)); |
107 params->set_services(std::move(services)); | 104 params->set_services(std::move(services)); |
108 params->set_exposed_services(std::move(exposed_services)); | 105 params->set_exposed_services(std::move(exposed_services)); |
109 params->set_connect_callback(callback); | 106 params->set_connect_callback(callback); |
110 manager_->ConnectToApplication(std::move(params)); | 107 manager_->ConnectToApplication(std::move(params)); |
111 } else { | 108 } else { |
112 LOG(WARNING) << "CapabilityFilter prevented connection from: " << | 109 LOG(WARNING) << "CapabilityFilter prevented connection from: " << |
113 identity_.url() << " to: " << url.spec(); | 110 identity_.url() << " to: " << url.spec(); |
114 callback.Run(kInvalidContentHandlerID); | 111 callback.Run(kInvalidApplicationID, kInvalidApplicationID); |
115 } | 112 } |
116 } | 113 } |
117 | 114 |
118 void ApplicationInstance::QuitApplication() { | 115 void ApplicationInstance::QuitApplication() { |
119 queue_requests_ = true; | 116 queue_requests_ = true; |
120 application_->OnQuitRequested( | 117 application_->OnQuitRequested( |
121 base::Bind(&ApplicationInstance::OnQuitRequestedResult, | 118 base::Bind(&ApplicationInstance::OnQuitRequestedResult, |
122 base::Unretained(this))); | 119 base::Unretained(this))); |
123 } | 120 } |
124 | 121 |
125 void ApplicationInstance::SetPID(uint32_t pid) { | 122 void ApplicationInstance::SetPID(uint32_t pid) { |
126 // This will call us back to update pid_. | 123 // This will call us back to update pid_. |
127 manager_->ApplicationPIDAvailable(id_, pid); | 124 manager_->ApplicationPIDAvailable(id_, pid); |
128 } | 125 } |
129 | 126 |
130 // static | 127 uint32_t ApplicationInstance::GenerateUniqueID() const { |
131 int ApplicationInstance::GenerateUniqueID() { | 128 static uint32_t id = Shell::kInvalidApplicationID; |
132 int id = g_instance_id.GetNext() + 1; | 129 ++id; |
133 CHECK_NE(0, id); | 130 CHECK_NE(Shell::kInvalidApplicationID, id); |
134 CHECK_NE(kInvalidInstanceId, id); | |
135 return id; | 131 return id; |
136 } | 132 } |
137 | 133 |
138 void ApplicationInstance::CallAcceptConnection( | 134 void ApplicationInstance::CallAcceptConnection( |
139 scoped_ptr<ConnectToApplicationParams> params) { | 135 scoped_ptr<ConnectToApplicationParams> params) { |
140 params->connect_callback().Run(requesting_content_handler_id_); | 136 params->connect_callback().Run(id_, requesting_content_handler_id_); |
141 AllowedInterfaces interfaces; | 137 AllowedInterfaces interfaces; |
142 interfaces.insert("*"); | 138 interfaces.insert("*"); |
143 if (!params->source().is_null()) | 139 if (!params->source().is_null()) |
144 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); | 140 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); |
145 | 141 |
| 142 ApplicationInstance* source = |
| 143 manager_->GetApplicationInstance(params->source()); |
| 144 uint32_t source_id = source ? source->id() : Shell::kInvalidApplicationID; |
146 application_->AcceptConnection( | 145 application_->AcceptConnection( |
147 params->source().url().spec(), params->TakeServices(), | 146 params->source().url().spec(), source_id, params->TakeServices(), |
148 params->TakeExposedServices(), Array<String>::From(interfaces), | 147 params->TakeExposedServices(), Array<String>::From(interfaces), |
149 params->target().url().spec()); | 148 params->target().url().spec()); |
150 } | 149 } |
151 | 150 |
152 void ApplicationInstance::OnConnectionError() { | 151 void ApplicationInstance::OnConnectionError() { |
153 std::vector<ConnectToApplicationParams*> queued_client_requests; | 152 std::vector<ConnectToApplicationParams*> queued_client_requests; |
154 queued_client_requests_.swap(queued_client_requests); | 153 queued_client_requests_.swap(queued_client_requests); |
155 auto manager = manager_; | 154 auto manager = manager_; |
156 manager_->OnApplicationInstanceError(this); | 155 manager_->OnApplicationInstanceError(this); |
157 //|this| is deleted. | 156 //|this| is deleted. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 191 |
193 queue_requests_ = false; | 192 queue_requests_ = false; |
194 for (auto request : queued_client_requests_) | 193 for (auto request : queued_client_requests_) |
195 CallAcceptConnection(make_scoped_ptr(request)); | 194 CallAcceptConnection(make_scoped_ptr(request)); |
196 | 195 |
197 queued_client_requests_.clear(); | 196 queued_client_requests_.clear(); |
198 } | 197 } |
199 | 198 |
200 } // namespace shell | 199 } // namespace shell |
201 } // namespace mojo | 200 } // namespace mojo |
OLD | NEW |