| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromecast/browser/service_connector.h" |
| |
| #include "base/functional/bind.h" |
| #include "base/logging.h" |
| #include "chromecast/browser/system_connector.h" |
| #include "content/public/browser/browser_task_traits.h" |
| #include "content/public/browser/browser_thread.h" |
| |
| namespace chromecast { |
| |
| namespace { |
| |
| ServiceConnector* g_instance = nullptr; |
| |
| } // namespace |
| |
| const ServiceConnectorClientId kBrowserProcessClientId = |
| ServiceConnectorClientId::FromUnsafeValue(1); |
| |
| const ServiceConnectorClientId kMediaServiceClientId = |
| ServiceConnectorClientId::FromUnsafeValue(2); |
| |
| ServiceConnector::ServiceConnector() { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| DCHECK(!g_instance); |
| g_instance = this; |
| } |
| |
| ServiceConnector::~ServiceConnector() { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| DCHECK_EQ(this, g_instance); |
| g_instance = nullptr; |
| } |
| |
| // static |
| mojo::PendingRemote<mojom::ServiceConnector> ServiceConnector::MakeRemote( |
| ServiceConnectorClientId client_id) { |
| DCHECK(g_instance); |
| mojo::PendingRemote<mojom::ServiceConnector> remote; |
| BindReceiver(client_id, remote.InitWithNewPipeAndPassReceiver()); |
| return remote; |
| } |
| |
| // static |
| void ServiceConnector::BindReceiver( |
| ServiceConnectorClientId client_id, |
| mojo::PendingReceiver<mojom::ServiceConnector> receiver) { |
| if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { |
| content::GetUIThreadTaskRunner({})->PostTask( |
| FROM_HERE, base::BindOnce(&ServiceConnector::BindReceiver, client_id, |
| std::move(receiver))); |
| return; |
| } |
| |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| DCHECK(g_instance); |
| g_instance->receivers_.Add(g_instance, std::move(receiver), client_id); |
| } |
| |
| void ServiceConnector::Connect(const std::string& service_name, |
| mojo::GenericPendingReceiver receiver) { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| |
| const ServiceConnectorClientId client_id = receivers_.current_context(); |
| |
| // If the client is browser code, forward indscriminately through the Service |
| // Manager. The browser generally has access unfettered to everything. |
| if (client_id == kBrowserProcessClientId) { |
| auto interface_name = *receiver.interface_name(); |
| GetSystemConnector()->BindInterface( |
| service_manager::ServiceFilter::ByName(service_name), interface_name, |
| receiver.PassPipe()); |
| return; |
| } |
| |
| LOG(ERROR) << "Client " << client_id.GetUnsafeValue() << " attempted to bind " |
| << *receiver.interface_name() << " in inaccessible service " |
| << service_name; |
| } |
| |
| } // namespace chromecast |