Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chrome/browser/ui/ash/cast_config_delegate_media_router.h" | 5 #include "chrome/browser/ui/ash/cast_config_client_media_router.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | |
| 8 #include <vector> | 9 #include <vector> |
| 9 | 10 |
| 10 #include "base/macros.h" | 11 #include "base/macros.h" |
| 11 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 13 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
| 14 #include "chrome/browser/media/router/media_router.h" | 15 #include "chrome/browser/media/router/media_router.h" |
| 15 #include "chrome/browser/media/router/media_router_factory.h" | 16 #include "chrome/browser/media/router/media_router_factory.h" |
| 16 #include "chrome/browser/media/router/media_router_feature.h" | 17 #include "chrome/browser/media/router/media_router_feature.h" |
| 17 #include "chrome/browser/media/router/media_routes_observer.h" | 18 #include "chrome/browser/media/router/media_routes_observer.h" |
| 18 #include "chrome/browser/media/router/media_sinks_observer.h" | 19 #include "chrome/browser/media/router/media_sinks_observer.h" |
| 19 #include "chrome/browser/media/router/media_source_helper.h" | 20 #include "chrome/browser/media/router/media_source_helper.h" |
| 20 #include "chrome/browser/profiles/profile_manager.h" | 21 #include "chrome/browser/profiles/profile_manager.h" |
| 22 #include "chrome/browser/ui/ash/ash_util.h" | |
| 21 #include "chrome/common/url_constants.h" | 23 #include "chrome/common/url_constants.h" |
| 22 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 23 #include "content/public/browser/notification_source.h" | 25 #include "content/public/browser/notification_source.h" |
| 26 #include "content/public/common/service_manager_connection.h" | |
| 27 #include "content/public/common/service_names.mojom.h" | |
| 28 #include "services/service_manager/public/cpp/connector.h" | |
| 24 | 29 |
| 25 namespace { | 30 namespace { |
| 26 | 31 |
| 27 media_router::MediaRouter* media_router_for_test_ = nullptr; | 32 media_router::MediaRouter* media_router_for_test_ = nullptr; |
| 28 | 33 |
| 29 // Returns the MediaRouter instance for the current primary profile. | 34 // Returns the MediaRouter instance for the current primary profile. |
| 30 media_router::MediaRouter* GetMediaRouter() { | 35 media_router::MediaRouter* GetMediaRouter() { |
| 31 if (media_router_for_test_) | 36 if (media_router_for_test_) |
| 32 return media_router_for_test_; | 37 return media_router_for_test_; |
| 33 | 38 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 51 // This class caches the values that the observers give us so we can query them | 56 // This class caches the values that the observers give us so we can query them |
| 52 // at any point in time. It also emits a device refresh event when new data is | 57 // at any point in time. It also emits a device refresh event when new data is |
| 53 // available. | 58 // available. |
| 54 class CastDeviceCache : public media_router::MediaRoutesObserver, | 59 class CastDeviceCache : public media_router::MediaRoutesObserver, |
| 55 public media_router::MediaSinksObserver { | 60 public media_router::MediaSinksObserver { |
| 56 public: | 61 public: |
| 57 using MediaSinks = std::vector<media_router::MediaSink>; | 62 using MediaSinks = std::vector<media_router::MediaSink>; |
| 58 using MediaRoutes = std::vector<media_router::MediaRoute>; | 63 using MediaRoutes = std::vector<media_router::MediaRoute>; |
| 59 using MediaRouteIds = std::vector<media_router::MediaRoute::Id>; | 64 using MediaRouteIds = std::vector<media_router::MediaRoute::Id>; |
| 60 | 65 |
| 61 explicit CastDeviceCache(ash::CastConfigDelegate* cast_config_delegate); | 66 explicit CastDeviceCache(ash::mojom::CastConfigClient* cast_config_client); |
| 62 ~CastDeviceCache() override; | 67 ~CastDeviceCache() override; |
| 63 | 68 |
| 64 // This may call cast_config_delegate->RequestDeviceRefresh() before | 69 // This may call cast_config_client->RequestDeviceRefresh() before |
| 65 // returning. | 70 // returning. |
| 66 void Init(); | 71 void Init(); |
| 67 | 72 |
| 68 const MediaSinks& sinks() const { return sinks_; } | 73 const MediaSinks& sinks() const { return sinks_; } |
| 69 const MediaRoutes& routes() const { return routes_; } | 74 const MediaRoutes& routes() const { return routes_; } |
| 70 | 75 |
| 71 private: | 76 private: |
| 72 // media_router::MediaSinksObserver: | 77 // media_router::MediaSinksObserver: |
| 73 void OnSinksReceived(const MediaSinks& sinks) override; | 78 void OnSinksReceived(const MediaSinks& sinks) override; |
| 74 | 79 |
| 75 // media_router::MediaRoutesObserver: | 80 // media_router::MediaRoutesObserver: |
| 76 void OnRoutesUpdated(const MediaRoutes& routes, | 81 void OnRoutesUpdated(const MediaRoutes& routes, |
| 77 const MediaRouteIds& unused_joinable_route_ids) override; | 82 const MediaRouteIds& unused_joinable_route_ids) override; |
| 78 | 83 |
| 79 MediaSinks sinks_; | 84 MediaSinks sinks_; |
| 80 MediaRoutes routes_; | 85 MediaRoutes routes_; |
| 81 | 86 |
| 82 // Not owned. | 87 // Not owned. |
| 83 ash::CastConfigDelegate* cast_config_delegate_; | 88 ash::mojom::CastConfigClient* cast_config_client_; |
| 84 | 89 |
| 85 DISALLOW_COPY_AND_ASSIGN(CastDeviceCache); | 90 DISALLOW_COPY_AND_ASSIGN(CastDeviceCache); |
| 86 }; | 91 }; |
| 87 | 92 |
| 88 CastDeviceCache::CastDeviceCache(ash::CastConfigDelegate* cast_config_delegate) | 93 CastDeviceCache::CastDeviceCache( |
| 94 ash::mojom::CastConfigClient* cast_config_client) | |
| 89 : MediaRoutesObserver(GetMediaRouter()), | 95 : MediaRoutesObserver(GetMediaRouter()), |
| 90 MediaSinksObserver(GetMediaRouter(), | 96 MediaSinksObserver(GetMediaRouter(), |
| 91 media_router::MediaSourceForDesktop(), | 97 media_router::MediaSourceForDesktop(), |
| 92 GURL(chrome::kChromeUIMediaRouterURL)), | 98 GURL(chrome::kChromeUIMediaRouterURL)), |
| 93 cast_config_delegate_(cast_config_delegate) {} | 99 cast_config_client_(cast_config_client) {} |
| 94 | 100 |
| 95 CastDeviceCache::~CastDeviceCache() {} | 101 CastDeviceCache::~CastDeviceCache() {} |
| 96 | 102 |
| 97 void CastDeviceCache::Init() { | 103 void CastDeviceCache::Init() { |
| 98 CHECK(MediaSinksObserver::Init()); | 104 CHECK(MediaSinksObserver::Init()); |
| 99 } | 105 } |
| 100 | 106 |
| 101 void CastDeviceCache::OnSinksReceived(const MediaSinks& sinks) { | 107 void CastDeviceCache::OnSinksReceived(const MediaSinks& sinks) { |
| 102 sinks_.clear(); | 108 sinks_.clear(); |
| 103 for (const media_router::MediaSink& sink : sinks) { | 109 for (const media_router::MediaSink& sink : sinks) { |
| 104 // The media router adds a MediaSink instance that doesn't have a name. Make | 110 // The media router adds a MediaSink instance that doesn't have a name. Make |
| 105 // sure to filter that sink out from the UI so it is not rendered, as it | 111 // sure to filter that sink out from the UI so it is not rendered, as it |
| 106 // will be a line that only has a icon with no apparent meaning. | 112 // will be a line that only has a icon with no apparent meaning. |
| 107 if (sink.name().empty()) | 113 if (sink.name().empty()) |
| 108 continue; | 114 continue; |
| 109 | 115 |
| 110 // Hide all sinks which have a domain (ie, castouts) to meet privacy | 116 // Hide all sinks which have a domain (ie, castouts) to meet privacy |
| 111 // requirements. This will be enabled once UI can display the domain. See | 117 // requirements. This will be enabled once UI can display the domain. See |
| 112 // crbug.com/624016. | 118 // crbug.com/624016. |
| 113 if (!sink.domain().empty()) | 119 if (!sink.domain().empty()) |
| 114 continue; | 120 continue; |
| 115 | 121 |
| 116 sinks_.push_back(sink); | 122 sinks_.push_back(sink); |
| 117 } | 123 } |
| 118 | 124 |
| 119 cast_config_delegate_->RequestDeviceRefresh(); | 125 cast_config_client_->RequestDeviceRefresh(); |
| 120 } | 126 } |
| 121 | 127 |
| 122 void CastDeviceCache::OnRoutesUpdated( | 128 void CastDeviceCache::OnRoutesUpdated( |
| 123 const MediaRoutes& routes, | 129 const MediaRoutes& routes, |
| 124 const MediaRouteIds& unused_joinable_route_ids) { | 130 const MediaRouteIds& unused_joinable_route_ids) { |
| 125 routes_ = routes; | 131 routes_ = routes; |
| 126 cast_config_delegate_->RequestDeviceRefresh(); | 132 cast_config_client_->RequestDeviceRefresh(); |
| 127 } | 133 } |
| 128 | 134 |
| 129 //////////////////////////////////////////////////////////////////////////////// | 135 //////////////////////////////////////////////////////////////////////////////// |
| 130 // CastConfigDelegateMediaRouter: | 136 // CastConfigClientMediaRouter: |
| 131 | 137 |
| 132 void CastConfigDelegateMediaRouter::SetMediaRouterForTest( | 138 void CastConfigClientMediaRouter::SetMediaRouterForTest( |
| 133 media_router::MediaRouter* media_router) { | 139 media_router::MediaRouter* media_router) { |
| 134 media_router_for_test_ = media_router; | 140 media_router_for_test_ = media_router; |
| 135 } | 141 } |
| 136 | 142 |
| 137 CastConfigDelegateMediaRouter::CastConfigDelegateMediaRouter() { | 143 CastConfigClientMediaRouter::CastConfigClientMediaRouter() : binding_(this) { |
| 138 // TODO(jdufault): This should use a callback interface once there is an | 144 // TODO(jdufault): This should use a callback interface once there is an |
| 139 // equivalent. See crbug.com/666005. | 145 // equivalent. See crbug.com/666005. |
| 140 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, | 146 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, |
| 141 content::NotificationService::AllSources()); | 147 content::NotificationService::AllSources()); |
| 148 | |
| 149 // When starting up, we need to connect to ash and set ourselves as the | |
| 150 // client. | |
| 151 service_manager::Connector* connector = | |
| 152 content::ServiceManagerConnection::GetForProcess()->GetConnector(); | |
| 153 // Connect to the SystemTray interface in ash. Under mash the SystemTray | |
|
James Cook
2016/12/02 04:15:52
nit: remove "SystemTray"
Elliot Glaysher
2016/12/02 19:23:11
Done.
| |
| 154 // interface is in the ash process. In classic ash we provide it to ourself. | |
| 155 if (chrome::IsRunningInMash()) { | |
| 156 connector->ConnectToInterface("ash", &cast_config_); | |
| 157 } else { | |
| 158 connector->ConnectToInterface(content::mojom::kBrowserServiceName, | |
| 159 &cast_config_); | |
| 160 } | |
| 161 | |
| 162 // Register this object as the client interface implementation. | |
| 163 ash::mojom::CastConfigClientAssociatedPtrInfo ptr_info; | |
| 164 binding_.Bind(&ptr_info, cast_config_.associated_group()); | |
| 165 cast_config_->SetClient(std::move(ptr_info)); | |
| 142 } | 166 } |
| 143 | 167 |
| 144 CastConfigDelegateMediaRouter::~CastConfigDelegateMediaRouter() {} | 168 CastConfigClientMediaRouter::~CastConfigClientMediaRouter() {} |
| 145 | 169 |
| 146 CastDeviceCache* CastConfigDelegateMediaRouter::devices() { | 170 void CastConfigClientMediaRouter::FlushForTesting() { |
| 171 binding_.FlushForTesting(); | |
| 172 } | |
| 173 | |
| 174 CastDeviceCache* CastConfigClientMediaRouter::devices() { | |
| 147 // The CastDeviceCache instance is lazily allocated because the MediaRouter | 175 // The CastDeviceCache instance is lazily allocated because the MediaRouter |
| 148 // component is not ready when the constructor is invoked. | 176 // component is not ready when the constructor is invoked. |
| 149 if (!devices_ && GetMediaRouter()) { | 177 if (!devices_ && GetMediaRouter()) { |
| 150 devices_ = base::MakeUnique<CastDeviceCache>(this); | 178 devices_ = base::MakeUnique<CastDeviceCache>(this); |
| 151 devices_->Init(); | 179 devices_->Init(); |
| 152 } | 180 } |
| 153 | 181 |
| 154 return devices_.get(); | 182 return devices_.get(); |
| 155 } | 183 } |
| 156 | 184 |
| 157 void CastConfigDelegateMediaRouter::RequestDeviceRefresh() { | 185 void CastConfigClientMediaRouter::RequestDeviceRefresh() { |
| 158 // The media router component isn't ready yet. | 186 // The media router component isn't ready yet. |
| 159 if (!devices()) | 187 if (!devices()) |
| 160 return; | 188 return; |
| 161 | 189 |
| 190 // We failed to connect to ash; don't crash in release. | |
| 191 if (!cast_config_) { | |
| 192 NOTREACHED(); | |
| 193 return; | |
| 194 } | |
| 195 | |
| 162 // Build the old-style SinkAndRoute set out of the MediaRouter | 196 // Build the old-style SinkAndRoute set out of the MediaRouter |
| 163 // source/sink/route setup. We first map the existing sinks, and then we | 197 // source/sink/route setup. We first map the existing sinks, and then we |
| 164 // update those sinks with activity information. | 198 // update those sinks with activity information. |
| 165 | 199 |
| 166 SinksAndRoutes items; | 200 std::vector<ash::mojom::SinkAndRoutePtr> items; |
| 167 | 201 |
| 168 for (const media_router::MediaSink& sink : devices()->sinks()) { | 202 for (const media_router::MediaSink& sink : devices()->sinks()) { |
| 169 SinkAndRoute sr; | 203 ash::mojom::SinkAndRoutePtr sr = ash::mojom::SinkAndRoute::New(); |
| 170 sr.sink.id = sink.id(); | 204 sr->route = ash::mojom::CastRoute::New(); |
| 171 sr.sink.name = base::UTF8ToUTF16(sink.name()); | 205 sr->sink = ash::mojom::CastSink::New(); |
| 172 sr.sink.domain = base::UTF8ToUTF16(sink.domain()); | 206 sr->sink->id = sink.id(); |
| 173 items.push_back(sr); | 207 sr->sink->name = sink.name(); |
| 208 sr->sink->domain = sink.domain(); | |
| 209 items.push_back(std::move(sr)); | |
| 174 } | 210 } |
| 175 | 211 |
| 176 for (const media_router::MediaRoute& route : devices()->routes()) { | 212 for (const media_router::MediaRoute& route : devices()->routes()) { |
| 177 if (!route.for_display()) | 213 if (!route.for_display()) |
| 178 continue; | 214 continue; |
| 179 | 215 |
| 180 for (SinkAndRoute& item : items) { | 216 for (ash::mojom::SinkAndRoutePtr& item : items) { |
| 181 if (item.sink.id == route.media_sink_id()) { | 217 if (item->sink->id == route.media_sink_id()) { |
| 182 item.route.id = route.media_route_id(); | 218 item->route->id = route.media_route_id(); |
| 183 item.route.title = | 219 item->route->title = StripEndingTab(route.description()); |
| 184 base::UTF8ToUTF16(StripEndingTab(route.description())); | 220 item->route->is_local_source = route.is_local(); |
| 185 item.route.is_local_source = route.is_local(); | |
| 186 | 221 |
| 187 // Default to a tab/app capture. This will display the media router | 222 // Default to a tab/app capture. This will display the media router |
| 188 // description. This means we will properly support DIAL casts. | 223 // description. This means we will properly support DIAL casts. |
| 189 item.route.content_source = Route::ContentSource::TAB; | 224 item->route->content_source = ash::mojom::ContentSource::TAB; |
| 190 if (media_router::IsDesktopMirroringMediaSource(route.media_source())) | 225 if (media_router::IsDesktopMirroringMediaSource(route.media_source())) |
| 191 item.route.content_source = Route::ContentSource::DESKTOP; | 226 item->route->content_source = ash::mojom::ContentSource::DESKTOP; |
| 192 | 227 |
| 193 break; | 228 break; |
| 194 } | 229 } |
| 195 } | 230 } |
| 196 } | 231 } |
| 197 | 232 |
| 198 for (ash::CastConfigDelegate::Observer& observer : observer_list_) | 233 cast_config_->OnDevicesUpdated(std::move(items)); |
| 199 observer.OnDevicesUpdated(items); | |
| 200 } | 234 } |
| 201 | 235 |
| 202 void CastConfigDelegateMediaRouter::CastToSink(const Sink& sink) { | 236 void CastConfigClientMediaRouter::CastToSink(ash::mojom::CastSinkPtr sink) { |
| 203 // TODO(imcheng): Pass in tab casting timeout. | 237 // TODO(imcheng): Pass in tab casting timeout. |
| 204 GetMediaRouter()->CreateRoute( | 238 GetMediaRouter()->CreateRoute( |
| 205 media_router::MediaSourceForDesktop().id(), sink.id, | 239 media_router::MediaSourceForDesktop().id(), sink->id, |
| 206 GURL("http://cros-cast-origin/"), nullptr, | 240 GURL("http://cros-cast-origin/"), nullptr, |
| 207 std::vector<media_router::MediaRouteResponseCallback>(), | 241 std::vector<media_router::MediaRouteResponseCallback>(), |
| 208 base::TimeDelta(), false); | 242 base::TimeDelta(), false); |
| 209 } | 243 } |
| 210 | 244 |
| 211 void CastConfigDelegateMediaRouter::StopCasting(const Route& route) { | 245 void CastConfigClientMediaRouter::StopCasting(ash::mojom::CastRoutePtr route) { |
| 212 GetMediaRouter()->TerminateRoute(route.id); | 246 GetMediaRouter()->TerminateRoute(route->id); |
| 213 } | 247 } |
| 214 | 248 |
| 215 void CastConfigDelegateMediaRouter::AddObserver( | 249 void CastConfigClientMediaRouter::Observe( |
| 216 ash::CastConfigDelegate::Observer* observer) { | |
| 217 observer_list_.AddObserver(observer); | |
| 218 } | |
| 219 | |
| 220 void CastConfigDelegateMediaRouter::RemoveObserver( | |
| 221 ash::CastConfigDelegate::Observer* observer) { | |
| 222 observer_list_.RemoveObserver(observer); | |
| 223 } | |
| 224 | |
| 225 void CastConfigDelegateMediaRouter::Observe( | |
| 226 int type, | 250 int type, |
| 227 const content::NotificationSource& source, | 251 const content::NotificationSource& source, |
| 228 const content::NotificationDetails& details) { | 252 const content::NotificationDetails& details) { |
| 229 switch (type) { | 253 switch (type) { |
| 230 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: | 254 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: |
| 231 // The active profile has changed, which means that the media router has | 255 // The active profile has changed, which means that the media router has |
| 232 // as well. Reset the device cache to ensure we are using up-to-date | 256 // as well. Reset the device cache to ensure we are using up-to-date |
| 233 // object instances. | 257 // object instances. |
| 234 devices_.reset(); | 258 devices_.reset(); |
| 235 RequestDeviceRefresh(); | 259 RequestDeviceRefresh(); |
| 236 break; | 260 break; |
| 237 } | 261 } |
| 238 } | 262 } |
| OLD | NEW |