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

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

Issue 2109613005: mash: Move system tray cast code into //ash/common (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: forward decl Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/system/cast/tray_cast.h ('k') | ash/system/chromeos/multi_user/user_switch_util.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ash/system/cast/tray_cast.h"
6
7 #include "ash/common/session/session_state_delegate.h"
8 #include "ash/common/shelf/shelf_types.h"
9 #include "ash/common/shelf/wm_shelf_util.h"
10 #include "ash/common/system/tray/fixed_sized_image_view.h"
11 #include "ash/common/system/tray/fixed_sized_scroll_view.h"
12 #include "ash/common/system/tray/hover_highlight_view.h"
13 #include "ash/common/system/tray/system_tray_delegate.h"
14 #include "ash/common/system/tray/throbber_view.h"
15 #include "ash/common/system/tray/tray_constants.h"
16 #include "ash/common/system/tray/tray_details_view.h"
17 #include "ash/common/system/tray/tray_item_more.h"
18 #include "ash/common/system/tray/tray_item_view.h"
19 #include "ash/common/system/tray/tray_popup_label_button.h"
20 #include "ash/common/system/tray/view_click_listener.h"
21 #include "ash/common/wm_shell.h"
22 #include "ash/system/chromeos/screen_security/screen_tray_item.h"
23 #include "ash/system/tray/system_tray.h"
24 #include "base/bind.h"
25 #include "grit/ash_resources.h"
26 #include "grit/ash_strings.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/gfx/image/image.h"
30 #include "ui/gfx/text_elider.h"
31 #include "ui/views/controls/button/button.h"
32 #include "ui/views/controls/image_view.h"
33 #include "ui/views/controls/label.h"
34 #include "ui/views/layout/box_layout.h"
35 #include "ui/views/layout/fill_layout.h"
36
37 namespace ash {
38
39 namespace {
40
41 const size_t kMaximumStatusStringLength = 100;
42 const int kStopButtonRightPadding = 18;
43
44 // Returns the active CastConfigDelegate instance.
45 CastConfigDelegate* GetCastConfigDelegate() {
46 return WmShell::Get()->system_tray_delegate()->GetCastConfigDelegate();
47 }
48
49 // Helper method to elide the given string to the maximum length. If a string is
50 // contains user-input and is displayed, we should elide it.
51 // TODO(jdufault): This does not properly trim unicode characters. We should
52 // implement this properly by using views::Label::SetElideBehavior(...). See
53 // crbug.com/532496.
54 base::string16 ElideString(const base::string16& text) {
55 base::string16 elided;
56 gfx::ElideString(text, kMaximumStatusStringLength, &elided);
57 return elided;
58 }
59
60 } // namespace
61
62 namespace tray {
63
64 // This view is displayed in the system tray when the cast extension is active.
65 // It asks the user if they want to cast the desktop. If they click on the
66 // chevron, then a detail view will replace this view where the user will
67 // actually pick the cast receiver.
68 class CastSelectDefaultView : public TrayItemMore {
69 public:
70 CastSelectDefaultView(SystemTrayItem* owner, bool show_more);
71 ~CastSelectDefaultView() override;
72
73 private:
74 DISALLOW_COPY_AND_ASSIGN(CastSelectDefaultView);
75 };
76
77 CastSelectDefaultView::CastSelectDefaultView(SystemTrayItem* owner,
78 bool show_more)
79 : TrayItemMore(owner, show_more) {
80 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
81
82 // Update the image and label.
83 SetImage(rb.GetImageNamed(IDR_AURA_UBER_TRAY_CAST).ToImageSkia());
84 base::string16 label =
85 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_DESKTOP);
86 SetLabel(label);
87 SetAccessibleName(label);
88 }
89
90 CastSelectDefaultView::~CastSelectDefaultView() {}
91
92 // This view is displayed when the screen is actively being casted; it allows
93 // the user to easily stop casting. It fully replaces the
94 // |CastSelectDefaultView| view inside of the |CastDuplexView|.
95 class CastCastView : public views::View, public views::ButtonListener {
96 public:
97 CastCastView();
98 ~CastCastView() override;
99
100 void StopCasting();
101
102 const std::string& displayed_activity_id() const {
103 return displayed_activity_id_;
104 }
105
106 // Updates the label for the stop view to include information about the
107 // current device that is being casted.
108 void UpdateLabel(
109 const CastConfigDelegate::ReceiversAndActivities& receivers_activities);
110
111 private:
112 // Overridden from views::View.
113 int GetHeightForWidth(int width) const override;
114 void Layout() override;
115
116 // Overridden from views::ButtonListener.
117 void ButtonPressed(views::Button* sender, const ui::Event& event) override;
118
119 // The cast activity id that we are displaying. If the user stops a cast, we
120 // send this value to the config delegate so that we stop the right cast.
121 std::string displayed_activity_id_;
122
123 views::ImageView* icon_;
124 views::Label* label_;
125 TrayPopupLabelButton* stop_button_;
126
127 DISALLOW_COPY_AND_ASSIGN(CastCastView);
128 };
129
130 CastCastView::CastCastView() {
131 // We will initialize the primary tray view which shows a stop button here.
132
133 set_background(views::Background::CreateSolidBackground(kBackgroundColor));
134 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
135 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
136 kTrayPopupPaddingHorizontal, 0,
137 kTrayPopupPaddingBetweenItems));
138 icon_ = new FixedSizedImageView(0, kTrayPopupItemHeight);
139 icon_->SetImage(
140 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia());
141 AddChildView(icon_);
142
143 // The label which describes both what we are casting (ie, the desktop) and
144 // where we are casting it to.
145 label_ = new views::Label;
146 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
147 label_->SetMultiLine(true);
148 label_->SetText(
149 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN));
150 AddChildView(label_);
151
152 // Add the stop bottom on the far-right. We customize how this stop button is
153 // displayed inside of |Layout()|.
154 base::string16 stop_button_text =
155 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
156 IDS_ASH_STATUS_TRAY_CAST_STOP);
157 stop_button_ = new TrayPopupLabelButton(this, stop_button_text);
158 AddChildView(stop_button_);
159 }
160
161 CastCastView::~CastCastView() {}
162
163 int CastCastView::GetHeightForWidth(int width) const {
164 // We are reusing the cached label_->bounds() calculation which was
165 // done inside of Layout(). Due to the way this object is initialized,
166 // Layout() will always get initially invoked with the dummy text
167 // (which will compute the proper label width) and then when we know
168 // the cast receiver we will update the label text, which will cause
169 // this method to get invoked.
170 return std::max(views::View::GetHeightForWidth(width),
171 kTrayPopupPaddingBetweenItems * 2 +
172 label_->GetHeightForWidth(label_->bounds().width()));
173 }
174
175 void CastCastView::Layout() {
176 views::View::Layout();
177
178 // Give the stop button the space it requests.
179 gfx::Size stop_size = stop_button_->GetPreferredSize();
180 gfx::Rect stop_bounds(stop_size);
181 stop_bounds.set_x(width() - stop_size.width() - kStopButtonRightPadding);
182 stop_bounds.set_y((height() - stop_size.height()) / 2);
183 stop_button_->SetBoundsRect(stop_bounds);
184
185 // Adjust the label's bounds in case it got cut off by |stop_button_|.
186 if (label_->bounds().Intersects(stop_button_->bounds())) {
187 gfx::Rect label_bounds = label_->bounds();
188 label_bounds.set_width(stop_button_->x() - kTrayPopupPaddingBetweenItems -
189 label_->x());
190 label_->SetBoundsRect(label_bounds);
191 }
192 }
193
194 void CastCastView::StopCasting() {
195 GetCastConfigDelegate()->StopCasting(displayed_activity_id_);
196 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_CAST_STOP_CAST);
197 }
198
199 void CastCastView::UpdateLabel(
200 const CastConfigDelegate::ReceiversAndActivities& receivers_activities) {
201 for (auto& i : receivers_activities) {
202 const CastConfigDelegate::Receiver& receiver = i.receiver;
203 const CastConfigDelegate::Activity& activity = i.activity;
204
205 if (!activity.id.empty()) {
206 displayed_activity_id_ = activity.id;
207
208 // We want to display different labels inside of the title depending on
209 // what we are actually casting - either the desktop, a tab, or a fallback
210 // that catches everything else (ie, an extension tab).
211 if (activity.tab_id == CastConfigDelegate::Activity::TabId::DESKTOP) {
212 label_->SetText(ElideString(l10n_util::GetStringFUTF16(
213 IDS_ASH_STATUS_TRAY_CAST_CAST_DESKTOP, receiver.name)));
214 } else if (activity.tab_id >= 0) {
215 label_->SetText(ElideString(l10n_util::GetStringFUTF16(
216 IDS_ASH_STATUS_TRAY_CAST_CAST_TAB, activity.title, receiver.name)));
217 } else {
218 label_->SetText(
219 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN));
220 }
221
222 PreferredSizeChanged();
223 Layout();
224
225 // If this machine is the source of the activity, then we want to display
226 // it over any other activity. There can be multiple activities if other
227 // devices on the network are casting at the same time.
228 if (activity.is_local_source)
229 break;
230 }
231 }
232 }
233
234 void CastCastView::ButtonPressed(views::Button* sender,
235 const ui::Event& event) {
236 DCHECK(sender == stop_button_);
237 StopCasting();
238 }
239
240 // This view by itself does very little. It acts as a front-end for managing
241 // which of the two child views (|CastSelectDefaultView| and |CastCastView|)
242 // is active.
243 class CastDuplexView : public views::View {
244 public:
245 CastDuplexView(
246 SystemTrayItem* owner,
247 bool show_more,
248 const CastConfigDelegate::ReceiversAndActivities& receivers_activities);
249 ~CastDuplexView() override;
250
251 // Activate either the casting or select view.
252 void ActivateCastView();
253 void ActivateSelectView();
254
255 CastSelectDefaultView* select_view() { return select_view_; }
256 CastCastView* cast_view() { return cast_view_; }
257
258 private:
259 // Overridden from views::View.
260 void ChildPreferredSizeChanged(views::View* child) override;
261 void Layout() override;
262
263 // Only one of |select_view_| or |cast_view_| will be displayed at any given
264 // time. This will return the view is being displayed.
265 views::View* ActiveChildView();
266
267 CastSelectDefaultView* select_view_;
268 CastCastView* cast_view_;
269
270 DISALLOW_COPY_AND_ASSIGN(CastDuplexView);
271 };
272
273 CastDuplexView::CastDuplexView(
274 SystemTrayItem* owner,
275 bool show_more,
276 const CastConfigDelegate::ReceiversAndActivities& receivers_activities) {
277 select_view_ = new CastSelectDefaultView(owner, show_more);
278 cast_view_ = new CastCastView();
279 cast_view_->UpdateLabel(receivers_activities);
280 SetLayoutManager(new views::FillLayout());
281
282 ActivateSelectView();
283 }
284
285 CastDuplexView::~CastDuplexView() {
286 RemoveChildView(ActiveChildView());
287 delete select_view_;
288 delete cast_view_;
289 }
290
291 void CastDuplexView::ActivateCastView() {
292 if (ActiveChildView() == cast_view_)
293 return;
294
295 RemoveChildView(select_view_);
296 AddChildView(cast_view_);
297 InvalidateLayout();
298 }
299
300 void CastDuplexView::ActivateSelectView() {
301 if (ActiveChildView() == select_view_)
302 return;
303
304 RemoveChildView(cast_view_);
305 AddChildView(select_view_);
306 InvalidateLayout();
307 }
308
309 void CastDuplexView::ChildPreferredSizeChanged(views::View* child) {
310 PreferredSizeChanged();
311 }
312
313 void CastDuplexView::Layout() {
314 views::View::Layout();
315
316 select_view_->SetBoundsRect(GetContentsBounds());
317 cast_view_->SetBoundsRect(GetContentsBounds());
318 }
319
320 views::View* CastDuplexView::ActiveChildView() {
321 if (cast_view_->parent() == this)
322 return cast_view_;
323 if (select_view_->parent() == this)
324 return select_view_;
325 return nullptr;
326 }
327
328 // Exposes an icon in the tray. |TrayCast| manages the visiblity of this.
329 class CastTrayView : public TrayItemView {
330 public:
331 explicit CastTrayView(SystemTrayItem* tray_item);
332 ~CastTrayView() override;
333
334 // Called when the tray alignment changes so that the icon can recenter
335 // itself.
336 void UpdateAlignment(ShelfAlignment alignment);
337
338 private:
339 DISALLOW_COPY_AND_ASSIGN(CastTrayView);
340 };
341
342 CastTrayView::CastTrayView(SystemTrayItem* tray_item)
343 : TrayItemView(tray_item) {
344 CreateImageView();
345
346 image_view()->SetImage(ui::ResourceBundle::GetSharedInstance()
347 .GetImageNamed(IDR_AURA_UBER_TRAY_SCREENSHARE)
348 .ToImageSkia());
349 }
350
351 CastTrayView::~CastTrayView() {}
352
353 void CastTrayView::UpdateAlignment(ShelfAlignment alignment) {
354 // Center the item dependent on the orientation of the shelf.
355 views::BoxLayout::Orientation layout = IsHorizontalAlignment(alignment)
356 ? views::BoxLayout::kVertical
357 : views::BoxLayout::kHorizontal;
358 SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0));
359 Layout();
360 }
361
362 // This view displays a list of cast receivers that can be clicked on and casted
363 // to. It is activated by clicking on the chevron inside of
364 // |CastSelectDefaultView|.
365 class CastDetailedView : public TrayDetailsView, public ViewClickListener {
366 public:
367 CastDetailedView(SystemTrayItem* owner,
368 LoginStatus login,
369 const CastConfigDelegate::ReceiversAndActivities&
370 receivers_and_activities);
371 ~CastDetailedView() override;
372
373 // Makes the detail view think the view associated with the given receiver_id
374 // was clicked. This will start a cast.
375 void SimulateViewClickedForTest(const std::string& receiver_id);
376
377 // Updates the list of available receivers.
378 void UpdateReceiverList(const CastConfigDelegate::ReceiversAndActivities&
379 new_receivers_and_activities);
380
381 private:
382 void CreateItems();
383
384 void UpdateReceiverListFromCachedData();
385 views::View* AddToReceiverList(
386 const CastConfigDelegate::ReceiverAndActivity& receiverActivity);
387
388 void AppendSettingsEntries();
389 void AppendHeaderEntry();
390
391 // Overridden from ViewClickListener.
392 void OnViewClicked(views::View* sender) override;
393
394 LoginStatus login_;
395 views::View* options_ = nullptr;
396 // A mapping from the receiver id to the receiver/activity data.
397 std::map<std::string, CastConfigDelegate::ReceiverAndActivity>
398 receivers_and_activities_;
399 // A mapping from the view pointer to the associated activity id.
400 std::map<views::View*, std::string> receiver_activity_map_;
401
402 DISALLOW_COPY_AND_ASSIGN(CastDetailedView);
403 };
404
405 CastDetailedView::CastDetailedView(
406 SystemTrayItem* owner,
407 LoginStatus login,
408 const CastConfigDelegate::ReceiversAndActivities& receivers_and_activities)
409 : TrayDetailsView(owner), login_(login) {
410 CreateItems();
411 UpdateReceiverList(receivers_and_activities);
412 }
413
414 CastDetailedView::~CastDetailedView() {}
415
416 void CastDetailedView::SimulateViewClickedForTest(
417 const std::string& receiver_id) {
418 for (auto& it : receiver_activity_map_) {
419 if (it.second == receiver_id) {
420 OnViewClicked(it.first);
421 break;
422 }
423 }
424 }
425
426 void CastDetailedView::CreateItems() {
427 CreateScrollableList();
428 if (GetCastConfigDelegate()->HasOptions())
429 AppendSettingsEntries();
430 AppendHeaderEntry();
431 }
432
433 void CastDetailedView::UpdateReceiverList(
434 const CastConfigDelegate::ReceiversAndActivities&
435 new_receivers_and_activities) {
436 // Add/update existing.
437 for (auto i = new_receivers_and_activities.begin();
438 i != new_receivers_and_activities.end(); ++i) {
439 receivers_and_activities_[i->receiver.id] = *i;
440 }
441
442 // Remove non-existent receivers. Removing an element invalidates all existing
443 // iterators.
444 auto i = receivers_and_activities_.begin();
445 while (i != receivers_and_activities_.end()) {
446 bool has_receiver = false;
447 for (auto receiver : new_receivers_and_activities) {
448 if (i->first == receiver.receiver.id)
449 has_receiver = true;
450 }
451
452 if (has_receiver)
453 ++i;
454 else
455 i = receivers_and_activities_.erase(i);
456 }
457
458 // Update UI.
459 UpdateReceiverListFromCachedData();
460 Layout();
461 }
462
463 void CastDetailedView::UpdateReceiverListFromCachedData() {
464 // Remove all of the existing views.
465 receiver_activity_map_.clear();
466 scroll_content()->RemoveAllChildViews(true);
467
468 // Add a view for each receiver.
469 for (auto& it : receivers_and_activities_) {
470 const CastConfigDelegate::ReceiverAndActivity& receiver_activity =
471 it.second;
472 views::View* container = AddToReceiverList(receiver_activity);
473 receiver_activity_map_[container] = it.first;
474 }
475
476 scroll_content()->SizeToPreferredSize();
477 static_cast<views::View*>(scroller())->Layout();
478 }
479
480 views::View* CastDetailedView::AddToReceiverList(
481 const CastConfigDelegate::ReceiverAndActivity& receiverActivity) {
482 HoverHighlightView* container = new HoverHighlightView(this);
483
484 const gfx::ImageSkia* image =
485 ui::ResourceBundle::GetSharedInstance()
486 .GetImageNamed(IDR_AURA_UBER_TRAY_CAST_DEVICE_ICON)
487 .ToImageSkia();
488 const base::string16& name = receiverActivity.receiver.name;
489 container->AddIndentedIconAndLabel(*image, name, false);
490
491 scroll_content()->AddChildView(container);
492 return container;
493 }
494
495 void CastDetailedView::AppendSettingsEntries() {
496 // Settings requires a browser window, hide it for non logged in user.
497 if (login_ == LoginStatus::NOT_LOGGED_IN || login_ == LoginStatus::LOCKED ||
498 WmShell::Get()->GetSessionStateDelegate()->IsInSecondaryLoginScreen()) {
499 return;
500 }
501
502 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
503 HoverHighlightView* container = new HoverHighlightView(this);
504 container->AddLabel(rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_OPTIONS),
505 gfx::ALIGN_LEFT, false /* highlight */);
506
507 AddChildView(container);
508 options_ = container;
509 }
510
511 void CastDetailedView::AppendHeaderEntry() {
512 CreateSpecialRow(IDS_ASH_STATUS_TRAY_CAST, this);
513 }
514
515 void CastDetailedView::OnViewClicked(views::View* sender) {
516 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
517
518 if (sender == footer()->content()) {
519 TransitionToDefaultView();
520 } else if (sender == options_) {
521 cast_config_delegate->LaunchCastOptions();
522 } else {
523 // Find the receiver we are going to cast to
524 auto it = receiver_activity_map_.find(sender);
525 if (it != receiver_activity_map_.end()) {
526 cast_config_delegate->CastToReceiver(it->second);
527 WmShell::Get()->RecordUserMetricsAction(
528 UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST);
529 }
530 }
531 }
532
533 } // namespace tray
534
535 TrayCast::TrayCast(SystemTray* system_tray) : SystemTrayItem(system_tray) {
536 WmShell::Get()->AddShellObserver(this);
537 }
538
539 TrayCast::~TrayCast() {
540 WmShell::Get()->RemoveShellObserver(this);
541 if (added_observer_)
542 GetCastConfigDelegate()->RemoveObserver(this);
543 }
544
545 void TrayCast::StartCastForTest(const std::string& receiver_id) {
546 if (detailed_ != nullptr)
547 detailed_->SimulateViewClickedForTest(receiver_id);
548 }
549
550 void TrayCast::StopCastForTest() {
551 default_->cast_view()->StopCasting();
552 }
553
554 const std::string& TrayCast::GetDisplayedCastId() {
555 return default_->cast_view()->displayed_activity_id();
556 }
557
558 const views::View* TrayCast::GetDefaultView() const {
559 return default_;
560 }
561
562 views::View* TrayCast::CreateTrayView(LoginStatus status) {
563 CHECK(tray_ == nullptr);
564 tray_ = new tray::CastTrayView(this);
565 tray_->SetVisible(is_casting_);
566 return tray_;
567 }
568
569 views::View* TrayCast::CreateDefaultView(LoginStatus status) {
570 CHECK(default_ == nullptr);
571
572 if (HasCastExtension()) {
573 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
574
575 // Add the cast observer here instead of the ctor for two reasons:
576 // - The ctor gets called too early in the initialization cycle (at least
577 // for the tests); the correct profile hasn't been setup yet.
578 // - If we're using the cast extension backend (media router is disabled),
579 // then the user can install the extension at any point in time. The
580 // return value of HasCastExtension() can change, so only checking it in
581 // the ctor isn't enough.
582 if (!added_observer_) {
583 cast_config_delegate->AddObserver(this);
584 added_observer_ = true;
585 }
586
587 // The extension updates its view model whenever the popup is opened, so we
588 // probably should as well.
589 cast_config_delegate->RequestDeviceRefresh();
590 }
591
592 default_ = new tray::CastDuplexView(this, status != LoginStatus::LOCKED,
593 receivers_and_activities_);
594 default_->set_id(TRAY_VIEW);
595 default_->select_view()->set_id(SELECT_VIEW);
596 default_->cast_view()->set_id(CAST_VIEW);
597
598 UpdatePrimaryView();
599 return default_;
600 }
601
602 views::View* TrayCast::CreateDetailedView(LoginStatus status) {
603 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_DETAILED_CAST_VIEW);
604 CHECK(detailed_ == nullptr);
605 detailed_ =
606 new tray::CastDetailedView(this, status, receivers_and_activities_);
607 return detailed_;
608 }
609
610 void TrayCast::DestroyTrayView() {
611 tray_ = nullptr;
612 }
613
614 void TrayCast::DestroyDefaultView() {
615 default_ = nullptr;
616 }
617
618 void TrayCast::DestroyDetailedView() {
619 detailed_ = nullptr;
620 }
621
622 bool TrayCast::HasCastExtension() {
623 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
624 return cast_config_delegate != nullptr &&
625 cast_config_delegate->HasCastExtension();
626 }
627
628 void TrayCast::OnDevicesUpdated(
629 const CastConfigDelegate::ReceiversAndActivities& receivers_activities) {
630 receivers_and_activities_ = receivers_activities;
631
632 if (default_) {
633 bool has_receivers = !receivers_and_activities_.empty();
634 default_->SetVisible(has_receivers);
635 default_->cast_view()->UpdateLabel(receivers_and_activities_);
636 }
637 if (detailed_)
638 detailed_->UpdateReceiverList(receivers_and_activities_);
639 }
640
641 void TrayCast::UpdatePrimaryView() {
642 if (HasCastExtension() && !receivers_and_activities_.empty()) {
643 if (default_) {
644 if (is_casting_)
645 default_->ActivateCastView();
646 else
647 default_->ActivateSelectView();
648 }
649
650 if (tray_)
651 tray_->SetVisible(is_casting_);
652 } else {
653 if (default_)
654 default_->SetVisible(false);
655 if (tray_)
656 tray_->SetVisible(false);
657 }
658 }
659
660 void TrayCast::OnCastingSessionStartedOrStopped(bool started) {
661 is_casting_ = started;
662 UpdatePrimaryView();
663 }
664
665 void TrayCast::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
666 if (tray_)
667 tray_->UpdateAlignment(alignment);
668 }
669
670 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/cast/tray_cast.h ('k') | ash/system/chromeos/multi_user/user_switch_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698