| 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 "ash/common/system/chromeos/cast/tray_cast.h" | 5 #include "ash/common/system/chromeos/cast/tray_cast.h" |
| 6 | 6 |
| 7 #include "ash/common/cast_config_client_proxy.h" |
| 7 #include "ash/common/material_design/material_design_controller.h" | 8 #include "ash/common/material_design/material_design_controller.h" |
| 8 #include "ash/common/session/session_state_delegate.h" | 9 #include "ash/common/session/session_state_delegate.h" |
| 9 #include "ash/common/shelf/wm_shelf_util.h" | 10 #include "ash/common/shelf/wm_shelf_util.h" |
| 10 #include "ash/common/system/chromeos/screen_security/screen_tray_item.h" | 11 #include "ash/common/system/chromeos/screen_security/screen_tray_item.h" |
| 11 #include "ash/common/system/tray/fixed_sized_image_view.h" | 12 #include "ash/common/system/tray/fixed_sized_image_view.h" |
| 12 #include "ash/common/system/tray/fixed_sized_scroll_view.h" | 13 #include "ash/common/system/tray/fixed_sized_scroll_view.h" |
| 13 #include "ash/common/system/tray/hover_highlight_view.h" | 14 #include "ash/common/system/tray/hover_highlight_view.h" |
| 14 #include "ash/common/system/tray/system_tray.h" | 15 #include "ash/common/system/tray/system_tray.h" |
| 15 #include "ash/common/system/tray/system_tray_delegate.h" | 16 #include "ash/common/system/tray/system_tray_delegate.h" |
| 16 #include "ash/common/system/tray/throbber_view.h" | 17 #include "ash/common/system/tray/throbber_view.h" |
| 17 #include "ash/common/system/tray/tray_constants.h" | 18 #include "ash/common/system/tray/tray_constants.h" |
| 18 #include "ash/common/system/tray/tray_details_view.h" | 19 #include "ash/common/system/tray/tray_details_view.h" |
| 19 #include "ash/common/system/tray/tray_item_more.h" | 20 #include "ash/common/system/tray/tray_item_more.h" |
| 20 #include "ash/common/system/tray/tray_item_view.h" | 21 #include "ash/common/system/tray/tray_item_view.h" |
| 21 #include "ash/common/system/tray/tray_utils.h" | 22 #include "ash/common/system/tray/tray_utils.h" |
| 22 #include "ash/common/wm_shell.h" | 23 #include "ash/common/wm_shell.h" |
| 23 #include "ash/public/cpp/shelf_types.h" | 24 #include "ash/public/cpp/shelf_types.h" |
| 25 #include "ash/public/interfaces/cast_config.mojom.h" |
| 24 #include "ash/resources/vector_icons/vector_icons.h" | 26 #include "ash/resources/vector_icons/vector_icons.h" |
| 25 #include "base/bind.h" | 27 #include "base/bind.h" |
| 28 #include "base/strings/utf_string_conversions.h" |
| 26 #include "grit/ash_resources.h" | 29 #include "grit/ash_resources.h" |
| 27 #include "grit/ash_strings.h" | 30 #include "grit/ash_strings.h" |
| 28 #include "ui/base/l10n/l10n_util.h" | 31 #include "ui/base/l10n/l10n_util.h" |
| 29 #include "ui/base/resource/resource_bundle.h" | 32 #include "ui/base/resource/resource_bundle.h" |
| 30 #include "ui/gfx/image/image.h" | 33 #include "ui/gfx/image/image.h" |
| 31 #include "ui/gfx/paint_vector_icon.h" | 34 #include "ui/gfx/paint_vector_icon.h" |
| 32 #include "ui/gfx/text_elider.h" | 35 #include "ui/gfx/text_elider.h" |
| 33 #include "ui/views/background.h" | 36 #include "ui/views/background.h" |
| 34 #include "ui/views/border.h" | 37 #include "ui/views/border.h" |
| 35 #include "ui/views/controls/button/button.h" | 38 #include "ui/views/controls/button/button.h" |
| 36 #include "ui/views/controls/image_view.h" | 39 #include "ui/views/controls/image_view.h" |
| 37 #include "ui/views/controls/label.h" | 40 #include "ui/views/controls/label.h" |
| 38 #include "ui/views/layout/box_layout.h" | 41 #include "ui/views/layout/box_layout.h" |
| 39 #include "ui/views/layout/fill_layout.h" | 42 #include "ui/views/layout/fill_layout.h" |
| 40 | 43 |
| 41 namespace ash { | 44 namespace ash { |
| 42 | 45 |
| 43 namespace { | 46 namespace { |
| 44 | 47 |
| 45 const size_t kMaximumStatusStringLength = 100; | 48 const size_t kMaximumStatusStringLength = 100; |
| 46 | 49 |
| 47 // Returns the active CastConfigDelegate instance. | |
| 48 CastConfigDelegate* GetCastConfigDelegate() { | |
| 49 ash::SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate(); | |
| 50 return delegate ? delegate->GetCastConfigDelegate() : nullptr; | |
| 51 } | |
| 52 | |
| 53 // Helper method to elide the given string to the maximum length. If a string is | 50 // Helper method to elide the given string to the maximum length. If a string is |
| 54 // contains user-input and is displayed, we should elide it. | 51 // contains user-input and is displayed, we should elide it. |
| 55 // TODO(jdufault): This does not properly trim unicode characters. We should | 52 // TODO(jdufault): This does not properly trim unicode characters. We should |
| 56 // implement this properly by using views::Label::SetElideBehavior(...). See | 53 // implement this properly by using views::Label::SetElideBehavior(...). See |
| 57 // crbug.com/532496. | 54 // crbug.com/532496. |
| 58 base::string16 ElideString(const base::string16& text) { | 55 base::string16 ElideString(const base::string16& text) { |
| 59 base::string16 elided; | 56 base::string16 elided; |
| 60 gfx::ElideString(text, kMaximumStatusStringLength, &elided); | 57 gfx::ElideString(text, kMaximumStatusStringLength, &elided); |
| 61 return elided; | 58 return elided; |
| 62 } | 59 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 // This view is displayed when the screen is actively being casted; it allows | 104 // This view is displayed when the screen is actively being casted; it allows |
| 108 // the user to easily stop casting. It fully replaces the | 105 // the user to easily stop casting. It fully replaces the |
| 109 // |CastSelectDefaultView| view inside of the |CastDuplexView|. | 106 // |CastSelectDefaultView| view inside of the |CastDuplexView|. |
| 110 class CastCastView : public ScreenStatusView { | 107 class CastCastView : public ScreenStatusView { |
| 111 public: | 108 public: |
| 112 CastCastView(); | 109 CastCastView(); |
| 113 ~CastCastView() override; | 110 ~CastCastView() override; |
| 114 | 111 |
| 115 void StopCasting(); | 112 void StopCasting(); |
| 116 | 113 |
| 117 const std::string& displayed_route_id() const { return displayed_route_.id; } | 114 const std::string& displayed_route_id() const { return displayed_route_->id; } |
| 118 | 115 |
| 119 // Updates the label for the stop view to include information about the | 116 // Updates the label for the stop view to include information about the |
| 120 // current device that is being casted. | 117 // current device that is being casted. |
| 121 void UpdateLabel(const CastConfigDelegate::SinksAndRoutes& sinks_routes); | 118 void UpdateLabel(const std::vector<mojom::SinkAndRoutePtr>& sinks_routes); |
| 122 | 119 |
| 123 private: | 120 private: |
| 124 // Overridden from views::ButtonListener. | 121 // Overridden from views::ButtonListener. |
| 125 void ButtonPressed(views::Button* sender, const ui::Event& event) override; | 122 void ButtonPressed(views::Button* sender, const ui::Event& event) override; |
| 126 | 123 |
| 127 // The cast activity id that we are displaying. If the user stops a cast, we | 124 // The cast activity id that we are displaying. If the user stops a cast, we |
| 128 // send this value to the config delegate so that we stop the right cast. | 125 // send this value to the config delegate so that we stop the right cast. |
| 129 CastConfigDelegate::Route displayed_route_; | 126 mojom::CastRoutePtr displayed_route_; |
| 130 | 127 |
| 131 DISALLOW_COPY_AND_ASSIGN(CastCastView); | 128 DISALLOW_COPY_AND_ASSIGN(CastCastView); |
| 132 }; | 129 }; |
| 133 | 130 |
| 134 CastCastView::CastCastView() | 131 CastCastView::CastCastView() |
| 135 : ScreenStatusView( | 132 : ScreenStatusView( |
| 136 nullptr, | 133 nullptr, |
| 137 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN), | 134 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN), |
| 138 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_STOP)) { | 135 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_STOP)) { |
| 139 if (MaterialDesignController::IsSystemTrayMenuMaterial()) { | 136 if (MaterialDesignController::IsSystemTrayMenuMaterial()) { |
| 140 icon()->SetImage(GetCastIconForSystemMenu(true)); | 137 icon()->SetImage(GetCastIconForSystemMenu(true)); |
| 141 } else { | 138 } else { |
| 142 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 139 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
| 143 icon()->SetImage( | 140 icon()->SetImage( |
| 144 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia()); | 141 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia()); |
| 145 } | 142 } |
| 146 } | 143 } |
| 147 | 144 |
| 148 CastCastView::~CastCastView() {} | 145 CastCastView::~CastCastView() {} |
| 149 | 146 |
| 150 void CastCastView::StopCasting() { | 147 void CastCastView::StopCasting() { |
| 151 GetCastConfigDelegate()->StopCasting(displayed_route_); | 148 WmShell::Get()->cast_config_client()->StopCasting(displayed_route_.Clone()); |
| 152 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_CAST_STOP_CAST); | 149 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_CAST_STOP_CAST); |
| 153 } | 150 } |
| 154 | 151 |
| 155 void CastCastView::UpdateLabel( | 152 void CastCastView::UpdateLabel( |
| 156 const CastConfigDelegate::SinksAndRoutes& sinks_routes) { | 153 const std::vector<mojom::SinkAndRoutePtr>& sinks_routes) { |
| 157 for (auto& i : sinks_routes) { | 154 for (auto& i : sinks_routes) { |
| 158 const CastConfigDelegate::Sink& sink = i.sink; | 155 const mojom::CastSinkPtr& sink = i->sink; |
| 159 const CastConfigDelegate::Route& route = i.route; | 156 const mojom::CastRoutePtr& route = i->route; |
| 160 | 157 |
| 161 if (!route.id.empty()) { | 158 if (!route->id.empty()) { |
| 162 displayed_route_ = route; | 159 displayed_route_ = route.Clone(); |
| 163 | 160 |
| 164 // We want to display different labels inside of the title depending on | 161 // We want to display different labels inside of the title depending on |
| 165 // what we are actually casting - either the desktop, a tab, or a fallback | 162 // what we are actually casting - either the desktop, a tab, or a fallback |
| 166 // that catches everything else (ie, an extension tab). | 163 // that catches everything else (ie, an extension tab). |
| 167 switch (route.content_source) { | 164 switch (route->content_source) { |
| 168 case CastConfigDelegate::Route::ContentSource::UNKNOWN: | 165 case ash::mojom::ContentSource::UNKNOWN: |
| 169 label()->SetText( | 166 label()->SetText( |
| 170 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN)); | 167 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN)); |
| 171 break; | 168 break; |
| 172 case CastConfigDelegate::Route::ContentSource::TAB: | 169 case ash::mojom::ContentSource::TAB: |
| 173 label()->SetText(ElideString(l10n_util::GetStringFUTF16( | 170 label()->SetText(ElideString(l10n_util::GetStringFUTF16( |
| 174 IDS_ASH_STATUS_TRAY_CAST_CAST_TAB, route.title, sink.name))); | 171 IDS_ASH_STATUS_TRAY_CAST_CAST_TAB, |
| 172 base::UTF8ToUTF16(route->title), base::UTF8ToUTF16(sink->name)))); |
| 175 break; | 173 break; |
| 176 case CastConfigDelegate::Route::ContentSource::DESKTOP: | 174 case ash::mojom::ContentSource::DESKTOP: |
| 177 label()->SetText(ElideString(l10n_util::GetStringFUTF16( | 175 label()->SetText(ElideString( |
| 178 IDS_ASH_STATUS_TRAY_CAST_CAST_DESKTOP, sink.name))); | 176 l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_CAST_CAST_DESKTOP, |
| 177 base::UTF8ToUTF16(sink->name)))); |
| 179 break; | 178 break; |
| 180 } | 179 } |
| 181 | 180 |
| 182 PreferredSizeChanged(); | 181 PreferredSizeChanged(); |
| 183 Layout(); | 182 Layout(); |
| 184 | 183 |
| 185 // If this machine is the source of the activity, then we want to display | 184 // If this machine is the source of the activity, then we want to display |
| 186 // it over any other activity. There can be multiple activities if other | 185 // it over any other activity. There can be multiple activities if other |
| 187 // devices on the network are casting at the same time. | 186 // devices on the network are casting at the same time. |
| 188 if (route.is_local_source) | 187 if (route->is_local_source) |
| 189 break; | 188 break; |
| 190 } | 189 } |
| 191 } | 190 } |
| 192 } | 191 } |
| 193 | 192 |
| 194 void CastCastView::ButtonPressed(views::Button* sender, | 193 void CastCastView::ButtonPressed(views::Button* sender, |
| 195 const ui::Event& event) { | 194 const ui::Event& event) { |
| 196 StopCasting(); | 195 StopCasting(); |
| 197 } | 196 } |
| 198 | 197 |
| 199 // This view by itself does very little. It acts as a front-end for managing | 198 // This view by itself does very little. It acts as a front-end for managing |
| 200 // which of the two child views (|CastSelectDefaultView| and |CastCastView|) | 199 // which of the two child views (|CastSelectDefaultView| and |CastCastView|) |
| 201 // is active. | 200 // is active. |
| 202 class CastDuplexView : public views::View { | 201 class CastDuplexView : public views::View { |
| 203 public: | 202 public: |
| 204 CastDuplexView(SystemTrayItem* owner, | 203 CastDuplexView(SystemTrayItem* owner, |
| 205 bool show_more, | 204 bool show_more, |
| 206 const CastConfigDelegate::SinksAndRoutes& sinks_routes); | 205 const std::vector<mojom::SinkAndRoutePtr>& sinks_routes); |
| 207 ~CastDuplexView() override; | 206 ~CastDuplexView() override; |
| 208 | 207 |
| 209 // Activate either the casting or select view. | 208 // Activate either the casting or select view. |
| 210 void ActivateCastView(); | 209 void ActivateCastView(); |
| 211 void ActivateSelectView(); | 210 void ActivateSelectView(); |
| 212 | 211 |
| 213 CastSelectDefaultView* select_view() { return select_view_; } | 212 CastSelectDefaultView* select_view() { return select_view_; } |
| 214 CastCastView* cast_view() { return cast_view_; } | 213 CastCastView* cast_view() { return cast_view_; } |
| 215 | 214 |
| 216 private: | 215 private: |
| 217 // Overridden from views::View. | 216 // Overridden from views::View. |
| 218 void ChildPreferredSizeChanged(views::View* child) override; | 217 void ChildPreferredSizeChanged(views::View* child) override; |
| 219 void Layout() override; | 218 void Layout() override; |
| 220 | 219 |
| 221 // Only one of |select_view_| or |cast_view_| will be displayed at any given | 220 // Only one of |select_view_| or |cast_view_| will be displayed at any given |
| 222 // time. This will return the view is being displayed. | 221 // time. This will return the view is being displayed. |
| 223 views::View* ActiveChildView(); | 222 views::View* ActiveChildView(); |
| 224 | 223 |
| 225 CastSelectDefaultView* select_view_; | 224 CastSelectDefaultView* select_view_; |
| 226 CastCastView* cast_view_; | 225 CastCastView* cast_view_; |
| 227 | 226 |
| 228 DISALLOW_COPY_AND_ASSIGN(CastDuplexView); | 227 DISALLOW_COPY_AND_ASSIGN(CastDuplexView); |
| 229 }; | 228 }; |
| 230 | 229 |
| 231 CastDuplexView::CastDuplexView( | 230 CastDuplexView::CastDuplexView( |
| 232 SystemTrayItem* owner, | 231 SystemTrayItem* owner, |
| 233 bool show_more, | 232 bool show_more, |
| 234 const CastConfigDelegate::SinksAndRoutes& sinks_routes) { | 233 const std::vector<mojom::SinkAndRoutePtr>& sinks_routes) { |
| 235 select_view_ = new CastSelectDefaultView(owner, show_more); | 234 select_view_ = new CastSelectDefaultView(owner, show_more); |
| 236 cast_view_ = new CastCastView(); | 235 cast_view_ = new CastCastView(); |
| 237 cast_view_->UpdateLabel(sinks_routes); | 236 cast_view_->UpdateLabel(sinks_routes); |
| 238 SetLayoutManager(new views::FillLayout()); | 237 SetLayoutManager(new views::FillLayout()); |
| 239 | 238 |
| 240 ActivateSelectView(); | 239 ActivateSelectView(); |
| 241 } | 240 } |
| 242 | 241 |
| 243 CastDuplexView::~CastDuplexView() { | 242 CastDuplexView::~CastDuplexView() { |
| 244 RemoveChildView(ActiveChildView()); | 243 RemoveChildView(ActiveChildView()); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 } | 306 } |
| 308 | 307 |
| 309 CastTrayView::~CastTrayView() {} | 308 CastTrayView::~CastTrayView() {} |
| 310 | 309 |
| 311 // This view displays a list of cast receivers that can be clicked on and casted | 310 // This view displays a list of cast receivers that can be clicked on and casted |
| 312 // to. It is activated by clicking on the chevron inside of | 311 // to. It is activated by clicking on the chevron inside of |
| 313 // |CastSelectDefaultView|. | 312 // |CastSelectDefaultView|. |
| 314 class CastDetailedView : public TrayDetailsView { | 313 class CastDetailedView : public TrayDetailsView { |
| 315 public: | 314 public: |
| 316 CastDetailedView(SystemTrayItem* owner, | 315 CastDetailedView(SystemTrayItem* owner, |
| 317 const CastConfigDelegate::SinksAndRoutes& sinks_and_routes); | 316 const std::vector<mojom::SinkAndRoutePtr>& sinks_and_routes); |
| 318 ~CastDetailedView() override; | 317 ~CastDetailedView() override; |
| 319 | 318 |
| 320 // Makes the detail view think the view associated with the given receiver_id | 319 // Makes the detail view think the view associated with the given receiver_id |
| 321 // was clicked. This will start a cast. | 320 // was clicked. This will start a cast. |
| 322 void SimulateViewClickedForTest(const std::string& receiver_id); | 321 void SimulateViewClickedForTest(const std::string& receiver_id); |
| 323 | 322 |
| 324 // Updates the list of available receivers. | 323 // Updates the list of available receivers. |
| 325 void UpdateReceiverList( | 324 void UpdateReceiverList( |
| 326 const CastConfigDelegate::SinksAndRoutes& sinks_routes); | 325 const std::vector<mojom::SinkAndRoutePtr>& sinks_routes); |
| 327 | 326 |
| 328 private: | 327 private: |
| 329 void CreateItems(); | 328 void CreateItems(); |
| 330 | 329 |
| 331 void UpdateReceiverListFromCachedData(); | 330 void UpdateReceiverListFromCachedData(); |
| 332 views::View* AddToReceiverList( | 331 views::View* AddToReceiverList(const mojom::SinkAndRoutePtr& sink_route); |
| 333 const CastConfigDelegate::SinkAndRoute& sink_route); | |
| 334 | 332 |
| 335 // TrayDetailsView: | 333 // TrayDetailsView: |
| 336 void HandleViewClicked(views::View* view) override; | 334 void HandleViewClicked(views::View* view) override; |
| 337 | 335 |
| 338 // A mapping from the receiver id to the receiver/activity data. | 336 // A mapping from the receiver id to the receiver/activity data. |
| 339 std::map<std::string, CastConfigDelegate::SinkAndRoute> sinks_and_routes_; | 337 std::map<std::string, ash::mojom::SinkAndRoutePtr> sinks_and_routes_; |
| 340 // A mapping from the view pointer to the associated activity id. | 338 // A mapping from the view pointer to the associated activity id. |
| 341 std::map<views::View*, CastConfigDelegate::Sink> view_to_sink_map_; | 339 std::map<views::View*, ash::mojom::CastSinkPtr> view_to_sink_map_; |
| 342 | 340 |
| 343 DISALLOW_COPY_AND_ASSIGN(CastDetailedView); | 341 DISALLOW_COPY_AND_ASSIGN(CastDetailedView); |
| 344 }; | 342 }; |
| 345 | 343 |
| 346 CastDetailedView::CastDetailedView( | 344 CastDetailedView::CastDetailedView( |
| 347 SystemTrayItem* owner, | 345 SystemTrayItem* owner, |
| 348 const CastConfigDelegate::SinksAndRoutes& sinks_routes) | 346 const std::vector<mojom::SinkAndRoutePtr>& sinks_routes) |
| 349 : TrayDetailsView(owner) { | 347 : TrayDetailsView(owner) { |
| 350 CreateItems(); | 348 CreateItems(); |
| 351 UpdateReceiverList(sinks_routes); | 349 UpdateReceiverList(sinks_routes); |
| 352 } | 350 } |
| 353 | 351 |
| 354 CastDetailedView::~CastDetailedView() {} | 352 CastDetailedView::~CastDetailedView() {} |
| 355 | 353 |
| 356 void CastDetailedView::SimulateViewClickedForTest( | 354 void CastDetailedView::SimulateViewClickedForTest( |
| 357 const std::string& receiver_id) { | 355 const std::string& receiver_id) { |
| 358 for (const auto& it : view_to_sink_map_) { | 356 for (const auto& it : view_to_sink_map_) { |
| 359 if (it.second.id == receiver_id) { | 357 if (it.second->id == receiver_id) { |
| 360 HandleViewClicked(it.first); | 358 HandleViewClicked(it.first); |
| 361 break; | 359 break; |
| 362 } | 360 } |
| 363 } | 361 } |
| 364 } | 362 } |
| 365 | 363 |
| 366 void CastDetailedView::CreateItems() { | 364 void CastDetailedView::CreateItems() { |
| 367 CreateScrollableList(); | 365 CreateScrollableList(); |
| 368 CreateTitleRow(IDS_ASH_STATUS_TRAY_CAST); | 366 CreateTitleRow(IDS_ASH_STATUS_TRAY_CAST); |
| 369 } | 367 } |
| 370 | 368 |
| 371 void CastDetailedView::UpdateReceiverList( | 369 void CastDetailedView::UpdateReceiverList( |
| 372 const CastConfigDelegate::SinksAndRoutes& sinks_routes) { | 370 const std::vector<mojom::SinkAndRoutePtr>& sinks_routes) { |
| 373 // Add/update existing. | 371 // Add/update existing. |
| 374 for (const auto& it : sinks_routes) | 372 for (const auto& it : sinks_routes) |
| 375 sinks_and_routes_[it.sink.id] = it; | 373 sinks_and_routes_[it->sink->id] = it->Clone(); |
| 376 | 374 |
| 377 // Remove non-existent sinks. Removing an element invalidates all existing | 375 // Remove non-existent sinks. Removing an element invalidates all existing |
| 378 // iterators. | 376 // iterators. |
| 379 auto i = sinks_and_routes_.begin(); | 377 auto i = sinks_and_routes_.begin(); |
| 380 while (i != sinks_and_routes_.end()) { | 378 while (i != sinks_and_routes_.end()) { |
| 381 bool has_receiver = false; | 379 bool has_receiver = false; |
| 382 for (auto receiver : sinks_routes) { | 380 for (auto& receiver : sinks_routes) { |
| 383 if (i->first == receiver.sink.id) | 381 if (i->first == receiver->sink->id) |
| 384 has_receiver = true; | 382 has_receiver = true; |
| 385 } | 383 } |
| 386 | 384 |
| 387 if (has_receiver) | 385 if (has_receiver) |
| 388 ++i; | 386 ++i; |
| 389 else | 387 else |
| 390 i = sinks_and_routes_.erase(i); | 388 i = sinks_and_routes_.erase(i); |
| 391 } | 389 } |
| 392 | 390 |
| 393 // Update UI. | 391 // Update UI. |
| 394 UpdateReceiverListFromCachedData(); | 392 UpdateReceiverListFromCachedData(); |
| 395 Layout(); | 393 Layout(); |
| 396 } | 394 } |
| 397 | 395 |
| 398 void CastDetailedView::UpdateReceiverListFromCachedData() { | 396 void CastDetailedView::UpdateReceiverListFromCachedData() { |
| 399 // Remove all of the existing views. | 397 // Remove all of the existing views. |
| 400 view_to_sink_map_.clear(); | 398 view_to_sink_map_.clear(); |
| 401 scroll_content()->RemoveAllChildViews(true); | 399 scroll_content()->RemoveAllChildViews(true); |
| 402 | 400 |
| 403 // Add a view for each receiver. | 401 // Add a view for each receiver. |
| 404 for (auto& it : sinks_and_routes_) { | 402 for (auto& it : sinks_and_routes_) { |
| 405 const CastConfigDelegate::SinkAndRoute& sink_route = it.second; | 403 const ash::mojom::SinkAndRoutePtr& sink_route = it.second; |
| 406 views::View* container = AddToReceiverList(sink_route); | 404 views::View* container = AddToReceiverList(sink_route); |
| 407 view_to_sink_map_[container] = sink_route.sink; | 405 view_to_sink_map_[container] = sink_route->sink.Clone(); |
| 408 } | 406 } |
| 409 | 407 |
| 410 scroll_content()->SizeToPreferredSize(); | 408 scroll_content()->SizeToPreferredSize(); |
| 411 static_cast<views::View*>(scroller())->Layout(); | 409 static_cast<views::View*>(scroller())->Layout(); |
| 412 } | 410 } |
| 413 | 411 |
| 414 views::View* CastDetailedView::AddToReceiverList( | 412 views::View* CastDetailedView::AddToReceiverList( |
| 415 const CastConfigDelegate::SinkAndRoute& sink_route) { | 413 const ash::mojom::SinkAndRoutePtr& sink_route) { |
| 416 const gfx::ImageSkia image = | 414 const gfx::ImageSkia image = |
| 417 MaterialDesignController::IsSystemTrayMenuMaterial() | 415 MaterialDesignController::IsSystemTrayMenuMaterial() |
| 418 ? gfx::CreateVectorIcon(kSystemMenuCastDeviceIcon, kMenuIconColor) | 416 ? gfx::CreateVectorIcon(kSystemMenuCastDeviceIcon, kMenuIconColor) |
| 419 : *ui::ResourceBundle::GetSharedInstance() | 417 : *ui::ResourceBundle::GetSharedInstance() |
| 420 .GetImageNamed(IDR_AURA_UBER_TRAY_CAST_DEVICE_ICON) | 418 .GetImageNamed(IDR_AURA_UBER_TRAY_CAST_DEVICE_ICON) |
| 421 .ToImageSkia(); | 419 .ToImageSkia(); |
| 422 | 420 |
| 423 HoverHighlightView* container = new HoverHighlightView(this); | 421 HoverHighlightView* container = new HoverHighlightView(this); |
| 424 container->AddIconAndLabelCustomSize( | 422 container->AddIconAndLabelCustomSize( |
| 425 image, sink_route.sink.name, false, kTrayPopupDetailsIconWidth, | 423 image, base::UTF8ToUTF16(sink_route->sink->name), false, |
| 426 kTrayPopupPaddingHorizontal, kTrayPopupPaddingBetweenItems); | 424 kTrayPopupDetailsIconWidth, kTrayPopupPaddingHorizontal, |
| 425 kTrayPopupPaddingBetweenItems); |
| 427 | 426 |
| 428 scroll_content()->AddChildView(container); | 427 scroll_content()->AddChildView(container); |
| 429 return container; | 428 return container; |
| 430 } | 429 } |
| 431 | 430 |
| 432 void CastDetailedView::HandleViewClicked(views::View* view) { | 431 void CastDetailedView::HandleViewClicked(views::View* view) { |
| 433 // Find the receiver we are going to cast to. | 432 // Find the receiver we are going to cast to. |
| 434 auto it = view_to_sink_map_.find(view); | 433 auto it = view_to_sink_map_.find(view); |
| 435 if (it != view_to_sink_map_.end()) { | 434 if (it != view_to_sink_map_.end()) { |
| 436 GetCastConfigDelegate()->CastToSink(it->second); | 435 WmShell::Get()->cast_config_client()->CastToSink(it->second.Clone()); |
| 437 WmShell::Get()->RecordUserMetricsAction( | 436 WmShell::Get()->RecordUserMetricsAction( |
| 438 UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST); | 437 UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST); |
| 439 } | 438 } |
| 440 } | 439 } |
| 441 | 440 |
| 442 } // namespace tray | 441 } // namespace tray |
| 443 | 442 |
| 444 TrayCast::TrayCast(SystemTray* system_tray) | 443 TrayCast::TrayCast(SystemTray* system_tray) |
| 445 : SystemTrayItem(system_tray, UMA_CAST) { | 444 : SystemTrayItem(system_tray, UMA_CAST), observer_binding_(this) { |
| 446 WmShell::Get()->AddShellObserver(this); | 445 WmShell::Get()->AddShellObserver(this); |
| 447 | 446 |
| 448 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); | 447 WmShell::Get()->cast_config_client()->AddObserverBinding(&observer_binding_); |
| 449 if (cast_config_delegate) { | 448 WmShell::Get()->cast_config_client()->RequestDeviceRefresh(); |
| 450 cast_config_delegate->AddObserver(this); | |
| 451 cast_config_delegate->RequestDeviceRefresh(); | |
| 452 } | |
| 453 } | 449 } |
| 454 | 450 |
| 455 TrayCast::~TrayCast() { | 451 TrayCast::~TrayCast() { |
| 456 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); | |
| 457 if (cast_config_delegate) | |
| 458 cast_config_delegate->RemoveObserver(this); | |
| 459 | |
| 460 WmShell::Get()->RemoveShellObserver(this); | 452 WmShell::Get()->RemoveShellObserver(this); |
| 461 } | 453 } |
| 462 | 454 |
| 463 void TrayCast::StartCastForTest(const std::string& receiver_id) { | 455 void TrayCast::StartCastForTest(const std::string& receiver_id) { |
| 464 if (detailed_ != nullptr) | 456 if (detailed_ != nullptr) |
| 465 detailed_->SimulateViewClickedForTest(receiver_id); | 457 detailed_->SimulateViewClickedForTest(receiver_id); |
| 466 } | 458 } |
| 467 | 459 |
| 468 void TrayCast::StopCastForTest() { | 460 void TrayCast::StopCastForTest() { |
| 469 default_->cast_view()->StopCasting(); | 461 default_->cast_view()->StopCasting(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 } | 501 } |
| 510 | 502 |
| 511 void TrayCast::DestroyDefaultView() { | 503 void TrayCast::DestroyDefaultView() { |
| 512 default_ = nullptr; | 504 default_ = nullptr; |
| 513 } | 505 } |
| 514 | 506 |
| 515 void TrayCast::DestroyDetailedView() { | 507 void TrayCast::DestroyDetailedView() { |
| 516 detailed_ = nullptr; | 508 detailed_ = nullptr; |
| 517 } | 509 } |
| 518 | 510 |
| 519 void TrayCast::OnDevicesUpdated( | 511 void TrayCast::OnDevicesUpdated(std::vector<mojom::SinkAndRoutePtr> devices) { |
| 520 const CastConfigDelegate::SinksAndRoutes& sinks_routes) { | 512 sinks_and_routes_ = std::move(devices); |
| 521 sinks_and_routes_ = sinks_routes; | |
| 522 UpdatePrimaryView(); | 513 UpdatePrimaryView(); |
| 523 | 514 |
| 524 if (default_) { | 515 if (default_) { |
| 525 bool has_receivers = !sinks_and_routes_.empty(); | 516 bool has_receivers = !sinks_and_routes_.empty(); |
| 526 default_->SetVisible(has_receivers); | 517 default_->SetVisible(has_receivers); |
| 527 default_->cast_view()->UpdateLabel(sinks_and_routes_); | 518 default_->cast_view()->UpdateLabel(sinks_and_routes_); |
| 528 } | 519 } |
| 529 if (detailed_) | 520 if (detailed_) |
| 530 detailed_->UpdateReceiverList(sinks_and_routes_); | 521 detailed_->UpdateReceiverList(sinks_and_routes_); |
| 531 } | 522 } |
| 532 | 523 |
| 533 void TrayCast::UpdatePrimaryView() { | 524 void TrayCast::UpdatePrimaryView() { |
| 534 if (GetCastConfigDelegate() && !sinks_and_routes_.empty()) { | 525 if (WmShell::Get()->cast_config_client()->CanConnect() && |
| 526 !sinks_and_routes_.empty()) { |
| 535 if (default_) { | 527 if (default_) { |
| 536 if (HasActiveRoute()) | 528 if (HasActiveRoute()) |
| 537 default_->ActivateCastView(); | 529 default_->ActivateCastView(); |
| 538 else | 530 else |
| 539 default_->ActivateSelectView(); | 531 default_->ActivateSelectView(); |
| 540 } | 532 } |
| 541 | 533 |
| 542 if (tray_) | 534 if (tray_) |
| 543 tray_->SetVisible(is_mirror_casting_); | 535 tray_->SetVisible(is_mirror_casting_); |
| 544 } else { | 536 } else { |
| 545 if (default_) | 537 if (default_) |
| 546 default_->SetVisible(false); | 538 default_->SetVisible(false); |
| 547 if (tray_) | 539 if (tray_) |
| 548 tray_->SetVisible(false); | 540 tray_->SetVisible(false); |
| 549 } | 541 } |
| 550 } | 542 } |
| 551 | 543 |
| 552 bool TrayCast::HasActiveRoute() { | 544 bool TrayCast::HasActiveRoute() { |
| 553 if (is_mirror_casting_) | 545 if (is_mirror_casting_) |
| 554 return true; | 546 return true; |
| 555 | 547 |
| 556 for (const auto& sr : sinks_and_routes_) { | 548 for (const auto& sr : sinks_and_routes_) { |
| 557 if (!sr.route.title.empty()) | 549 if (!sr->route->title.empty()) |
| 558 return true; | 550 return true; |
| 559 } | 551 } |
| 560 | 552 |
| 561 return false; | 553 return false; |
| 562 } | 554 } |
| 563 | 555 |
| 564 void TrayCast::OnCastingSessionStartedOrStopped(bool started) { | 556 void TrayCast::OnCastingSessionStartedOrStopped(bool started) { |
| 565 is_mirror_casting_ = started; | 557 is_mirror_casting_ = started; |
| 566 UpdatePrimaryView(); | 558 UpdatePrimaryView(); |
| 567 } | 559 } |
| 568 | 560 |
| 569 } // namespace ash | 561 } // namespace ash |
| OLD | NEW |