Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc

Issue 2973983002: Revert of [Media Router] Add CastMediaSinkService (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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
5 #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/common/media_router/discovery/media_sink_internal.h"
10 #include "components/cast_channel/cast_socket_service.h"
11 #include "components/cast_channel/cast_socket_service_factory.h"
12 #include "components/net_log/chrome_net_log.h"
13 #include "content/public/common/content_client.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/ip_address.h"
16
17 namespace {
18
19 constexpr char kObserverId[] = "browser_observer_id";
20
21 enum ErrorType {
22 NONE,
23 NOT_CAST_DEVICE,
24 MISSING_ID,
25 MISSING_FRIENDLY_NAME,
26 MISSING_OR_INVALID_IP_ADDRESS,
27 MISSING_OR_INVALID_PORT,
28 };
29
30 ErrorType CreateCastMediaSink(const media_router::DnsSdService& service,
31 int channel_id,
32 bool audio_only,
33 media_router::MediaSinkInternal* cast_sink) {
34 DCHECK(cast_sink);
35 if (service.service_name.find(
36 media_router::CastMediaSinkService::kCastServiceType) ==
37 std::string::npos)
38 return ErrorType::NOT_CAST_DEVICE;
39
40 net::IPAddress ip_address;
41 if (!ip_address.AssignFromIPLiteral(service.ip_address))
42 return ErrorType::MISSING_OR_INVALID_IP_ADDRESS;
43
44 std::map<std::string, std::string> service_data;
45 for (const auto& item : service.service_data) {
46 // |item| format should be "id=xxxxxx", etc.
47 size_t split_idx = item.find('=');
48 if (split_idx == std::string::npos)
49 continue;
50
51 std::string key = item.substr(0, split_idx);
52 std::string val =
53 split_idx < item.length() ? item.substr(split_idx + 1) : "";
54 service_data[key] = val;
55 }
56
57 // When use this "sink" within browser, please note it will have a different
58 // ID when it is sent to the extension, because it derives a different sink ID
59 // using the given sink ID.
60 std::string unique_id = service_data["id"];
61 if (unique_id.empty())
62 return ErrorType::MISSING_ID;
63 std::string friendly_name = service_data["fn"];
64 if (friendly_name.empty())
65 return ErrorType::MISSING_FRIENDLY_NAME;
66 media_router::MediaSink sink(unique_id, friendly_name,
67 media_router::MediaSink::IconType::CAST);
68
69 media_router::CastSinkExtraData extra_data;
70 extra_data.ip_address = ip_address;
71 extra_data.model_name = service_data["md"];
72 extra_data.capabilities = cast_channel::CastDeviceCapability::AUDIO_OUT;
73 if (!audio_only)
74 extra_data.capabilities |= cast_channel::CastDeviceCapability::VIDEO_OUT;
75 extra_data.cast_channel_id = channel_id;
76
77 cast_sink->set_sink(sink);
78 cast_sink->set_cast_data(extra_data);
79
80 return ErrorType::NONE;
81 }
82
83 } // namespace
84
85 namespace media_router {
86
87 // static
88 const char CastMediaSinkService::kCastServiceType[] = "_googlecast._tcp.local";
89
90 CastMediaSinkService::CastMediaSinkService(
91 const OnSinksDiscoveredCallback& callback,
92 content::BrowserContext* browser_context)
93 : MediaSinkServiceBase(callback) {
94 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
95 cast_socket_service_ = cast_channel::CastSocketServiceFactory::GetInstance()
96 ->GetForBrowserContext(browser_context);
97 DCHECK(cast_socket_service_);
98 }
99
100 CastMediaSinkService::CastMediaSinkService(
101 const OnSinksDiscoveredCallback& callback,
102 cast_channel::CastSocketService* cast_socket_service)
103 : MediaSinkServiceBase(callback),
104 cast_socket_service_(cast_socket_service) {
105 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
106 DCHECK(cast_socket_service_);
107 }
108
109 CastMediaSinkService::~CastMediaSinkService() {}
110
111 void CastMediaSinkService::Start() {
112 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
113 if (dns_sd_registry_)
114 return;
115
116 dns_sd_registry_ = DnsSdRegistry::GetInstance();
117 dns_sd_registry_->AddObserver(this);
118 dns_sd_registry_->RegisterDnsSdListener(kCastServiceType);
119 MediaSinkServiceBase::StartTimer();
120 }
121
122 void CastMediaSinkService::Stop() {
123 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
124 if (!dns_sd_registry_)
125 return;
126
127 dns_sd_registry_->UnregisterDnsSdListener(kCastServiceType);
128 dns_sd_registry_->RemoveObserver(this);
129 dns_sd_registry_ = nullptr;
130 MediaSinkServiceBase::StopTimer();
131 }
132
133 void CastMediaSinkService::SetDnsSdRegistryForTest(DnsSdRegistry* registry) {
134 DCHECK(!dns_sd_registry_);
135 dns_sd_registry_ = registry;
136 dns_sd_registry_->AddObserver(this);
137 dns_sd_registry_->RegisterDnsSdListener(kCastServiceType);
138 MediaSinkServiceBase::StartTimer();
139 }
140
141 void CastMediaSinkService::OnDnsSdEvent(
142 const std::string& service_type,
143 const DnsSdRegistry::DnsSdServiceList& services) {
144 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
145 DVLOG(2) << "CastMediaSinkService::OnDnsSdEvent found " << services.size()
146 << " services";
147
148 current_sinks_.clear();
149 current_services_ = services;
150
151 for (const auto& service : services) {
152 net::IPAddress ip_address;
153 if (!ip_address.AssignFromIPLiteral(service.ip_address)) {
154 DVLOG(2) << "Invalid ip_addresss: " << service.ip_address;
155 continue;
156 }
157 net::HostPortPair host_port_pair =
158 net::HostPortPair::FromString(service.service_host_port);
159
160 content::BrowserThread::PostTask(
161 content::BrowserThread::IO, FROM_HERE,
162 base::Bind(&CastMediaSinkService::OpenChannelOnIOThread, this, service,
163 net::IPEndPoint(ip_address, host_port_pair.port())));
164 }
165
166 MediaSinkServiceBase::RestartTimer();
167 }
168
169 void CastMediaSinkService::OpenChannelOnIOThread(
170 const DnsSdService& service,
171 const net::IPEndPoint& ip_endpoint) {
172 auto* observer = cast_socket_service_->GetObserver(kObserverId);
173 if (!observer) {
174 observer = new CastSocketObserver();
175 cast_socket_service_->AddObserver(kObserverId, base::WrapUnique(observer));
176 }
177
178 cast_socket_service_->OpenSocket(
179 ip_endpoint, g_browser_process->net_log(),
180 base::Bind(&CastMediaSinkService::OnChannelOpenedOnIOThread, this,
181 service),
182 observer);
183 }
184
185 void CastMediaSinkService::OnChannelOpenedOnIOThread(
186 const DnsSdService& service,
187 int channel_id,
188 cast_channel::ChannelError channel_error) {
189 if (channel_error != cast_channel::ChannelError::NONE) {
190 DVLOG(2) << "Fail to open channel " << service.ip_address << ": "
191 << service.service_host_port
192 << " [ChannelError]: " << (int)channel_error;
193 return;
194 }
195
196 auto* socket = cast_socket_service_->GetSocket(channel_id);
197 if (!socket) {
198 DVLOG(2) << "Fail to find socket with [channel_id]: " << channel_id;
199 return;
200 }
201
202 content::BrowserThread::PostTask(
203 content::BrowserThread::UI, FROM_HERE,
204 base::Bind(&CastMediaSinkService::OnChannelOpenedOnUIThread, this,
205 service, channel_id, socket->audio_only()));
206 }
207
208 void CastMediaSinkService::OnChannelOpenedOnUIThread(
209 const DnsSdService& service,
210 int channel_id,
211 bool audio_only) {
212 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
213 MediaSinkInternal sink;
214 ErrorType error = CreateCastMediaSink(service, channel_id, audio_only, &sink);
215 if (error != ErrorType::NONE) {
216 DVLOG(2) << "Fail to create Cast device [error]: " << error;
217 return;
218 }
219
220 if (!base::ContainsValue(current_services_, service)) {
221 DVLOG(2) << "Service data not found in current service data list...";
222 return;
223 }
224
225 DVLOG(2) << "Ading sink to current_sinks_ [id]: " << sink.sink().id();
226 current_sinks_.insert(sink);
227 MediaSinkServiceBase::RestartTimer();
228 }
229
230 CastMediaSinkService::CastSocketObserver::CastSocketObserver() {}
231 CastMediaSinkService::CastSocketObserver::~CastSocketObserver() {}
232
233 void CastMediaSinkService::CastSocketObserver::OnError(
234 const cast_channel::CastSocket& socket,
235 cast_channel::ChannelError error_state) {
236 DVLOG(1) << "OnError [ip_endpoint]: " << socket.ip_endpoint().ToString()
237 << " [error_state]: "
238 << cast_channel::ChannelErrorToString(error_state);
239 }
240
241 void CastMediaSinkService::CastSocketObserver::OnMessage(
242 const cast_channel::CastSocket& socket,
243 const cast_channel::CastMessage& message) {}
244
245 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698