Index: ash/system/cast/tray_cast.cc |
diff --git a/ash/system/cast/tray_cast.cc b/ash/system/cast/tray_cast.cc |
index b155c680c9aca0ad0ff5954ee4b2c05002a0ca98..7c744851b2fc674ce42b320db9573db969ff03bd 100644 |
--- a/ash/system/cast/tray_cast.cc |
+++ b/ash/system/cast/tray_cast.cc |
@@ -42,6 +42,12 @@ const int kStopButtonRightPadding = 18; |
// Returns the active CastConfigDelegate instance. |
ash::CastConfigDelegate* GetCastConfigDelegate() { |
+ // When shutting down Chrome, there may not be a shell or a delegate instance. |
+ if (!ash::Shell::GetInstance() || |
+ !ash::Shell::GetInstance()->system_tray_delegate()) { |
+ return nullptr; |
+ } |
+ |
return ash::Shell::GetInstance() |
->system_tray_delegate() |
->GetCastConfigDelegate(); |
@@ -125,12 +131,11 @@ class CastCastView : public views::View, public views::ButtonListener { |
views::ImageView* icon_; |
views::Label* label_; |
TrayPopupLabelButton* stop_button_; |
- base::WeakPtrFactory<CastCastView> weak_ptr_factory_; |
DISALLOW_COPY_AND_ASSIGN(CastCastView); |
}; |
-CastCastView::CastCastView() : weak_ptr_factory_(this) { |
+CastCastView::CastCastView() { |
// We will initialize the primary tray view which shows a stop button here. |
set_background(views::Background::CreateSolidBackground(kBackgroundColor)); |
@@ -412,7 +417,6 @@ class CastDetailedView : public TrayDetailsView, public ViewClickListener { |
receivers_and_activities_; |
// A mapping from the view pointer to the associated activity id. |
std::map<views::View*, std::string> receiver_activity_map_; |
- base::WeakPtrFactory<CastDetailedView> weak_ptr_factory_; |
DISALLOW_COPY_AND_ASSIGN(CastDetailedView); |
}; |
@@ -421,7 +425,7 @@ CastDetailedView::CastDetailedView( |
SystemTrayItem* owner, |
user::LoginStatus login, |
const CastConfigDelegate::ReceiversAndActivities& receivers_and_activities) |
- : TrayDetailsView(owner), login_(login), weak_ptr_factory_(this) { |
+ : TrayDetailsView(owner), login_(login) { |
CreateItems(); |
UpdateReceiverList(receivers_and_activities); |
} |
@@ -551,14 +555,19 @@ void CastDetailedView::OnViewClicked(views::View* sender) { |
} // namespace tray |
-TrayCast::TrayCast(SystemTray* system_tray) |
- : SystemTrayItem(system_tray), |
- weak_ptr_factory_(this) { |
+TrayCast::TrayCast(SystemTray* system_tray) : SystemTrayItem(system_tray) { |
Shell::GetInstance()->AddShellObserver(this); |
} |
TrayCast::~TrayCast() { |
- Shell::GetInstance()->RemoveShellObserver(this); |
+ // TODO(jdufault): Remove these if checks (and the ones in |
+ // GetCastConfigDelegate) by fixing deinit order. See crbug.com/577413. |
+ if (Shell::GetInstance()) |
+ Shell::GetInstance()->RemoveShellObserver(this); |
+ |
+ ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); |
+ if (added_observer_ && cast_config_delegate) |
+ cast_config_delegate->RemoveObserver(this); |
} |
void TrayCast::StartCastForTest(const std::string& receiver_id) { |
@@ -591,16 +600,16 @@ views::View* TrayCast::CreateDefaultView(user::LoginStatus status) { |
if (HasCastExtension()) { |
ash::CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate(); |
- // We add the cast listener here instead of in the ctor for two reasons: |
+ // Add the cast observer here instead of the ctor for two reasons: |
// - The ctor gets called too early in the initialization cycle (at least |
// for the tests); the correct profile hasn't been setup yet. |
- // - The listener is only added if there is a cast extension. If the call |
- // below were in the ctor, then the cast tray item would not appear if the |
- // user installed the extension in an existing session. |
- if (!device_update_subscription_) { |
- device_update_subscription_ = |
- cast_config_delegate->RegisterDeviceUpdateObserver(base::Bind( |
- &TrayCast::OnReceiversUpdated, weak_ptr_factory_.GetWeakPtr())); |
+ // - If we're using the cast extension backend (media router is disabled), |
+ // then the user can install the extension at any point in time. The |
+ // return value of HasCastExtension() can change, so only checking it in |
+ // the ctor isn't enough. |
+ if (!added_observer_) { |
+ cast_config_delegate->AddObserver(this); |
+ added_observer_ = true; |
} |
// The extension updates its view model whenever the popup is opened, so we |
@@ -645,7 +654,7 @@ bool TrayCast::HasCastExtension() { |
cast_config_delegate->HasCastExtension(); |
} |
-void TrayCast::OnReceiversUpdated( |
+void TrayCast::OnDevicesUpdated( |
const CastConfigDelegate::ReceiversAndActivities& receivers_activities) { |
receivers_and_activities_ = receivers_activities; |