Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <utility> | 6 #include <utility> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "mojo/public/cpp/bindings/interface_ptr.h" | 11 #include "mojo/public/cpp/bindings/interface_ptr.h" |
| 12 #include "mojo/shell/public/cpp/connector.h" | 12 #include "mojo/shell/public/cpp/connector.h" |
| 13 #include "mojo/shell/public/cpp/lib/connection_impl.h" | 13 #include "mojo/shell/public/cpp/lib/connection_impl.h" |
| 14 #include "mojo/shell/public/cpp/lib/connector_impl.h" | 14 #include "mojo/shell/public/cpp/lib/connector_impl.h" |
| 15 #include "mojo/shell/public/cpp/shell_client.h" | 15 #include "mojo/shell/public/cpp/shell_client.h" |
| 16 #include "mojo/shell/public/cpp/shell_connection.h" | 16 #include "mojo/shell/public/cpp/shell_connection.h" |
| 17 | 17 |
| 18 namespace mojo { | 18 namespace mojo { |
| 19 | 19 |
| 20 namespace { | |
| 21 | |
| 22 void DefaultTerminationClosure() { | |
| 23 if (base::MessageLoop::current() && | |
| 24 base::MessageLoop::current()->is_running()) | |
| 25 base::MessageLoop::current()->QuitWhenIdle(); | |
| 26 } | |
| 27 | |
| 28 } // namespace | |
| 29 | |
| 30 class AppRefCountImpl : public AppRefCount { | 20 class AppRefCountImpl : public AppRefCount { |
| 31 public: | 21 public: |
| 32 AppRefCountImpl(ShellConnection* connection, | 22 AppRefCountImpl(ShellConnection* connection, |
| 33 scoped_refptr<base::SingleThreadTaskRunner> app_task_runner) | 23 scoped_refptr<base::SingleThreadTaskRunner> app_task_runner) |
| 34 : connection_(connection), | 24 : connection_(connection), |
| 35 app_task_runner_(app_task_runner) {} | 25 app_task_runner_(app_task_runner) {} |
| 36 ~AppRefCountImpl() override { | 26 ~AppRefCountImpl() override { |
| 37 #ifndef NDEBUG | 27 #ifndef NDEBUG |
| 38 // Ensure that this object is used on only one thread at a time, or else | 28 // Ensure that this object is used on only one thread at a time, or else |
| 39 // there could be races where the object is being reset on one thread and | 29 // there could be races where the object is being reset on one thread and |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 | 75 |
| 86 DISALLOW_COPY_AND_ASSIGN(AppRefCountImpl); | 76 DISALLOW_COPY_AND_ASSIGN(AppRefCountImpl); |
| 87 }; | 77 }; |
| 88 | 78 |
| 89 //////////////////////////////////////////////////////////////////////////////// | 79 //////////////////////////////////////////////////////////////////////////////// |
| 90 // ShellConnection, public: | 80 // ShellConnection, public: |
| 91 | 81 |
| 92 ShellConnection::ShellConnection( | 82 ShellConnection::ShellConnection( |
| 93 mojo::ShellClient* client, | 83 mojo::ShellClient* client, |
| 94 InterfaceRequest<shell::mojom::ShellClient> request) | 84 InterfaceRequest<shell::mojom::ShellClient> request) |
| 95 : ShellConnection(client, | |
| 96 std::move(request), | |
| 97 base::Bind(&DefaultTerminationClosure)) {} | |
| 98 | |
| 99 ShellConnection::ShellConnection( | |
| 100 mojo::ShellClient* client, | |
| 101 InterfaceRequest<shell::mojom::ShellClient> request, | |
| 102 const Closure& termination_closure) | |
| 103 : client_(client), | 85 : client_(client), |
| 104 binding_(this, std::move(request)), | 86 binding_(this, std::move(request)), |
| 105 termination_closure_(termination_closure), | |
| 106 quit_requested_(false), | |
| 107 ref_count_(0), | 87 ref_count_(0), |
| 108 weak_factory_(this) {} | 88 weak_factory_(this) {} |
| 109 | 89 |
| 110 ShellConnection::~ShellConnection() {} | 90 ShellConnection::~ShellConnection() {} |
| 111 | 91 |
| 112 void ShellConnection::WaitForInitialize() { | 92 void ShellConnection::WaitForInitialize() { |
| 113 DCHECK(!shell_.is_bound()); | 93 DCHECK(!connector_); |
| 114 binding_.WaitForIncomingMethodCall(); | 94 binding_.WaitForIncomingMethodCall(); |
| 115 } | 95 } |
| 116 | 96 |
| 117 //////////////////////////////////////////////////////////////////////////////// | 97 //////////////////////////////////////////////////////////////////////////////// |
| 118 // ShellConnection, Shell implementation: | 98 // ShellConnection, Shell implementation: |
| 119 | 99 |
| 120 scoped_ptr<Connection> ShellConnection::Connect(const std::string& url) { | 100 scoped_ptr<Connection> ShellConnection::Connect(const std::string& url) { |
| 121 return connector_->Connect(url); | 101 return connector_->Connect(url); |
| 122 } | 102 } |
| 123 | 103 |
| 124 scoped_ptr<Connection> ShellConnection::Connect( | 104 scoped_ptr<Connection> ShellConnection::Connect( |
| 125 Connector::ConnectParams* params) { | 105 Connector::ConnectParams* params) { |
| 126 return connector_->Connect(params); | 106 return connector_->Connect(params); |
| 127 } | 107 } |
| 128 | 108 |
| 129 scoped_ptr<Connector> ShellConnection::CloneConnector() const { | 109 scoped_ptr<Connector> ShellConnection::CloneConnector() const { |
| 130 return connector_->Clone(); | 110 return connector_->Clone(); |
| 131 } | 111 } |
| 132 | 112 |
| 133 void ShellConnection::Quit() { | |
| 134 // We can't quit immediately, since there could be in-flight requests from the | |
| 135 // shell. So check with it first. | |
| 136 if (shell_) { | |
| 137 quit_requested_ = true; | |
| 138 shell_->QuitApplication(); | |
| 139 } else { | |
| 140 QuitNow(); | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 scoped_ptr<AppRefCount> ShellConnection::CreateAppRefCount() { | 113 scoped_ptr<AppRefCount> ShellConnection::CreateAppRefCount() { |
| 145 AddRef(); | 114 AddRef(); |
| 146 return make_scoped_ptr( | 115 return make_scoped_ptr( |
| 147 new AppRefCountImpl(this, base::MessageLoop::current()->task_runner())); | 116 new AppRefCountImpl(this, base::MessageLoop::current()->task_runner())); |
| 148 } | 117 } |
| 149 | 118 |
| 119 void ShellConnection::Quit() { | |
| 120 client_->Quit(); | |
| 121 if (base::MessageLoop::current() && | |
|
sky
2016/02/25 17:13:10
ick!
| |
| 122 base::MessageLoop::current()->is_running()) { | |
| 123 base::MessageLoop::current()->QuitWhenIdle(); | |
| 124 } | |
| 125 } | |
| 126 | |
| 150 //////////////////////////////////////////////////////////////////////////////// | 127 //////////////////////////////////////////////////////////////////////////////// |
| 151 // ShellConnection, shell::mojom::ShellClient implementation: | 128 // ShellConnection, shell::mojom::ShellClient implementation: |
| 152 | 129 |
| 153 void ShellConnection::Initialize(shell::mojom::ShellPtr shell, | 130 void ShellConnection::Initialize(shell::mojom::ConnectorPtr connector, |
| 154 const mojo::String& url, | 131 const mojo::String& url, |
| 155 uint32_t id, | 132 uint32_t id, |
| 156 uint32_t user_id) { | 133 uint32_t user_id) { |
| 157 shell_ = std::move(shell); | 134 connector_.reset(new ConnectorImpl( |
| 158 shell_.set_connection_error_handler([this]() { OnConnectionError(); }); | 135 std::move(connector), |
| 159 | 136 base::Bind(&ShellConnection::OnConnectionError, |
| 160 shell::mojom::ConnectorPtr connector; | 137 weak_factory_.GetWeakPtr()))); |
| 161 shell_->GetConnector(GetProxy(&connector)); | |
| 162 connector_.reset(new ConnectorImpl(connector.PassInterface())); | |
| 163 | |
| 164 client_->Initialize(this, url, id, user_id); | 138 client_->Initialize(this, url, id, user_id); |
| 165 } | 139 } |
| 166 | 140 |
| 167 void ShellConnection::AcceptConnection( | 141 void ShellConnection::AcceptConnection( |
| 168 const String& requestor_url, | 142 const String& requestor_url, |
| 169 uint32_t requestor_id, | 143 uint32_t requestor_id, |
| 170 uint32_t requestor_user_id, | 144 uint32_t requestor_user_id, |
| 171 shell::mojom::InterfaceProviderRequest local_interfaces, | 145 shell::mojom::InterfaceProviderRequest local_interfaces, |
| 172 shell::mojom::InterfaceProviderPtr remote_interfaces, | 146 shell::mojom::InterfaceProviderPtr remote_interfaces, |
| 173 Array<String> allowed_interfaces, | 147 Array<String> allowed_interfaces, |
| 174 const String& url) { | 148 const String& url) { |
| 175 scoped_ptr<Connection> registry(new internal::ConnectionImpl( | 149 scoped_ptr<Connection> registry(new internal::ConnectionImpl( |
| 176 url, requestor_url, requestor_id, requestor_user_id, | 150 url, requestor_url, requestor_id, requestor_user_id, |
| 177 std::move(remote_interfaces), std::move(local_interfaces), | 151 std::move(remote_interfaces), std::move(local_interfaces), |
| 178 allowed_interfaces.To<std::set<std::string>>())); | 152 allowed_interfaces.To<std::set<std::string>>())); |
| 179 if (!client_->AcceptConnection(registry.get())) | 153 if (!client_->AcceptConnection(registry.get())) |
| 180 return; | 154 return; |
| 181 | 155 |
| 182 // If we were quitting because we thought there were no more interfaces for | 156 // TODO(beng): it appears we never prune this list. We should, when the |
| 183 // this app in use, then that has changed so cancel the quit request. | 157 // connection's remote service provider pipe breaks. |
| 184 if (quit_requested_) | |
| 185 quit_requested_ = false; | |
| 186 | |
| 187 incoming_connections_.push_back(std::move(registry)); | 158 incoming_connections_.push_back(std::move(registry)); |
| 188 } | 159 } |
| 189 | 160 |
| 190 void ShellConnection::OnQuitRequested(const Callback<void(bool)>& callback) { | |
| 191 // If by the time we got the reply from the shell, more requests had come in | |
| 192 // then we don't want to quit the app anymore so we return false. Otherwise | |
| 193 // |quit_requested_| is true so we tell the shell to proceed with the quit. | |
| 194 callback.Run(quit_requested_); | |
| 195 if (quit_requested_) | |
| 196 QuitNow(); | |
| 197 } | |
| 198 | |
| 199 //////////////////////////////////////////////////////////////////////////////// | 161 //////////////////////////////////////////////////////////////////////////////// |
| 200 // ShellConnection, private: | 162 // ShellConnection, private: |
| 201 | 163 |
| 202 void ShellConnection::OnConnectionError() { | 164 void ShellConnection::OnConnectionError() { |
| 203 base::WeakPtr<ShellConnection> ptr(weak_factory_.GetWeakPtr()); | 165 base::WeakPtr<ShellConnection> ptr(weak_factory_.GetWeakPtr()); |
| 204 | 166 |
| 205 // We give the client notice first, since it might want to do something on | 167 // We give the client notice first, since it might want to do something on |
| 206 // shell connection errors other than immediate termination of the run | 168 // shell connection errors other than immediate termination of the run |
| 207 // loop. The application might want to continue servicing connections other | 169 // loop. The application might want to continue servicing connections other |
| 208 // than the one to the shell. | 170 // than the one to the shell. |
| 209 bool quit_now = client_->ShellConnectionLost(); | 171 bool quit_now = client_->ShellConnectionLost(); |
| 210 if (quit_now) | 172 if (quit_now) |
| 211 QuitNow(); | 173 Quit(); |
| 212 if (!ptr) | 174 if (!ptr) |
| 213 return; | 175 return; |
| 214 shell_ = nullptr; | 176 connector_.reset(); |
| 215 } | |
| 216 | |
| 217 void ShellConnection::QuitNow() { | |
| 218 client_->Quit(); | |
| 219 termination_closure_.Run(); | |
| 220 } | |
| 221 | |
| 222 void ShellConnection::UnbindConnections( | |
| 223 InterfaceRequest<shell::mojom::ShellClient>* request, | |
| 224 shell::mojom::ShellPtr* shell) { | |
| 225 *request = binding_.Unbind(); | |
| 226 shell->Bind(shell_.PassInterface()); | |
| 227 } | 177 } |
| 228 | 178 |
| 229 void ShellConnection::AddRef() { | 179 void ShellConnection::AddRef() { |
| 230 ++ref_count_; | 180 ++ref_count_; |
| 231 } | 181 } |
| 232 | 182 |
| 233 void ShellConnection::Release() { | 183 void ShellConnection::Release() { |
| 234 if (!--ref_count_) | 184 if (!--ref_count_) |
| 235 Quit(); | 185 Quit(); |
| 236 } | 186 } |
| 237 | 187 |
| 238 } // namespace mojo | 188 } // namespace mojo |
| OLD | NEW |