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