| 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> | |
| 6 #include <utility> | |
| 7 | |
| 8 #include "base/bind.h" | 5 #include "base/bind.h" |
| 9 #include "base/logging.h" | 6 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 11 #include "mojo/public/cpp/bindings/interface_ptr.h" | 8 #include "mojo/public/cpp/bindings/interface_ptr.h" |
| 12 #include "mojo/shell/public/cpp/connector.h" | 9 #include "mojo/shell/public/cpp/connector.h" |
| 13 #include "mojo/shell/public/cpp/lib/connection_impl.h" | 10 #include "mojo/shell/public/cpp/lib/connection_impl.h" |
| 14 #include "mojo/shell/public/cpp/lib/connector_impl.h" | 11 #include "mojo/shell/public/cpp/lib/connector_impl.h" |
| 15 #include "mojo/shell/public/cpp/shell_client.h" | 12 #include "mojo/shell/public/cpp/shell_client.h" |
| 16 #include "mojo/shell/public/cpp/shell_connection.h" | 13 #include "mojo/shell/public/cpp/shell_connection.h" |
| 17 | 14 |
| 18 namespace mojo { | 15 namespace mojo { |
| 19 | 16 |
| 20 class AppRefCountImpl : public AppRefCount { | |
| 21 public: | |
| 22 AppRefCountImpl(ShellConnection* connection, | |
| 23 scoped_refptr<base::SingleThreadTaskRunner> app_task_runner) | |
| 24 : connection_(connection), | |
| 25 app_task_runner_(app_task_runner) {} | |
| 26 ~AppRefCountImpl() override { | |
| 27 #ifndef NDEBUG | |
| 28 // Ensure that this object is used on only one thread at a time, or else | |
| 29 // there could be races where the object is being reset on one thread and | |
| 30 // cloned on another. | |
| 31 if (clone_task_runner_) | |
| 32 DCHECK(clone_task_runner_->BelongsToCurrentThread()); | |
| 33 #endif | |
| 34 | |
| 35 if (app_task_runner_->BelongsToCurrentThread()) { | |
| 36 connection_->Release(); | |
| 37 } else { | |
| 38 app_task_runner_->PostTask( | |
| 39 FROM_HERE, | |
| 40 base::Bind(&ShellConnection::Release, base::Unretained(connection_))); | |
| 41 } | |
| 42 } | |
| 43 | |
| 44 private: | |
| 45 // AppRefCount: | |
| 46 scoped_ptr<AppRefCount> Clone() override { | |
| 47 if (app_task_runner_->BelongsToCurrentThread()) { | |
| 48 connection_->AddRef(); | |
| 49 } else { | |
| 50 app_task_runner_->PostTask( | |
| 51 FROM_HERE, | |
| 52 base::Bind(&ShellConnection::AddRef, base::Unretained(connection_))); | |
| 53 } | |
| 54 | |
| 55 #ifndef NDEBUG | |
| 56 // Ensure that this object is used on only one thread at a time, or else | |
| 57 // there could be races where the object is being reset on one thread and | |
| 58 // cloned on another. | |
| 59 if (clone_task_runner_) { | |
| 60 DCHECK(clone_task_runner_->BelongsToCurrentThread()); | |
| 61 } else { | |
| 62 clone_task_runner_ = base::MessageLoop::current()->task_runner(); | |
| 63 } | |
| 64 #endif | |
| 65 | |
| 66 return make_scoped_ptr(new AppRefCountImpl(connection_, app_task_runner_)); | |
| 67 } | |
| 68 | |
| 69 ShellConnection* connection_; | |
| 70 scoped_refptr<base::SingleThreadTaskRunner> app_task_runner_; | |
| 71 | |
| 72 #ifndef NDEBUG | |
| 73 scoped_refptr<base::SingleThreadTaskRunner> clone_task_runner_; | |
| 74 #endif | |
| 75 | |
| 76 DISALLOW_COPY_AND_ASSIGN(AppRefCountImpl); | |
| 77 }; | |
| 78 | |
| 79 //////////////////////////////////////////////////////////////////////////////// | 17 //////////////////////////////////////////////////////////////////////////////// |
| 80 // ShellConnection, public: | 18 // ShellConnection, public: |
| 81 | 19 |
| 82 ShellConnection::ShellConnection( | 20 ShellConnection::ShellConnection( |
| 83 mojo::ShellClient* client, | 21 mojo::ShellClient* client, |
| 84 InterfaceRequest<shell::mojom::ShellClient> request) | 22 InterfaceRequest<shell::mojom::ShellClient> request) |
| 85 : client_(client), | 23 : client_(client), |
| 86 binding_(this, std::move(request)), | 24 binding_(this, std::move(request)), |
| 87 ref_count_(0), | |
| 88 weak_factory_(this) {} | 25 weak_factory_(this) {} |
| 89 | 26 |
| 90 ShellConnection::~ShellConnection() {} | 27 ShellConnection::~ShellConnection() {} |
| 91 | 28 |
| 92 void ShellConnection::WaitForInitialize() { | 29 void ShellConnection::WaitForInitialize() { |
| 93 DCHECK(!connector_); | 30 DCHECK(!connector_); |
| 94 binding_.WaitForIncomingMethodCall(); | 31 binding_.WaitForIncomingMethodCall(); |
| 95 } | 32 } |
| 96 | 33 |
| 97 //////////////////////////////////////////////////////////////////////////////// | 34 //////////////////////////////////////////////////////////////////////////////// |
| 98 // ShellConnection, Shell implementation: | |
| 99 | |
| 100 scoped_ptr<Connection> ShellConnection::Connect(const std::string& url) { | |
| 101 return connector_->Connect(url); | |
| 102 } | |
| 103 | |
| 104 scoped_ptr<Connection> ShellConnection::Connect( | |
| 105 Connector::ConnectParams* params) { | |
| 106 return connector_->Connect(params); | |
| 107 } | |
| 108 | |
| 109 scoped_ptr<Connector> ShellConnection::CloneConnector() const { | |
| 110 return connector_->Clone(); | |
| 111 } | |
| 112 | |
| 113 scoped_ptr<AppRefCount> ShellConnection::CreateAppRefCount() { | |
| 114 AddRef(); | |
| 115 return make_scoped_ptr( | |
| 116 new AppRefCountImpl(this, base::MessageLoop::current()->task_runner())); | |
| 117 } | |
| 118 | |
| 119 void ShellConnection::Quit() { | |
| 120 client_->Quit(); | |
| 121 if (base::MessageLoop::current() && | |
| 122 base::MessageLoop::current()->is_running()) { | |
| 123 base::MessageLoop::current()->QuitWhenIdle(); | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 //////////////////////////////////////////////////////////////////////////////// | |
| 128 // ShellConnection, shell::mojom::ShellClient implementation: | 35 // ShellConnection, shell::mojom::ShellClient implementation: |
| 129 | 36 |
| 130 void ShellConnection::Initialize(shell::mojom::ConnectorPtr connector, | 37 void ShellConnection::Initialize(shell::mojom::ConnectorPtr connector, |
| 131 const mojo::String& url, | 38 const mojo::String& url, |
| 132 uint32_t id, | 39 uint32_t id, |
| 133 uint32_t user_id) { | 40 uint32_t user_id) { |
| 134 connector_.reset(new ConnectorImpl( | 41 connector_.reset(new ConnectorImpl( |
| 135 std::move(connector), | 42 std::move(connector), |
| 136 base::Bind(&ShellConnection::OnConnectionError, | 43 base::Bind(&ShellConnection::OnConnectionError, |
| 137 weak_factory_.GetWeakPtr()))); | 44 weak_factory_.GetWeakPtr()))); |
| 138 client_->Initialize(this, url, id, user_id); | 45 client_->Initialize(connector_.get(), url, id, user_id); |
| 139 } | 46 } |
| 140 | 47 |
| 141 void ShellConnection::AcceptConnection( | 48 void ShellConnection::AcceptConnection( |
| 142 const String& requestor_url, | 49 const String& requestor_url, |
| 143 uint32_t requestor_id, | 50 uint32_t requestor_id, |
| 144 uint32_t requestor_user_id, | 51 uint32_t requestor_user_id, |
| 145 shell::mojom::InterfaceProviderRequest local_interfaces, | 52 shell::mojom::InterfaceProviderRequest local_interfaces, |
| 146 shell::mojom::InterfaceProviderPtr remote_interfaces, | 53 shell::mojom::InterfaceProviderPtr remote_interfaces, |
| 147 Array<String> allowed_interfaces, | 54 Array<String> allowed_interfaces, |
| 148 const String& url) { | 55 const String& url) { |
| 149 scoped_ptr<Connection> registry(new internal::ConnectionImpl( | 56 scoped_ptr<Connection> registry(new internal::ConnectionImpl( |
| 150 url, requestor_url, requestor_id, requestor_user_id, | 57 url, requestor_url, requestor_id, requestor_user_id, |
| 151 std::move(remote_interfaces), std::move(local_interfaces), | 58 std::move(remote_interfaces), std::move(local_interfaces), |
| 152 allowed_interfaces.To<std::set<std::string>>())); | 59 allowed_interfaces.To<std::set<std::string>>())); |
| 153 if (!client_->AcceptConnection(registry.get())) | 60 if (!client_->AcceptConnection(registry.get())) |
| 154 return; | 61 return; |
| 155 | 62 |
| 156 // TODO(beng): it appears we never prune this list. We should, when the | 63 // TODO(beng): it appears we never prune this list. We should, when the |
| 157 // connection's remote service provider pipe breaks. | 64 // connection's remote service provider pipe breaks. |
| 158 incoming_connections_.push_back(std::move(registry)); | 65 incoming_connections_.push_back(std::move(registry)); |
| 159 } | 66 } |
| 160 | 67 |
| 161 //////////////////////////////////////////////////////////////////////////////// | 68 //////////////////////////////////////////////////////////////////////////////// |
| 162 // ShellConnection, private: | 69 // ShellConnection, private: |
| 163 | 70 |
| 164 void ShellConnection::OnConnectionError() { | 71 void ShellConnection::OnConnectionError() { |
| 165 base::WeakPtr<ShellConnection> ptr(weak_factory_.GetWeakPtr()); | |
| 166 | |
| 167 // We give the client notice first, since it might want to do something on | 72 // We give the client notice first, since it might want to do something on |
| 168 // shell connection errors other than immediate termination of the run | 73 // shell connection errors other than immediate termination of the run |
| 169 // loop. The application might want to continue servicing connections other | 74 // loop. The application might want to continue servicing connections other |
| 170 // than the one to the shell. | 75 // than the one to the shell. |
| 171 bool quit_now = client_->ShellConnectionLost(); | 76 if (client_->ShellConnectionLost()) |
| 172 if (quit_now) | 77 connector_.reset(); |
| 173 Quit(); | |
| 174 if (!ptr) | |
| 175 return; | |
| 176 connector_.reset(); | |
| 177 } | |
| 178 | |
| 179 void ShellConnection::AddRef() { | |
| 180 ++ref_count_; | |
| 181 } | |
| 182 | |
| 183 void ShellConnection::Release() { | |
| 184 if (!--ref_count_) | |
| 185 Quit(); | |
| 186 } | 78 } |
| 187 | 79 |
| 188 } // namespace mojo | 80 } // namespace mojo |
| OLD | NEW |