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 ShellPtr shell; | 53 ShellPtr shell; |
57 binding_.Bind(GetProxy(&shell)); | 54 binding_.Bind(GetProxy(&shell)); |
58 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); | 55 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); |
59 application_->Initialize(std::move(shell), identity_.url().spec()); | 56 application_->Initialize(std::move(shell), identity_.url().spec(), id_); |
60 } | 57 } |
61 | 58 |
62 void ApplicationInstance::ConnectToClient( | 59 void ApplicationInstance::ConnectToClient( |
63 scoped_ptr<ConnectToApplicationParams> params) { | 60 scoped_ptr<ConnectToApplicationParams> params) { |
64 if (queue_requests_) { | 61 if (queue_requests_) { |
65 queued_client_requests_.push_back(params.release()); | 62 queued_client_requests_.push_back(params.release()); |
66 return; | 63 return; |
67 } | 64 } |
68 | 65 |
69 CallAcceptConnection(std::move(params)); | 66 CallAcceptConnection(std::move(params)); |
(...skipping 12 matching lines...) Expand all Loading... |
82 void ApplicationInstance::ConnectToApplication( | 79 void ApplicationInstance::ConnectToApplication( |
83 URLRequestPtr app_request, | 80 URLRequestPtr app_request, |
84 InterfaceRequest<ServiceProvider> services, | 81 InterfaceRequest<ServiceProvider> services, |
85 ServiceProviderPtr exposed_services, | 82 ServiceProviderPtr exposed_services, |
86 CapabilityFilterPtr filter, | 83 CapabilityFilterPtr filter, |
87 const ConnectToApplicationCallback& callback) { | 84 const ConnectToApplicationCallback& callback) { |
88 std::string url_string = app_request->url.To<std::string>(); | 85 std::string url_string = app_request->url.To<std::string>(); |
89 GURL url(url_string); | 86 GURL url(url_string); |
90 if (!url.is_valid()) { | 87 if (!url.is_valid()) { |
91 LOG(ERROR) << "Error: invalid URL: " << url_string; | 88 LOG(ERROR) << "Error: invalid URL: " << url_string; |
92 callback.Run(kInvalidContentHandlerID); | 89 callback.Run(kInvalidApplicationID, kInvalidApplicationID); |
93 return; | 90 return; |
94 } | 91 } |
95 if (allow_any_application_ || | 92 if (allow_any_application_ || |
96 identity_.filter().find(url.spec()) != identity_.filter().end()) { | 93 identity_.filter().find(url.spec()) != identity_.filter().end()) { |
97 CapabilityFilter capability_filter = GetPermissiveCapabilityFilter(); | 94 CapabilityFilter capability_filter = GetPermissiveCapabilityFilter(); |
98 if (!filter.is_null()) | 95 if (!filter.is_null()) |
99 capability_filter = filter->filter.To<CapabilityFilter>(); | 96 capability_filter = filter->filter.To<CapabilityFilter>(); |
100 | 97 |
101 scoped_ptr<ConnectToApplicationParams> params( | 98 scoped_ptr<ConnectToApplicationParams> params( |
102 new ConnectToApplicationParams); | 99 new ConnectToApplicationParams); |
103 params->SetSource(this); | 100 params->SetSource(this); |
104 GURL app_url(app_request->url); | 101 GURL app_url(app_request->url); |
105 params->SetTargetURLRequest( | 102 params->SetTargetURLRequest( |
106 std::move(app_request), | 103 std::move(app_request), |
107 Identity(app_url, std::string(), capability_filter)); | 104 Identity(app_url, std::string(), capability_filter)); |
108 params->set_services(std::move(services)); | 105 params->set_services(std::move(services)); |
109 params->set_exposed_services(std::move(exposed_services)); | 106 params->set_exposed_services(std::move(exposed_services)); |
110 params->set_connect_callback(callback); | 107 params->set_connect_callback(callback); |
111 manager_->ConnectToApplication(std::move(params)); | 108 manager_->ConnectToApplication(std::move(params)); |
112 } else { | 109 } else { |
113 LOG(WARNING) << "CapabilityFilter prevented connection from: " << | 110 LOG(WARNING) << "CapabilityFilter prevented connection from: " << |
114 identity_.url() << " to: " << url.spec(); | 111 identity_.url() << " to: " << url.spec(); |
115 callback.Run(kInvalidContentHandlerID); | 112 callback.Run(kInvalidApplicationID, kInvalidApplicationID); |
116 } | 113 } |
117 } | 114 } |
118 | 115 |
119 void ApplicationInstance::QuitApplication() { | 116 void ApplicationInstance::QuitApplication() { |
120 queue_requests_ = true; | 117 queue_requests_ = true; |
121 application_->OnQuitRequested( | 118 application_->OnQuitRequested( |
122 base::Bind(&ApplicationInstance::OnQuitRequestedResult, | 119 base::Bind(&ApplicationInstance::OnQuitRequestedResult, |
123 base::Unretained(this))); | 120 base::Unretained(this))); |
124 } | 121 } |
125 | 122 |
126 void ApplicationInstance::SetPID(uint32_t pid) { | 123 void ApplicationInstance::SetPID(uint32_t pid) { |
127 // This will call us back to update pid_. | 124 // This will call us back to update pid_. |
128 manager_->ApplicationPIDAvailable(id_, pid); | 125 manager_->ApplicationPIDAvailable(id_, pid); |
129 } | 126 } |
130 | 127 |
131 // static | 128 uint32_t ApplicationInstance::GenerateUniqueID() const { |
132 int ApplicationInstance::GenerateUniqueID() { | 129 static uint32_t id = Shell::kInvalidApplicationID; |
133 int id = g_instance_id.GetNext() + 1; | 130 ++id; |
134 CHECK_NE(0, id); | 131 CHECK_NE(Shell::kInvalidApplicationID, id); |
135 CHECK_NE(kInvalidInstanceId, id); | |
136 return id; | 132 return id; |
137 } | 133 } |
138 | 134 |
139 void ApplicationInstance::CallAcceptConnection( | 135 void ApplicationInstance::CallAcceptConnection( |
140 scoped_ptr<ConnectToApplicationParams> params) { | 136 scoped_ptr<ConnectToApplicationParams> params) { |
141 params->connect_callback().Run(requesting_content_handler_id_); | 137 params->connect_callback().Run(id_, requesting_content_handler_id_); |
142 AllowedInterfaces interfaces; | 138 AllowedInterfaces interfaces; |
143 interfaces.insert("*"); | 139 interfaces.insert("*"); |
144 if (!params->source().is_null()) | 140 if (!params->source().is_null()) |
145 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); | 141 interfaces = GetAllowedInterfaces(params->source().filter(), identity_); |
146 | 142 |
| 143 ApplicationInstance* source = |
| 144 manager_->GetApplicationInstance(params->source()); |
| 145 uint32_t source_id = source ? source->id() : Shell::kInvalidApplicationID; |
147 application_->AcceptConnection( | 146 application_->AcceptConnection( |
148 params->source().url().spec(), params->TakeServices(), | 147 params->source().url().spec(), source_id, params->TakeServices(), |
149 params->TakeExposedServices(), Array<String>::From(interfaces), | 148 params->TakeExposedServices(), Array<String>::From(interfaces), |
150 params->target().url().spec()); | 149 params->target().url().spec()); |
151 } | 150 } |
152 | 151 |
153 void ApplicationInstance::OnConnectionError() { | 152 void ApplicationInstance::OnConnectionError() { |
154 std::vector<ConnectToApplicationParams*> queued_client_requests; | 153 std::vector<ConnectToApplicationParams*> queued_client_requests; |
155 queued_client_requests_.swap(queued_client_requests); | 154 queued_client_requests_.swap(queued_client_requests); |
156 auto manager = manager_; | 155 auto manager = manager_; |
157 manager_->OnApplicationInstanceError(this); | 156 manager_->OnApplicationInstanceError(this); |
158 //|this| is deleted. | 157 //|this| is deleted. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 | 192 |
194 queue_requests_ = false; | 193 queue_requests_ = false; |
195 for (auto request : queued_client_requests_) | 194 for (auto request : queued_client_requests_) |
196 CallAcceptConnection(make_scoped_ptr(request)); | 195 CallAcceptConnection(make_scoped_ptr(request)); |
197 | 196 |
198 queued_client_requests_.clear(); | 197 queued_client_requests_.clear(); |
199 } | 198 } |
200 | 199 |
201 } // namespace shell | 200 } // namespace shell |
202 } // namespace mojo | 201 } // namespace mojo |
OLD | NEW |