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/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 24 matching lines...) Expand all Loading... |
35 | 35 |
36 namespace ash { | 36 namespace ash { |
37 | 37 |
38 namespace { | 38 namespace { |
39 | 39 |
40 const int kMaximumStatusStringLength = 100; | 40 const int kMaximumStatusStringLength = 100; |
41 const int kStopButtonRightPadding = 18; | 41 const int kStopButtonRightPadding = 18; |
42 | 42 |
43 // Returns the active CastConfigDelegate instance. | 43 // Returns the active CastConfigDelegate instance. |
44 ash::CastConfigDelegate* GetCastConfigDelegate() { | 44 ash::CastConfigDelegate* GetCastConfigDelegate() { |
| 45 // When shutting down Chrome, there may not be a shell or a delegate instance. |
| 46 if (!ash::Shell::GetInstance() || |
| 47 !ash::Shell::GetInstance()->system_tray_delegate()) { |
| 48 return nullptr; |
| 49 } |
| 50 |
45 return ash::Shell::GetInstance() | 51 return ash::Shell::GetInstance() |
46 ->system_tray_delegate() | 52 ->system_tray_delegate() |
47 ->GetCastConfigDelegate(); | 53 ->GetCastConfigDelegate(); |
48 } | 54 } |
49 | 55 |
50 // Helper method to elide the given string to the maximum length. If a string is | 56 // Helper method to elide the given string to the maximum length. If a string is |
51 // contains user-input and is displayed, we should elide it. | 57 // contains user-input and is displayed, we should elide it. |
52 // TODO(jdufault): This does not properly trim unicode characters. We should | 58 // TODO(jdufault): This does not properly trim unicode characters. We should |
53 // implement this properly by using views::Label::SetElideBehavior(...). See | 59 // implement this properly by using views::Label::SetElideBehavior(...). See |
54 // crbug.com/532496. | 60 // crbug.com/532496. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 // Overridden from views::ButtonListener. | 124 // Overridden from views::ButtonListener. |
119 void ButtonPressed(views::Button* sender, const ui::Event& event) override; | 125 void ButtonPressed(views::Button* sender, const ui::Event& event) override; |
120 | 126 |
121 // The cast activity id that we are displaying. If the user stops a cast, we | 127 // The cast activity id that we are displaying. If the user stops a cast, we |
122 // send this value to the config delegate so that we stop the right cast. | 128 // send this value to the config delegate so that we stop the right cast. |
123 std::string displayed_activity_id_; | 129 std::string displayed_activity_id_; |
124 | 130 |
125 views::ImageView* icon_; | 131 views::ImageView* icon_; |
126 views::Label* label_; | 132 views::Label* label_; |
127 TrayPopupLabelButton* stop_button_; | 133 TrayPopupLabelButton* stop_button_; |
128 base::WeakPtrFactory<CastCastView> weak_ptr_factory_; | |
129 | 134 |
130 DISALLOW_COPY_AND_ASSIGN(CastCastView); | 135 DISALLOW_COPY_AND_ASSIGN(CastCastView); |
131 }; | 136 }; |
132 | 137 |
133 CastCastView::CastCastView() : weak_ptr_factory_(this) { | 138 CastCastView::CastCastView() { |
134 // We will initialize the primary tray view which shows a stop button here. | 139 // We will initialize the primary tray view which shows a stop button here. |
135 | 140 |
136 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); | 141 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); |
137 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 142 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
138 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, | 143 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, |
139 kTrayPopupPaddingHorizontal, 0, | 144 kTrayPopupPaddingHorizontal, 0, |
140 kTrayPopupPaddingBetweenItems)); | 145 kTrayPopupPaddingBetweenItems)); |
141 icon_ = new FixedSizedImageView(0, kTrayPopupItemHeight); | 146 icon_ = new FixedSizedImageView(0, kTrayPopupItemHeight); |
142 icon_->SetImage( | 147 icon_->SetImage( |
143 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia()); | 148 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia()); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 // Overridden from ViewClickListener. | 410 // Overridden from ViewClickListener. |
406 void OnViewClicked(views::View* sender) override; | 411 void OnViewClicked(views::View* sender) override; |
407 | 412 |
408 user::LoginStatus login_; | 413 user::LoginStatus login_; |
409 views::View* options_ = nullptr; | 414 views::View* options_ = nullptr; |
410 // A mapping from the receiver id to the receiver/activity data. | 415 // A mapping from the receiver id to the receiver/activity data. |
411 std::map<std::string, CastConfigDelegate::ReceiverAndActivity> | 416 std::map<std::string, CastConfigDelegate::ReceiverAndActivity> |
412 receivers_and_activities_; | 417 receivers_and_activities_; |
413 // A mapping from the view pointer to the associated activity id. | 418 // A mapping from the view pointer to the associated activity id. |
414 std::map<views::View*, std::string> receiver_activity_map_; | 419 std::map<views::View*, std::string> receiver_activity_map_; |
415 base::WeakPtrFactory<CastDetailedView> weak_ptr_factory_; | |
416 | 420 |
417 DISALLOW_COPY_AND_ASSIGN(CastDetailedView); | 421 DISALLOW_COPY_AND_ASSIGN(CastDetailedView); |
418 }; | 422 }; |
419 | 423 |
420 CastDetailedView::CastDetailedView( | 424 CastDetailedView::CastDetailedView( |
421 SystemTrayItem* owner, | 425 SystemTrayItem* owner, |
422 user::LoginStatus login, | 426 user::LoginStatus login, |
423 const CastConfigDelegate::ReceiversAndActivities& receivers_and_activities) | 427 const CastConfigDelegate::ReceiversAndActivities& receivers_and_activities) |
424 : TrayDetailsView(owner), login_(login), weak_ptr_factory_(this) { | 428 : TrayDetailsView(owner), login_(login) { |
425 CreateItems(); | 429 CreateItems(); |
426 UpdateReceiverList(receivers_and_activities); | 430 UpdateReceiverList(receivers_and_activities); |
427 } | 431 } |
428 | 432 |
429 CastDetailedView::~CastDetailedView() { | 433 CastDetailedView::~CastDetailedView() { |
430 } | 434 } |
431 | 435 |
432 void CastDetailedView::SimulateViewClickedForTest( | 436 void CastDetailedView::SimulateViewClickedForTest( |
433 const std::string& receiver_id) { | 437 const std::string& receiver_id) { |
434 for (auto& it : receiver_activity_map_) { | 438 for (auto& it : receiver_activity_map_) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 if (it != receiver_activity_map_.end()) { | 548 if (it != receiver_activity_map_.end()) { |
545 cast_config_delegate->CastToReceiver(it->second); | 549 cast_config_delegate->CastToReceiver(it->second); |
546 Shell::GetInstance()->metrics()->RecordUserMetricsAction( | 550 Shell::GetInstance()->metrics()->RecordUserMetricsAction( |
547 ash::UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST); | 551 ash::UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST); |
548 } | 552 } |
549 } | 553 } |
550 } | 554 } |
551 | 555 |
552 } // namespace tray | 556 } // namespace tray |
553 | 557 |
554 TrayCast::TrayCast(SystemTray* system_tray) | 558 TrayCast::TrayCast(SystemTray* system_tray) : SystemTrayItem(system_tray) { |
555 : SystemTrayItem(system_tray), | |
556 weak_ptr_factory_(this) { | |
557 Shell::GetInstance()->AddShellObserver(this); | 559 Shell::GetInstance()->AddShellObserver(this); |
558 } | 560 } |
559 | 561 |
560 TrayCast::~TrayCast() { | 562 TrayCast::~TrayCast() { |
561 Shell::GetInstance()->RemoveShellObserver(this); | 563 if (Shell::GetInstance()) |
| 564 Shell::GetInstance()->RemoveShellObserver(this); |
| 565 |
| 566 ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); |
| 567 if (added_observer_ && cast_config_delegate) |
| 568 cast_config_delegate->RemoveObserver(this); |
562 } | 569 } |
563 | 570 |
564 void TrayCast::StartCastForTest(const std::string& receiver_id) { | 571 void TrayCast::StartCastForTest(const std::string& receiver_id) { |
565 if (detailed_ != nullptr) | 572 if (detailed_ != nullptr) |
566 detailed_->SimulateViewClickedForTest(receiver_id); | 573 detailed_->SimulateViewClickedForTest(receiver_id); |
567 } | 574 } |
568 | 575 |
569 void TrayCast::StopCastForTest() { | 576 void TrayCast::StopCastForTest() { |
570 default_->cast_view()->StopCasting(); | 577 default_->cast_view()->StopCasting(); |
571 } | 578 } |
(...skipping 12 matching lines...) Expand all Loading... |
584 tray_->SetVisible(is_casting_); | 591 tray_->SetVisible(is_casting_); |
585 return tray_; | 592 return tray_; |
586 } | 593 } |
587 | 594 |
588 views::View* TrayCast::CreateDefaultView(user::LoginStatus status) { | 595 views::View* TrayCast::CreateDefaultView(user::LoginStatus status) { |
589 CHECK(default_ == nullptr); | 596 CHECK(default_ == nullptr); |
590 | 597 |
591 if (HasCastExtension()) { | 598 if (HasCastExtension()) { |
592 ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); | 599 ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); |
593 | 600 |
594 // We add the cast listener here instead of in the ctor for two reasons: | 601 // Add the cast observer here instead of the ctor for two reasons: |
595 // - The ctor gets called too early in the initialization cycle (at least | 602 // - The ctor gets called too early in the initialization cycle (at least |
596 // for the tests); the correct profile hasn't been setup yet. | 603 // for the tests); the correct profile hasn't been setup yet. |
597 // - The listener is only added if there is a cast extension. If the call | 604 // - If we're using the cast extension backend (media router is disabled), |
598 // below were in the ctor, then the cast tray item would not appear if the | 605 // then the user can install the extension at any point in time. The |
599 // user installed the extension in an existing session. | 606 // return value of HasCastExtension() can change, so only checking it in |
600 if (!device_update_subscription_) { | 607 // the ctor isn't enough. |
601 device_update_subscription_ = | 608 if (!added_observer_) { |
602 cast_config_delegate->RegisterDeviceUpdateObserver(base::Bind( | 609 cast_config_delegate->AddObserver(this); |
603 &TrayCast::OnReceiversUpdated, weak_ptr_factory_.GetWeakPtr())); | 610 added_observer_ = true; |
604 } | 611 } |
605 | 612 |
606 // The extension updates its view model whenever the popup is opened, so we | 613 // The extension updates its view model whenever the popup is opened, so we |
607 // probably should as well. | 614 // probably should as well. |
608 cast_config_delegate->RequestDeviceRefresh(); | 615 cast_config_delegate->RequestDeviceRefresh(); |
609 } | 616 } |
610 | 617 |
611 default_ = new tray::CastDuplexView(this, status != user::LOGGED_IN_LOCKED, | 618 default_ = new tray::CastDuplexView(this, status != user::LOGGED_IN_LOCKED, |
612 receivers_and_activities_); | 619 receivers_and_activities_); |
613 default_->set_id(TRAY_VIEW); | 620 default_->set_id(TRAY_VIEW); |
(...skipping 24 matching lines...) Expand all Loading... |
638 void TrayCast::DestroyDetailedView() { | 645 void TrayCast::DestroyDetailedView() { |
639 detailed_ = nullptr; | 646 detailed_ = nullptr; |
640 } | 647 } |
641 | 648 |
642 bool TrayCast::HasCastExtension() { | 649 bool TrayCast::HasCastExtension() { |
643 ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); | 650 ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); |
644 return cast_config_delegate != nullptr && | 651 return cast_config_delegate != nullptr && |
645 cast_config_delegate->HasCastExtension(); | 652 cast_config_delegate->HasCastExtension(); |
646 } | 653 } |
647 | 654 |
648 void TrayCast::OnReceiversUpdated( | 655 void TrayCast::OnDevicesUpdated( |
649 const CastConfigDelegate::ReceiversAndActivities& receivers_activities) { | 656 const CastConfigDelegate::ReceiversAndActivities& receivers_activities) { |
650 receivers_and_activities_ = receivers_activities; | 657 receivers_and_activities_ = receivers_activities; |
651 | 658 |
652 if (default_) { | 659 if (default_) { |
653 bool has_receivers = !receivers_and_activities_.empty(); | 660 bool has_receivers = !receivers_and_activities_.empty(); |
654 default_->SetVisible(has_receivers); | 661 default_->SetVisible(has_receivers); |
655 default_->cast_view()->UpdateLabel(receivers_and_activities_); | 662 default_->cast_view()->UpdateLabel(receivers_and_activities_); |
656 } | 663 } |
657 if (detailed_) | 664 if (detailed_) |
658 detailed_->UpdateReceiverList(receivers_and_activities_); | 665 detailed_->UpdateReceiverList(receivers_and_activities_); |
(...skipping 22 matching lines...) Expand all Loading... |
681 is_casting_ = started; | 688 is_casting_ = started; |
682 UpdatePrimaryView(); | 689 UpdatePrimaryView(); |
683 } | 690 } |
684 | 691 |
685 void TrayCast::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { | 692 void TrayCast::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { |
686 if (tray_) | 693 if (tray_) |
687 tray_->UpdateAlignment(alignment); | 694 tray_->UpdateAlignment(alignment); |
688 } | 695 } |
689 | 696 |
690 } // namespace ash | 697 } // namespace ash |
OLD | NEW |