service_connector.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "chromecast/browser/service_connector.h"
  5. #include "base/bind.h"
  6. #include "base/logging.h"
  7. #include "chromecast/browser/system_connector.h"
  8. #include "chromecast/common/mojom/constants.mojom.h"
  9. #include "chromecast/common/mojom/multiroom.mojom.h"
  10. #include "content/public/browser/browser_task_traits.h"
  11. #include "content/public/browser/browser_thread.h"
  12. namespace chromecast {
  13. namespace {
  14. ServiceConnector* g_instance = nullptr;
  15. } // namespace
  16. const ServiceConnectorClientId kBrowserProcessClientId =
  17. ServiceConnectorClientId::FromUnsafeValue(1);
  18. const ServiceConnectorClientId kMediaServiceClientId =
  19. ServiceConnectorClientId::FromUnsafeValue(2);
  20. ServiceConnector::ServiceConnector() {
  21. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  22. DCHECK(!g_instance);
  23. g_instance = this;
  24. }
  25. ServiceConnector::~ServiceConnector() {
  26. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  27. DCHECK_EQ(this, g_instance);
  28. g_instance = nullptr;
  29. }
  30. // static
  31. mojo::PendingRemote<mojom::ServiceConnector> ServiceConnector::MakeRemote(
  32. ServiceConnectorClientId client_id) {
  33. DCHECK(g_instance);
  34. mojo::PendingRemote<mojom::ServiceConnector> remote;
  35. BindReceiver(client_id, remote.InitWithNewPipeAndPassReceiver());
  36. return remote;
  37. }
  38. // static
  39. void ServiceConnector::BindReceiver(
  40. ServiceConnectorClientId client_id,
  41. mojo::PendingReceiver<mojom::ServiceConnector> receiver) {
  42. if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
  43. content::GetUIThreadTaskRunner({})->PostTask(
  44. FROM_HERE, base::BindOnce(&ServiceConnector::BindReceiver, client_id,
  45. std::move(receiver)));
  46. return;
  47. }
  48. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  49. DCHECK(g_instance);
  50. g_instance->receivers_.Add(g_instance, std::move(receiver), client_id);
  51. }
  52. void ServiceConnector::Connect(const std::string& service_name,
  53. mojo::GenericPendingReceiver receiver) {
  54. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  55. const ServiceConnectorClientId client_id = receivers_.current_context();
  56. // If the client is browser code, forward indscriminately through the Service
  57. // Manager. The browser generally has access unfettered to everything.
  58. if (client_id == kBrowserProcessClientId) {
  59. auto interface_name = *receiver.interface_name();
  60. GetSystemConnector()->BindInterface(
  61. service_manager::ServiceFilter::ByName(service_name), interface_name,
  62. receiver.PassPipe());
  63. return;
  64. }
  65. // In the public implementation of this class, the only other client we
  66. // support is the Media Service, binding to the MultiroomManager interface in
  67. // the Chromecast service.
  68. if (client_id != kMediaServiceClientId ||
  69. service_name != mojom::kChromecastServiceName) {
  70. LOG(ERROR) << "Client " << client_id.GetUnsafeValue()
  71. << " attempted to bind " << *receiver.interface_name()
  72. << " in inaccessible service " << service_name;
  73. return;
  74. }
  75. if (auto r = receiver.As<mojom::MultiroomManager>()) {
  76. GetSystemConnector()->BindInterface(service_name, std::move(r));
  77. return;
  78. }
  79. LOG(ERROR) << "Media Service attempted to bind inaccessible interface "
  80. << *receiver.interface_name() << " in \"chromecast\" service.";
  81. }
  82. } // namespace chromecast