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

Side by Side Diff: ash/system/cast/tray_cast.cc

Issue 1288073005: Make the ChromeOS chromecast system tray integration use a private API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Created 5 years, 4 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
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/system/cast/tray_cast.h" 5 #include "ash/system/cast/tray_cast.h"
6 6
7 #include "ash/session/session_state_delegate.h" 7 #include "ash/session/session_state_delegate.h"
8 #include "ash/shelf/shelf_types.h" 8 #include "ash/shelf/shelf_types.h"
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ash/system/chromeos/screen_security/screen_tray_item.h" 10 #include "ash/system/chromeos/screen_security/screen_tray_item.h"
(...skipping 18 matching lines...) Expand all
29 #include "ui/views/controls/button/button.h" 29 #include "ui/views/controls/button/button.h"
30 #include "ui/views/controls/image_view.h" 30 #include "ui/views/controls/image_view.h"
31 #include "ui/views/controls/label.h" 31 #include "ui/views/controls/label.h"
32 #include "ui/views/layout/box_layout.h" 32 #include "ui/views/layout/box_layout.h"
33 #include "ui/views/layout/fill_layout.h" 33 #include "ui/views/layout/fill_layout.h"
34 34
35 namespace ash { 35 namespace ash {
36 36
37 namespace { 37 namespace {
38 const int kStopButtonRightPadding = 18; 38 const int kStopButtonRightPadding = 18;
39
40 // Returns the active CastConfigDelegate instance.
41 ash::CastConfigDelegate* GetCastConfigDelegate() {
42 return ash::Shell::GetInstance()
43 ->system_tray_delegate()
44 ->GetCastConfigDelegate();
45 }
39 } // namespace 46 } // namespace
40 47
41 namespace tray { 48 namespace tray {
42 49
43 // This view is displayed in the system tray when the cast extension is active. 50 // This view is displayed in the system tray when the cast extension is active.
44 // It asks the user if they want to cast the desktop. If they click on the 51 // It asks the user if they want to cast the desktop. If they click on the
45 // chevron, then a detail view will replace this view where the user will 52 // chevron, then a detail view will replace this view where the user will
46 // actually pick the cast receiver. 53 // actually pick the cast receiver.
47 class CastSelectDefaultView : public TrayItemMore { 54 class CastSelectDefaultView : public TrayItemMore {
48 public: 55 public:
49 CastSelectDefaultView(SystemTrayItem* owner, 56 CastSelectDefaultView(SystemTrayItem* owner,
50 CastConfigDelegate* cast_config_delegate,
51 bool show_more); 57 bool show_more);
52 ~CastSelectDefaultView() override; 58 ~CastSelectDefaultView() override;
53 59
54 // Updates the label based on the current set of receivers (if there are or
55 // are not any available receivers).
56 void UpdateLabel();
57
58 private: 60 private:
59 void UpdateLabelCallback(
60 const CastConfigDelegate::ReceiversAndActivites& receivers_activities);
61
62 CastConfigDelegate* cast_config_delegate_;
63 base::WeakPtrFactory<CastSelectDefaultView> weak_ptr_factory_;
64 DISALLOW_COPY_AND_ASSIGN(CastSelectDefaultView); 61 DISALLOW_COPY_AND_ASSIGN(CastSelectDefaultView);
65 }; 62 };
66 63
67 CastSelectDefaultView::CastSelectDefaultView( 64 CastSelectDefaultView::CastSelectDefaultView(SystemTrayItem* owner,
68 SystemTrayItem* owner, 65 bool show_more)
69 CastConfigDelegate* cast_config_delegate, 66 : TrayItemMore(owner, show_more) {
70 bool show_more)
71 : TrayItemMore(owner, show_more),
72 cast_config_delegate_(cast_config_delegate),
73 weak_ptr_factory_(this) {
74 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 67 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
68
69 // Update the image and label.
75 SetImage(rb.GetImageNamed(IDR_AURA_UBER_TRAY_CAST).ToImageSkia()); 70 SetImage(rb.GetImageNamed(IDR_AURA_UBER_TRAY_CAST).ToImageSkia());
76 71 base::string16 label =
77 // We first set a default label before we actually know what the label will 72 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_DESKTOP);
78 // be, because it could take awhile before UpdateLabel() actually applies 73 SetLabel(label);
79 // the correct label. 74 SetAccessibleName(label);
80 SetLabel(rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_NO_DEVICE));
81 UpdateLabel();
82 } 75 }
83 76
84 CastSelectDefaultView::~CastSelectDefaultView() { 77 CastSelectDefaultView::~CastSelectDefaultView() {}
85 }
86
87 void CastSelectDefaultView::UpdateLabelCallback(
88 const CastConfigDelegate::ReceiversAndActivites& receivers_activities) {
89 // The label needs to reflect if there are no cast receivers
90 const base::string16 label =
91 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
92 receivers_activities.empty() ? IDS_ASH_STATUS_TRAY_CAST_NO_DEVICE
93 : IDS_ASH_STATUS_TRAY_CAST_DESKTOP);
94 SetLabel(label);
95 SetAccessibleName(label);
96 SetVisible(true);
97 }
98
99 void CastSelectDefaultView::UpdateLabel() {
100 if (cast_config_delegate_ == nullptr ||
101 cast_config_delegate_->HasCastExtension() == false)
102 return;
103
104 cast_config_delegate_->GetReceiversAndActivities(
105 base::Bind(&CastSelectDefaultView::UpdateLabelCallback,
106 weak_ptr_factory_.GetWeakPtr()));
107 }
108 78
109 // This view is displayed when the screen is actively being casted; it allows 79 // This view is displayed when the screen is actively being casted; it allows
110 // the user to easily stop casting. It fully replaces the 80 // the user to easily stop casting. It fully replaces the
111 // |CastSelectDefaultView| view inside of the |CastDuplexView|. 81 // |CastSelectDefaultView| view inside of the |CastDuplexView|.
112 class CastCastView : public views::View, public views::ButtonListener { 82 class CastCastView : public views::View, public views::ButtonListener {
113 public: 83 public:
114 explicit CastCastView(CastConfigDelegate* cast_config_delegate); 84 CastCastView();
115 ~CastCastView() override; 85 ~CastCastView() override;
116 86
117 void StopCasting(); 87 void StopCasting();
118 88
119 // Updates the label for the stop view to include information about the 89 // Updates the label for the stop view to include information about the
120 // current device that is being casted. 90 // current device that is being casted.
121 void UpdateLabel(); 91 void UpdateLabel(
92 const CastConfigDelegate::ReceiversAndActivites& receivers_activities);
122 93
123 private: 94 private:
124 void UpdateLabelCallback(
125 const CastConfigDelegate::ReceiversAndActivites& receivers_activities);
126
127 // Overridden from views::View. 95 // Overridden from views::View.
128 int GetHeightForWidth(int width) const override; 96 int GetHeightForWidth(int width) const override;
129 void Layout() override; 97 void Layout() override;
130 98
131 // Overridden from views::ButtonListener. 99 // Overridden from views::ButtonListener.
132 void ButtonPressed(views::Button* sender, const ui::Event& event) override; 100 void ButtonPressed(views::Button* sender, const ui::Event& event) override;
133 101
134 CastConfigDelegate* cast_config_delegate_;
135 views::ImageView* icon_; 102 views::ImageView* icon_;
136 views::Label* label_; 103 views::Label* label_;
137 TrayPopupLabelButton* stop_button_; 104 TrayPopupLabelButton* stop_button_;
138 base::WeakPtrFactory<CastCastView> weak_ptr_factory_; 105 base::WeakPtrFactory<CastCastView> weak_ptr_factory_;
139 106
140 DISALLOW_COPY_AND_ASSIGN(CastCastView); 107 DISALLOW_COPY_AND_ASSIGN(CastCastView);
141 }; 108 };
142 109
143 CastCastView::CastCastView(CastConfigDelegate* cast_config_delegate) 110 CastCastView::CastCastView() : weak_ptr_factory_(this) {
144 : cast_config_delegate_(cast_config_delegate), weak_ptr_factory_(this) {
145 // We will initialize the primary tray view which shows a stop button here. 111 // We will initialize the primary tray view which shows a stop button here.
146 112
147 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); 113 set_background(views::Background::CreateSolidBackground(kBackgroundColor));
148 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); 114 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
149 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 115 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
150 kTrayPopupPaddingHorizontal, 0, 116 kTrayPopupPaddingHorizontal, 0,
151 kTrayPopupPaddingBetweenItems)); 117 kTrayPopupPaddingBetweenItems));
152 icon_ = new FixedSizedImageView(0, kTrayPopupItemHeight); 118 icon_ = new FixedSizedImageView(0, kTrayPopupItemHeight);
153 icon_->SetImage( 119 icon_->SetImage(
154 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia()); 120 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia());
155 AddChildView(icon_); 121 AddChildView(icon_);
156 122
157 // The label which describes both what we are casting (ie, the desktop) and 123 // The label which describes both what we are casting (ie, the desktop) and
158 // where we are casting it to. 124 // where we are casting it to.
159 label_ = new views::Label; 125 label_ = new views::Label;
160 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 126 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
161 label_->SetMultiLine(true); 127 label_->SetMultiLine(true);
162 label_->SetText( 128 label_->SetText(
163 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN)); 129 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN));
164 AddChildView(label_); 130 AddChildView(label_);
165 131
166 // Add the stop bottom on the far-right. We customize how this stop button is 132 // Add the stop bottom on the far-right. We customize how this stop button is
167 // displayed inside of |Layout()|. 133 // displayed inside of |Layout()|.
168 base::string16 stop_button_text = 134 base::string16 stop_button_text =
169 ui::ResourceBundle::GetSharedInstance().GetLocalizedString( 135 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
170 IDS_ASH_STATUS_TRAY_CAST_STOP); 136 IDS_ASH_STATUS_TRAY_CAST_STOP);
171 stop_button_ = new TrayPopupLabelButton(this, stop_button_text); 137 stop_button_ = new TrayPopupLabelButton(this, stop_button_text);
172 AddChildView(stop_button_); 138 AddChildView(stop_button_);
173
174 UpdateLabel();
175 } 139 }
176 140
177 CastCastView::~CastCastView() { 141 CastCastView::~CastCastView() {
178 } 142 }
179 143
180 int CastCastView::GetHeightForWidth(int width) const { 144 int CastCastView::GetHeightForWidth(int width) const {
181 // We are reusing the cached label_->bounds() calculation which was 145 // We are reusing the cached label_->bounds() calculation which was
182 // done inside of Layout(). Due to the way this object is initialized, 146 // done inside of Layout(). Due to the way this object is initialized,
183 // Layout() will always get initially invoked with the dummy text 147 // Layout() will always get initially invoked with the dummy text
184 // (which will compute the proper label width) and then when we know 148 // (which will compute the proper label width) and then when we know
(...skipping 17 matching lines...) Expand all
202 // Adjust the label's bounds in case it got cut off by |stop_button_|. 166 // Adjust the label's bounds in case it got cut off by |stop_button_|.
203 if (label_->bounds().Intersects(stop_button_->bounds())) { 167 if (label_->bounds().Intersects(stop_button_->bounds())) {
204 gfx::Rect label_bounds = label_->bounds(); 168 gfx::Rect label_bounds = label_->bounds();
205 label_bounds.set_width(stop_button_->x() - kTrayPopupPaddingBetweenItems - 169 label_bounds.set_width(stop_button_->x() - kTrayPopupPaddingBetweenItems -
206 label_->x()); 170 label_->x());
207 label_->SetBoundsRect(label_bounds); 171 label_->SetBoundsRect(label_bounds);
208 } 172 }
209 } 173 }
210 174
211 void CastCastView::StopCasting() { 175 void CastCastView::StopCasting() {
212 cast_config_delegate_->StopCasting(); 176 GetCastConfigDelegate()->StopCasting();
213 Shell::GetInstance()->metrics()->RecordUserMetricsAction( 177 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
214 ash::UMA_STATUS_AREA_CAST_STOP_CAST); 178 ash::UMA_STATUS_AREA_CAST_STOP_CAST);
215 } 179 }
216 180
217 void CastCastView::UpdateLabel() { 181 void CastCastView::UpdateLabel(
218 if (cast_config_delegate_ == nullptr ||
219 cast_config_delegate_->HasCastExtension() == false)
220 return;
221
222 cast_config_delegate_->GetReceiversAndActivities(base::Bind(
223 &CastCastView::UpdateLabelCallback, weak_ptr_factory_.GetWeakPtr()));
224 }
225
226 void CastCastView::UpdateLabelCallback(
227 const CastConfigDelegate::ReceiversAndActivites& receivers_activities) { 182 const CastConfigDelegate::ReceiversAndActivites& receivers_activities) {
228 for (auto& i : receivers_activities) { 183 for (auto& i : receivers_activities) {
229 const CastConfigDelegate::Receiver receiver = i.second.receiver; 184 const CastConfigDelegate::Receiver& receiver = i.receiver;
230 const CastConfigDelegate::Activity activity = i.second.activity; 185 const CastConfigDelegate::Activity& activity = i.activity;
231 if (!activity.id.empty()) { 186 if (!activity.id.empty()) {
232 // We want to display different labels inside of the title depending on 187 // We want to display different labels inside of the title depending on
233 // what we are actually casting - either the desktop, a tab, or a fallback 188 // what we are actually casting - either the desktop, a tab, or a fallback
234 // that catches everything else (ie, an extension tab). 189 // that catches everything else (ie, an extension tab).
235 if (activity.tab_id == CastConfigDelegate::Activity::TabId::DESKTOP) { 190 if (activity.tab_id == CastConfigDelegate::Activity::TabId::DESKTOP) {
236 label_->SetText(l10n_util::GetStringFUTF16( 191 label_->SetText(l10n_util::GetStringFUTF16(
237 IDS_ASH_STATUS_TRAY_CAST_CAST_DESKTOP, receiver.name)); 192 IDS_ASH_STATUS_TRAY_CAST_CAST_DESKTOP, receiver.name));
238 } else if (activity.tab_id >= 0) { 193 } else if (activity.tab_id >= 0) {
239 label_->SetText(l10n_util::GetStringFUTF16( 194 label_->SetText(l10n_util::GetStringFUTF16(
240 IDS_ASH_STATUS_TRAY_CAST_CAST_TAB, activity.title, receiver.name)); 195 IDS_ASH_STATUS_TRAY_CAST_CAST_TAB, activity.title, receiver.name));
(...skipping 13 matching lines...) Expand all
254 const ui::Event& event) { 209 const ui::Event& event) {
255 DCHECK(sender == stop_button_); 210 DCHECK(sender == stop_button_);
256 StopCasting(); 211 StopCasting();
257 } 212 }
258 213
259 // This view by itself does very little. It acts as a front-end for managing 214 // This view by itself does very little. It acts as a front-end for managing
260 // which of the two child views (|CastSelectDefaultView| and |CastCastView|) 215 // which of the two child views (|CastSelectDefaultView| and |CastCastView|)
261 // is active. 216 // is active.
262 class CastDuplexView : public views::View { 217 class CastDuplexView : public views::View {
263 public: 218 public:
264 CastDuplexView(SystemTrayItem* owner, 219 CastDuplexView(
265 CastConfigDelegate* config_delegate, 220 SystemTrayItem* owner,
266 bool show_more); 221 bool show_more,
222 const CastConfigDelegate::ReceiversAndActivites& receivers_activities);
267 ~CastDuplexView() override; 223 ~CastDuplexView() override;
268 224
269 // Activate either the casting or select view. 225 // Activate either the casting or select view.
270 void ActivateCastView(); 226 void ActivateCastView();
271 void ActivateSelectView(); 227 void ActivateSelectView();
272 228
273 CastSelectDefaultView* select_view() { return select_view_; } 229 CastSelectDefaultView* select_view() { return select_view_; }
274 CastCastView* cast_view() { return cast_view_; } 230 CastCastView* cast_view() { return cast_view_; }
275 231
276 private: 232 private:
277 // Overridden from views::View. 233 // Overridden from views::View.
278 void ChildPreferredSizeChanged(views::View* child) override; 234 void ChildPreferredSizeChanged(views::View* child) override;
279 void Layout() override; 235 void Layout() override;
280 236
281 // Only one of |select_view_| or |cast_view_| will be displayed at any given 237 // Only one of |select_view_| or |cast_view_| will be displayed at any given
282 // time. This will return the view is being displayed. 238 // time. This will return the view is being displayed.
283 views::View* ActiveChildView(); 239 views::View* ActiveChildView();
284 240
285 CastSelectDefaultView* select_view_; 241 CastSelectDefaultView* select_view_;
286 CastCastView* cast_view_; 242 CastCastView* cast_view_;
287 243
288 DISALLOW_COPY_AND_ASSIGN(CastDuplexView); 244 DISALLOW_COPY_AND_ASSIGN(CastDuplexView);
289 }; 245 };
290 246
291 CastDuplexView::CastDuplexView(SystemTrayItem* owner, 247 CastDuplexView::CastDuplexView(
292 CastConfigDelegate* config_delegate, 248 SystemTrayItem* owner,
293 bool show_more) { 249 bool show_more,
294 select_view_ = new CastSelectDefaultView(owner, config_delegate, show_more); 250 const CastConfigDelegate::ReceiversAndActivites& receivers_activities) {
295 cast_view_ = new CastCastView(config_delegate); 251 select_view_ = new CastSelectDefaultView(owner, show_more);
252 cast_view_ = new CastCastView();
253 cast_view_->UpdateLabel(receivers_activities);
296 SetLayoutManager(new views::FillLayout()); 254 SetLayoutManager(new views::FillLayout());
297 255
298 ActivateSelectView(); 256 ActivateSelectView();
299 } 257 }
300 258
301 CastDuplexView::~CastDuplexView() { 259 CastDuplexView::~CastDuplexView() {
302 RemoveChildView(ActiveChildView()); 260 RemoveChildView(ActiveChildView());
303 delete select_view_; 261 delete select_view_;
304 delete cast_view_; 262 delete cast_view_;
305 } 263 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0)); 341 SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0));
384 Layout(); 342 Layout();
385 } 343 }
386 344
387 // This view displays a list of cast receivers that can be clicked on and casted 345 // This view displays a list of cast receivers that can be clicked on and casted
388 // to. It is activated by clicking on the chevron inside of 346 // to. It is activated by clicking on the chevron inside of
389 // |CastSelectDefaultView|. 347 // |CastSelectDefaultView|.
390 class CastDetailedView : public TrayDetailsView, public ViewClickListener { 348 class CastDetailedView : public TrayDetailsView, public ViewClickListener {
391 public: 349 public:
392 CastDetailedView(SystemTrayItem* owner, 350 CastDetailedView(SystemTrayItem* owner,
393 CastConfigDelegate* cast_config_delegate, 351 user::LoginStatus login,
394 user::LoginStatus login); 352 const CastConfigDelegate::ReceiversAndActivites&
353 receivers_and_activities);
395 ~CastDetailedView() override; 354 ~CastDetailedView() override;
396 355
397 // Makes the detail view think the view associated with the given receiver_id 356 // Makes the detail view think the view associated with the given receiver_id
398 // was clicked. This will start a cast. 357 // was clicked. This will start a cast.
399 void SimulateViewClickedForTest(const std::string& receiver_id); 358 void SimulateViewClickedForTest(const std::string& receiver_id);
400 359
360 // Updates the list of available receivers.
361 void UpdateReceiverList(const CastConfigDelegate::ReceiversAndActivites&
362 new_receivers_and_activities);
363
401 private: 364 private:
402 void CreateItems(); 365 void CreateItems();
403 366
404 void UpdateReceiverList();
405 void UpdateReceiverListCallback(
406 const CastConfigDelegate::ReceiversAndActivites&
407 new_receivers_and_activities);
408 void UpdateReceiverListFromCachedData(); 367 void UpdateReceiverListFromCachedData();
409 views::View* AddToReceiverList( 368 views::View* AddToReceiverList(
410 const CastConfigDelegate::ReceiverAndActivity& receiverActivity); 369 const CastConfigDelegate::ReceiverAndActivity& receiverActivity);
411 370
412 void AppendSettingsEntries(); 371 void AppendSettingsEntries();
413 void AppendHeaderEntry(); 372 void AppendHeaderEntry();
414 373
415 // Overridden from ViewClickListener. 374 // Overridden from ViewClickListener.
416 void OnViewClicked(views::View* sender) override; 375 void OnViewClicked(views::View* sender) override;
417 376
418 CastConfigDelegate* cast_config_delegate_;
419 user::LoginStatus login_; 377 user::LoginStatus login_;
420 views::View* options_ = nullptr; 378 views::View* options_ = nullptr;
421 CastConfigDelegate::ReceiversAndActivites receivers_and_activities_; 379 // A mapping from the receiver id to the receiver/activity data.
422 // A mapping from the view pointer to the associated activity id 380 std::map<std::string, CastConfigDelegate::ReceiverAndActivity>
381 receivers_and_activities_;
382 // A mapping from the view pointer to the associated activity id.
423 std::map<views::View*, std::string> receiver_activity_map_; 383 std::map<views::View*, std::string> receiver_activity_map_;
424 base::WeakPtrFactory<CastDetailedView> weak_ptr_factory_; 384 base::WeakPtrFactory<CastDetailedView> weak_ptr_factory_;
425 385
426 DISALLOW_COPY_AND_ASSIGN(CastDetailedView); 386 DISALLOW_COPY_AND_ASSIGN(CastDetailedView);
427 }; 387 };
428 388
429 CastDetailedView::CastDetailedView(SystemTrayItem* owner, 389 CastDetailedView::CastDetailedView(
430 CastConfigDelegate* cast_config_delegate, 390 SystemTrayItem* owner,
431 user::LoginStatus login) 391 user::LoginStatus login,
432 : TrayDetailsView(owner), 392 const CastConfigDelegate::ReceiversAndActivites& receivers_and_activities)
433 cast_config_delegate_(cast_config_delegate), 393 : TrayDetailsView(owner), login_(login), weak_ptr_factory_(this) {
434 login_(login),
435 weak_ptr_factory_(this) {
436 CreateItems(); 394 CreateItems();
437 UpdateReceiverList(); 395 UpdateReceiverList(receivers_and_activities);
438 } 396 }
439 397
440 CastDetailedView::~CastDetailedView() { 398 CastDetailedView::~CastDetailedView() {
441 } 399 }
442 400
443 void CastDetailedView::SimulateViewClickedForTest( 401 void CastDetailedView::SimulateViewClickedForTest(
444 const std::string& receiver_id) { 402 const std::string& receiver_id) {
445 for (auto& it : receiver_activity_map_) { 403 for (auto& it : receiver_activity_map_) {
446 if (it.second == receiver_id) { 404 if (it.second == receiver_id) {
447 OnViewClicked(it.first); 405 OnViewClicked(it.first);
448 break; 406 break;
449 } 407 }
450 } 408 }
451 } 409 }
452 410
453 void CastDetailedView::CreateItems() { 411 void CastDetailedView::CreateItems() {
454 CreateScrollableList(); 412 CreateScrollableList();
455 AppendSettingsEntries(); 413 AppendSettingsEntries();
456 AppendHeaderEntry(); 414 AppendHeaderEntry();
457 } 415 }
458 416
459 void CastDetailedView::UpdateReceiverList() { 417 void CastDetailedView::UpdateReceiverList(
460 cast_config_delegate_->GetReceiversAndActivities(
461 base::Bind(&CastDetailedView::UpdateReceiverListCallback,
462 weak_ptr_factory_.GetWeakPtr()));
463 }
464
465 void CastDetailedView::UpdateReceiverListCallback(
466 const CastConfigDelegate::ReceiversAndActivites& 418 const CastConfigDelegate::ReceiversAndActivites&
467 new_receivers_and_activities) { 419 new_receivers_and_activities) {
468 // Add/update existing. 420 // Add/update existing.
469 for (auto i = new_receivers_and_activities.begin(); 421 for (auto i = new_receivers_and_activities.begin();
470 i != new_receivers_and_activities.end(); ++i) { 422 i != new_receivers_and_activities.end(); ++i) {
471 receivers_and_activities_[i->first] = i->second; 423 receivers_and_activities_[i->receiver.id] = *i;
472 } 424 }
473 // Remove non-existent. 425
474 for (auto i = receivers_and_activities_.begin(); 426 // Remove non-existent receivers. Removing an element invalidates all existing
475 i != receivers_and_activities_.end(); ++i) { 427 // iterators.
476 if (new_receivers_and_activities.count(i->first) == 0) 428 auto i = receivers_and_activities_.begin();
477 receivers_and_activities_.erase(i->first); 429 while (i != receivers_and_activities_.end()) {
430 bool has_receiver = false;
431 for (auto receiver : new_receivers_and_activities) {
432 if (i->first == receiver.receiver.id)
433 has_receiver = true;
434 }
435
436 if (has_receiver)
437 ++i;
438 else
439 i = receivers_and_activities_.erase(i);
478 } 440 }
479 441
480 // Update UI. 442 // Update UI.
481 UpdateReceiverListFromCachedData(); 443 UpdateReceiverListFromCachedData();
482 Layout(); 444 Layout();
483 } 445 }
484 446
485 void CastDetailedView::UpdateReceiverListFromCachedData() { 447 void CastDetailedView::UpdateReceiverListFromCachedData() {
486 // Remove all of the existing views. 448 // Remove all of the existing views.
487 receiver_activity_map_.clear(); 449 receiver_activity_map_.clear();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 493
532 AddChildView(container); 494 AddChildView(container);
533 options_ = container; 495 options_ = container;
534 } 496 }
535 497
536 void CastDetailedView::AppendHeaderEntry() { 498 void CastDetailedView::AppendHeaderEntry() {
537 CreateSpecialRow(IDS_ASH_STATUS_TRAY_CAST, this); 499 CreateSpecialRow(IDS_ASH_STATUS_TRAY_CAST, this);
538 } 500 }
539 501
540 void CastDetailedView::OnViewClicked(views::View* sender) { 502 void CastDetailedView::OnViewClicked(views::View* sender) {
503 ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
504
541 if (sender == footer()->content()) { 505 if (sender == footer()->content()) {
542 TransitionToDefaultView(); 506 TransitionToDefaultView();
543 } else if (sender == options_) { 507 } else if (sender == options_) {
544 cast_config_delegate_->LaunchCastOptions(); 508 cast_config_delegate->LaunchCastOptions();
545 } else { 509 } else {
546 // Find the receiver we are going to cast to 510 // Find the receiver we are going to cast to
547 auto it = receiver_activity_map_.find(sender); 511 auto it = receiver_activity_map_.find(sender);
548 if (it != receiver_activity_map_.end()) { 512 if (it != receiver_activity_map_.end()) {
549 cast_config_delegate_->CastToReceiver(it->second); 513 cast_config_delegate->CastToReceiver(it->second);
550 Shell::GetInstance()->metrics()->RecordUserMetricsAction( 514 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
551 ash::UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST); 515 ash::UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST);
552 } 516 }
553 } 517 }
554 } 518 }
555 519
556 } // namespace tray 520 } // namespace tray
557 521
558 TrayCast::TrayCast(SystemTray* system_tray) 522 TrayCast::TrayCast(SystemTray* system_tray)
559 : SystemTrayItem(system_tray), 523 : SystemTrayItem(system_tray),
560 cast_config_delegate_(ash::Shell::GetInstance()
561 ->system_tray_delegate()
562 ->GetCastConfigDelegate()),
563 weak_ptr_factory_(this) { 524 weak_ptr_factory_(this) {
564 Shell::GetInstance()->AddShellObserver(this); 525 Shell::GetInstance()->AddShellObserver(this);
565 } 526 }
566 527
567 TrayCast::~TrayCast() { 528 TrayCast::~TrayCast() {
568 Shell::GetInstance()->RemoveShellObserver(this); 529 Shell::GetInstance()->RemoveShellObserver(this);
569 } 530 }
570 531
571 void TrayCast::StartCastForTest(const std::string& receiver_id) { 532 void TrayCast::StartCastForTest(const std::string& receiver_id) {
572 if (detailed_ != nullptr) 533 if (detailed_ != nullptr)
(...skipping 11 matching lines...) Expand all
584 views::View* TrayCast::CreateTrayView(user::LoginStatus status) { 545 views::View* TrayCast::CreateTrayView(user::LoginStatus status) {
585 CHECK(tray_ == nullptr); 546 CHECK(tray_ == nullptr);
586 tray_ = new tray::CastTrayView(this); 547 tray_ = new tray::CastTrayView(this);
587 tray_->SetVisible(is_casting_); 548 tray_->SetVisible(is_casting_);
588 return tray_; 549 return tray_;
589 } 550 }
590 551
591 views::View* TrayCast::CreateDefaultView(user::LoginStatus status) { 552 views::View* TrayCast::CreateDefaultView(user::LoginStatus status) {
592 CHECK(default_ == nullptr); 553 CHECK(default_ == nullptr);
593 554
594 default_ = new tray::CastDuplexView(this, cast_config_delegate_, 555 if (HasCastExtension()) {
595 status != user::LOGGED_IN_LOCKED); 556 ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
557
558 // We add the cast listener here instead of in the ctor for two reasons:
559 // - The ctor gets called too early in the initialization cycle (at least
560 // for the tests); the correct profile hasn't been setup yet.
561 // - The listener is only added if there is a cast extension. If the call
562 // below were in the ctor, then the cast tray item would not appear if the
563 // user installed the extension in an existing session.
564 if (!device_update_subscription_) {
565 device_update_subscription_ =
566 cast_config_delegate->RegisterDeviceUpdateObserver(base::Bind(
567 &TrayCast::OnReceiversUpdated, weak_ptr_factory_.GetWeakPtr()));
568 }
569
570 // The extension updates its view model whenever the popup is opened, so we
571 // probably should as well.
572 cast_config_delegate->RequestDeviceRefresh();
573 }
574
575 default_ = new tray::CastDuplexView(this, status != user::LOGGED_IN_LOCKED,
576 receivers_and_activities_);
596 default_->set_id(TRAY_VIEW); 577 default_->set_id(TRAY_VIEW);
597 default_->select_view()->set_id(SELECT_VIEW); 578 default_->select_view()->set_id(SELECT_VIEW);
598 default_->cast_view()->set_id(CAST_VIEW); 579 default_->cast_view()->set_id(CAST_VIEW);
599 580
600 UpdatePrimaryView(); 581 UpdatePrimaryView();
601 return default_; 582 return default_;
602 } 583 }
603 584
604 views::View* TrayCast::CreateDetailedView(user::LoginStatus status) { 585 views::View* TrayCast::CreateDetailedView(user::LoginStatus status) {
605 Shell::GetInstance()->metrics()->RecordUserMetricsAction( 586 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
606 ash::UMA_STATUS_AREA_DETAILED_CAST_VIEW); 587 ash::UMA_STATUS_AREA_DETAILED_CAST_VIEW);
607 CHECK(detailed_ == nullptr); 588 CHECK(detailed_ == nullptr);
608 detailed_ = new tray::CastDetailedView(this, cast_config_delegate_, status); 589 detailed_ =
590 new tray::CastDetailedView(this, status, receivers_and_activities_);
609 return detailed_; 591 return detailed_;
610 } 592 }
611 593
612 void TrayCast::DestroyTrayView() { 594 void TrayCast::DestroyTrayView() {
613 tray_ = nullptr; 595 tray_ = nullptr;
614 } 596 }
615 597
616 void TrayCast::DestroyDefaultView() { 598 void TrayCast::DestroyDefaultView() {
617 default_ = nullptr; 599 default_ = nullptr;
618 } 600 }
619 601
620 void TrayCast::DestroyDetailedView() { 602 void TrayCast::DestroyDetailedView() {
621 detailed_ = nullptr; 603 detailed_ = nullptr;
622 } 604 }
623 605
624 bool TrayCast::HasCastExtension() { 606 bool TrayCast::HasCastExtension() {
625 return cast_config_delegate_ != nullptr && 607 ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
626 cast_config_delegate_->HasCastExtension(); 608 return cast_config_delegate != nullptr &&
609 cast_config_delegate->HasCastExtension();
627 } 610 }
628 611
629 void TrayCast::UpdateCachedReceiverState( 612 void TrayCast::OnReceiversUpdated(
630 const CastConfigDelegate::ReceiversAndActivites& receivers_activities) { 613 const CastConfigDelegate::ReceiversAndActivites& receivers_activities) {
631 has_cast_receivers_ = !receivers_activities.empty(); 614 receivers_and_activities_ = receivers_activities;
632 if (default_) 615
633 default_->SetVisible(has_cast_receivers_); 616 if (default_) {
617 bool has_receivers = !receivers_and_activities_.empty();
618 default_->SetVisible(has_receivers);
619 default_->cast_view()->UpdateLabel(receivers_and_activities_);
620 }
621 if (detailed_)
622 detailed_->UpdateReceiverList(receivers_and_activities_);
634 } 623 }
635 624
636 void TrayCast::UpdatePrimaryView() { 625 void TrayCast::UpdatePrimaryView() {
637 if (HasCastExtension()) { 626 if (HasCastExtension()) {
638 if (default_) { 627 if (default_) {
639 if (is_casting_) { 628 if (is_casting_)
640 default_->ActivateCastView(); 629 default_->ActivateCastView();
641 } else { 630 else
642 default_->ActivateSelectView(); 631 default_->ActivateSelectView();
643
644 // We only want to show the select view if we have a receiver we can
645 // cast to. To prevent showing the tray item and then hiding it some
646 // short time after, we cache if we have any receivers. We set our
647 // default visibility to true if we do have a receiver, false otherwise.
648 default_->SetVisible(has_cast_receivers_);
649 cast_config_delegate_->GetReceiversAndActivities(
650 base::Bind(&TrayCast::UpdateCachedReceiverState,
651 weak_ptr_factory_.GetWeakPtr()));
652 }
653 } 632 }
654 633
655 if (tray_) 634 if (tray_)
656 tray_->SetVisible(is_casting_); 635 tray_->SetVisible(is_casting_);
657 } else { 636 } else {
658 if (default_) 637 if (default_)
659 default_->SetVisible(false); 638 default_->SetVisible(false);
660 if (tray_) 639 if (tray_)
661 tray_->SetVisible(false); 640 tray_->SetVisible(false);
662 } 641 }
663 } 642 }
664 643
665 void TrayCast::OnCastingSessionStartedOrStopped(bool started) { 644 void TrayCast::OnCastingSessionStartedOrStopped(bool started) {
666 is_casting_ = started; 645 is_casting_ = started;
667 UpdatePrimaryView(); 646 UpdatePrimaryView();
668 } 647 }
669 648
670 void TrayCast::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { 649 void TrayCast::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
671 if (tray_) 650 if (tray_)
672 tray_->UpdateAlignment(alignment); 651 tray_->UpdateAlignment(alignment);
673 } 652 }
674 653
675 } // namespace ash 654 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/cast/tray_cast.h ('k') | chrome/browser/extensions/api/cast_devices_private/cast_devices_private_api.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698