• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "libcef/browser/media_router/media_sink_impl.h"
6 
7 #include "libcef/browser/thread_util.h"
8 
9 #include "base/strings/string_number_conversions.h"
10 #include "chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h"
11 #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h"
12 #include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h"
13 #include "components/media_router/common/discovery/media_sink_internal.h"
14 #include "components/media_router/common/discovery/media_sink_service_base.h"
15 
16 namespace {
17 
18 using SinkServiceVector = std::vector<media_router::MediaSinkServiceBase*>;
19 
GetSinkServices()20 SinkServiceVector GetSinkServices() {
21   CEF_REQUIRE_UIT();
22   auto sink_service = media_router::DualMediaSinkService::GetInstance();
23   return {sink_service->GetCastMediaSinkServiceImpl(),
24           sink_service->GetDialMediaSinkServiceImpl()};
25 }
26 
GetSinkInternalAndContinue(SinkServiceVector services,const media_router::MediaSink::Id & sink_id,CefRefPtr<CefMediaSinkDeviceInfoCallback> callback)27 void GetSinkInternalAndContinue(
28     SinkServiceVector services,
29     const media_router::MediaSink::Id& sink_id,
30     CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
31   CEF_REQUIRE_IOT();
32 
33   CefMediaSinkDeviceInfo device_info;
34   const media_router::MediaSinkInternal* sink_internal = nullptr;
35 
36   for (auto service : services) {
37     sink_internal = service->GetSinkById(sink_id);
38     if (sink_internal)
39       break;
40   }
41 
42   if (sink_internal) {
43     if (sink_internal->is_cast_sink()) {
44       const auto& cast_data = sink_internal->cast_data();
45       CefString(&device_info.ip_address) =
46           cast_data.ip_endpoint.ToStringWithoutPort();
47       device_info.port = cast_data.ip_endpoint.port();
48       CefString(&device_info.model_name) = cast_data.model_name;
49     } else if (sink_internal->is_dial_sink()) {
50       const auto& dial_data = sink_internal->dial_data();
51       CefString(&device_info.ip_address) = dial_data.ip_address.ToString();
52       if (dial_data.app_url.is_valid() && dial_data.app_url.has_port()) {
53         base::StringToInt(dial_data.app_url.port_piece(), &device_info.port);
54       }
55       CefString(&device_info.model_name) = dial_data.model_name;
56     }
57   }
58 
59   // Execute the callback on the UI thread.
60   CEF_POST_TASK(
61       CEF_UIT,
62       base::BindOnce(&CefMediaSinkDeviceInfoCallback::OnMediaSinkDeviceInfo,
63                      callback, device_info));
64 }
65 
GetDeviceInfo(const media_router::MediaSink::Id & sink_id,CefRefPtr<CefMediaSinkDeviceInfoCallback> callback)66 void GetDeviceInfo(const media_router::MediaSink::Id& sink_id,
67                    CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
68   auto next_step = base::BindOnce(
69       [](const media_router::MediaSink::Id& sink_id,
70          CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
71         CEF_POST_TASK(CEF_IOT,
72                       base::BindOnce(GetSinkInternalAndContinue,
73                                      GetSinkServices(), sink_id, callback));
74       },
75       sink_id, callback);
76 
77   if (CEF_CURRENTLY_ON(CEF_UIT)) {
78     std::move(next_step).Run();
79   } else {
80     CEF_POST_TASK(CEF_UIT, std::move(next_step));
81   }
82 }
83 
84 }  // namespace
85 
CefMediaSinkImpl(const media_router::MediaSink & sink)86 CefMediaSinkImpl::CefMediaSinkImpl(const media_router::MediaSink& sink)
87     : sink_(sink) {}
88 
CefMediaSinkImpl(const media_router::MediaSink::Id & sink_id,const std::string & sink_name,media_router::mojom::MediaRouteProviderId provider_id)89 CefMediaSinkImpl::CefMediaSinkImpl(
90     const media_router::MediaSink::Id& sink_id,
91     const std::string& sink_name,
92     media_router::mojom::MediaRouteProviderId provider_id)
93     : sink_(sink_id,
94             sink_name,
95             media_router::SinkIconType::GENERIC,
96             provider_id) {}
97 
GetId()98 CefString CefMediaSinkImpl::GetId() {
99   return sink_.id();
100 }
101 
GetName()102 CefString CefMediaSinkImpl::GetName() {
103   return sink_.name();
104 }
105 
GetDescription()106 CefString CefMediaSinkImpl::GetDescription() {
107   return sink_.description().value_or("");
108 }
109 
GetIconType()110 CefMediaSink::IconType CefMediaSinkImpl::GetIconType() {
111   // Verify that our enum matches Chromium's values.
112   static_assert(static_cast<int>(CEF_MSIT_TOTAL_COUNT) ==
113                     static_cast<int>(media_router::SinkIconType::TOTAL_COUNT),
114                 "enum mismatch");
115 
116   return static_cast<CefMediaSink::IconType>(sink_.icon_type());
117 }
118 
GetDeviceInfo(CefRefPtr<CefMediaSinkDeviceInfoCallback> callback)119 void CefMediaSinkImpl::GetDeviceInfo(
120     CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
121   ::GetDeviceInfo(sink_.id(), callback);
122 }
123 
IsCastSink()124 bool CefMediaSinkImpl::IsCastSink() {
125   return sink_.provider_id() == media_router::mojom::MediaRouteProviderId::CAST;
126 }
127 
IsDialSink()128 bool CefMediaSinkImpl::IsDialSink() {
129   return sink_.provider_id() == media_router::mojom::MediaRouteProviderId::DIAL;
130 }
131 
IsCompatibleWith(CefRefPtr<CefMediaSource> source)132 bool CefMediaSinkImpl::IsCompatibleWith(CefRefPtr<CefMediaSource> source) {
133   if (source) {
134     if (IsCastSink())
135       return source->IsCastSource();
136     if (IsDialSink())
137       return source->IsDialSource();
138   }
139   return false;
140 }
141