| Index: chrome/browser/ui/toolbar/media_router_action.cc
|
| diff --git a/chrome/browser/ui/toolbar/media_router_action.cc b/chrome/browser/ui/toolbar/media_router_action.cc
|
| index 97c60b2a4d4204916f94fb4734162b036ff85d49..b49f18f73bc356d0dfe87e7691ac3942a0351ce0 100644
|
| --- a/chrome/browser/ui/toolbar/media_router_action.cc
|
| +++ b/chrome/browser/ui/toolbar/media_router_action.cc
|
| @@ -17,8 +17,13 @@
|
| #include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
|
| #include "chrome/browser/ui/toolbar/media_router_action_platform_delegate.h"
|
| #include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
|
| +#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
|
| #include "chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.h"
|
| +#include "chrome/common/pref_names.h"
|
| #include "chrome/grit/generated_resources.h"
|
| +#include "components/prefs/pref_service.h"
|
| +#include "components/prefs/pref_service_factory.h"
|
| +#include "grit/theme_resources.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| #include "ui/gfx/color_palette.h"
|
| #include "ui/gfx/image/image_skia.h"
|
| @@ -41,17 +46,19 @@ MediaRouterAction::MediaRouterAction(Browser* browser,
|
| media_router::MediaRoutesObserver(GetMediaRouter(browser)),
|
| current_icon_(gfx::VectorIconId::MEDIA_ROUTER_IDLE),
|
| has_local_display_route_(false),
|
| + has_dialog_(false),
|
| delegate_(nullptr),
|
| browser_(browser),
|
| toolbar_actions_bar_(toolbar_actions_bar),
|
| platform_delegate_(MediaRouterActionPlatformDelegate::Create(browser)),
|
| - contextual_menu_(browser),
|
| + contextual_menu_(browser, this),
|
| tab_strip_model_observer_(this),
|
| + toolbar_actions_bar_observer_(this),
|
| weak_ptr_factory_(this) {
|
| DCHECK(browser_);
|
| DCHECK(toolbar_actions_bar_);
|
| tab_strip_model_observer_.Add(browser_->tab_strip_model());
|
| -
|
| + toolbar_actions_bar_observer_.Add(toolbar_actions_bar_);
|
| RegisterObserver();
|
| }
|
|
|
| @@ -66,13 +73,13 @@ std::string MediaRouterAction::GetId() const {
|
| void MediaRouterAction::SetDelegate(ToolbarActionViewDelegate* delegate) {
|
| delegate_ = delegate;
|
|
|
| - // Updates the current popup state if |delegate_| is non-null and has
|
| + // Updates the current dialog state if |delegate_| is non-null and has
|
| // WebContents ready.
|
| // In cases such as opening a new browser window, SetDelegate() will be
|
| - // called before the WebContents is set. In those cases, we update the popup
|
| + // called before the WebContents is set. In those cases, we update the dialog
|
| // state when ActiveTabChanged() is called.
|
| if (delegate_ && delegate_->GetCurrentWebContents())
|
| - UpdatePopupState();
|
| + UpdateDialogState();
|
| }
|
|
|
| gfx::Image MediaRouterAction::GetIcon(content::WebContents* web_contents,
|
| @@ -113,7 +120,6 @@ bool MediaRouterAction::HasPopup(
|
|
|
| void MediaRouterAction::HidePopup() {
|
| GetMediaRouterDialogController()->HideMediaRouterDialog();
|
| - OnPopupHidden();
|
| }
|
|
|
| gfx::NativeView MediaRouterAction::GetPopupNativeView() {
|
| @@ -143,8 +149,8 @@ bool MediaRouterAction::ExecuteAction(bool by_user) {
|
| }
|
|
|
| void MediaRouterAction::UpdateState() {
|
| - if (delegate_)
|
| - delegate_->UpdateState();
|
| + DCHECK(delegate_);
|
| + delegate_->UpdateState();
|
| }
|
|
|
| bool MediaRouterAction::DisabledClickOpensMenu() const {
|
| @@ -166,48 +172,70 @@ void MediaRouterAction::OnRoutesUpdated(
|
| return route.is_local() && route.for_display();
|
| }) != routes.end();
|
| MaybeUpdateIcon();
|
| + MaybeRemoveAction();
|
| }
|
|
|
| void MediaRouterAction::ActiveTabChanged(content::WebContents* old_contents,
|
| content::WebContents* new_contents,
|
| int index,
|
| int reason) {
|
| - UpdatePopupState();
|
| + UpdateDialogState();
|
| + MaybeRemoveAction();
|
| +}
|
| +
|
| +void MediaRouterAction::OnToolbarActionsBarAnimationEnded() {
|
| + // Depress the action if the dialog is shown, release it otherwise.
|
| + DCHECK(delegate_);
|
| + if (GetMediaRouterDialogController()->IsShowingMediaRouterDialog())
|
| + OnDialogShown();
|
| }
|
|
|
| -void MediaRouterAction::OnPopupHidden() {
|
| - if (delegate_)
|
| +void MediaRouterAction::OnDialogHidden() {
|
| + if (has_dialog_) {
|
| + has_dialog_ = false;
|
| + DCHECK(delegate_);
|
| delegate_->OnPopupClosed();
|
| + }
|
| }
|
|
|
| -void MediaRouterAction::OnPopupShown() {
|
| - // We depress the action regardless of whether ExecuteAction() was user
|
| - // initiated.
|
| - if (delegate_)
|
| +void MediaRouterAction::OnDialogShown() {
|
| + if (!has_dialog_) {
|
| + has_dialog_ = true;
|
| + DCHECK(delegate_);
|
| + // We depress the action regardless of whether ExecuteAction() was user
|
| + // initiated.
|
| delegate_->OnPopupShown(true);
|
| + }
|
| +}
|
| +
|
| +void MediaRouterAction::ToggleVisibilityPreference() {
|
| + browser_->profile()->GetPrefs()->SetBoolean(
|
| + prefs::kMediaRouterAlwaysShowActionIcon, !ShouldAlwaysShowIcon());
|
| + MaybeRemoveAction();
|
| }
|
|
|
| -void MediaRouterAction::UpdatePopupState() {
|
| +void MediaRouterAction::UpdateDialogState() {
|
| MediaRouterDialogControllerImpl* controller =
|
| GetMediaRouterDialogController();
|
|
|
| if (!controller)
|
| return;
|
|
|
| - // When each browser window is created, its toolbar creates a
|
| - // MediaRouterAction that is only destroyed when the browser window is torn
|
| - // down. |controller| will keep track of that instance. If |this| was created
|
| - // in overflow mode, it will be destroyed when the overflow menu is closed.
|
| - // If SetMediaRouterAction() was previously called, this is a no-op.
|
| + // |controller| keeps track of |this| if |this| was created with the browser
|
| + // window or ephemerally by activating the Cast functionality. If |this| was
|
| + // created in overflow mode, it will be destroyed when the overflow menu is
|
| + // closed. If SetMediaRouterAction() was previously called, this is a no-op.
|
| if (!toolbar_actions_bar_->in_overflow_mode())
|
| controller->SetMediaRouterAction(weak_ptr_factory_.GetWeakPtr());
|
|
|
| // Update the button in case the pressed state is out of sync with dialog
|
| - // visibility.
|
| - if (controller->IsShowingMediaRouterDialog())
|
| - OnPopupShown();
|
| - else
|
| - OnPopupHidden();
|
| + // visibility. If we just added the ephemeral icon to the toolbar and need to
|
| + // depress it, we do that in |OnToolbarActionsBarAnimationEnded|.
|
| + DCHECK(delegate_);
|
| + if (ShouldAlwaysShowIcon() && controller->IsShowingMediaRouterDialog())
|
| + OnDialogShown();
|
| + else if (!controller->IsShowingMediaRouterDialog())
|
| + OnDialogHidden();
|
| }
|
|
|
| MediaRouterDialogControllerImpl*
|
| @@ -232,11 +260,25 @@ void MediaRouterAction::MaybeUpdateIcon() {
|
|
|
| // Tell the associated view to update its icon to reflect the change made
|
| // above.
|
| - if (delegate_)
|
| - delegate_->UpdateState();
|
| + UpdateState();
|
| + }
|
| +}
|
| +
|
| +void MediaRouterAction::MaybeRemoveAction() {
|
| + if (!ShouldAlwaysShowIcon() &&
|
| + !GetMediaRouterDialogController()->IsShowingMediaRouterDialog() &&
|
| + !has_local_display_route_) {
|
| + // Warning: |this| can be deleted here.
|
| + ToolbarActionsModel::Get(browser_->profile())
|
| + ->RemoveComponentAction(GetId());
|
| }
|
| }
|
|
|
| +bool MediaRouterAction::ShouldAlwaysShowIcon() {
|
| + PrefService* pref_service = browser_->profile()->GetPrefs();
|
| + return pref_service->GetBoolean(prefs::kMediaRouterAlwaysShowActionIcon);
|
| +}
|
| +
|
| gfx::VectorIconId MediaRouterAction::GetCurrentIcon() const {
|
| // Highest priority is to indicate whether there's an issue.
|
| if (issue_) {
|
| @@ -249,3 +291,7 @@ gfx::VectorIconId MediaRouterAction::GetCurrentIcon() const {
|
| return has_local_display_route_ ? gfx::VectorIconId::MEDIA_ROUTER_ACTIVE
|
| : gfx::VectorIconId::MEDIA_ROUTER_IDLE;
|
| }
|
| +
|
| +base::WeakPtr<MediaRouterAction> MediaRouterAction::GetWeakPtr() {
|
| + return weak_ptr_factory_.GetWeakPtr();
|
| +}
|
|
|