blob: cda871f5aaf799604fb64deb29aa98adee84b08e [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/toolbar/media_router_action_controller.h"
#include "base/bind.h"
#include "base/task/post_task.h"
#include "chrome/browser/media/router/media_router.h"
#include "chrome/browser/media/router/media_router_factory.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_task_traits.h"
MediaRouterActionController::MediaRouterActionController(Profile* profile)
: MediaRouterActionController(
profile,
media_router::MediaRouterFactory::GetApiForBrowserContext(profile)) {}
MediaRouterActionController::~MediaRouterActionController() {
DCHECK_EQ(dialog_count_, 0u);
}
// static
bool MediaRouterActionController::IsActionShownByPolicy(Profile* profile) {
CHECK(profile);
const PrefService::Preference* pref =
profile->GetPrefs()->FindPreference(prefs::kShowCastIconInToolbar);
bool show = false;
if (pref->IsManaged())
pref->GetValue()->GetAsBoolean(&show);
return show;
}
// static
bool MediaRouterActionController::GetAlwaysShowActionPref(Profile* profile) {
CHECK(profile);
return profile->GetPrefs()->GetBoolean(prefs::kShowCastIconInToolbar);
}
// static
void MediaRouterActionController::SetAlwaysShowActionPref(Profile* profile,
bool always_show) {
CHECK(profile);
profile->GetPrefs()->SetBoolean(prefs::kShowCastIconInToolbar, always_show);
}
void MediaRouterActionController::OnIssue(const media_router::Issue& issue) {
has_issue_ = true;
MaybeAddOrRemoveAction();
}
void MediaRouterActionController::OnIssuesCleared() {
has_issue_ = false;
MaybeAddOrRemoveAction();
}
void MediaRouterActionController::OnRoutesUpdated(
const std::vector<media_router::MediaRoute>& routes,
const std::vector<media_router::MediaRoute::Id>& joinable_route_ids) {
has_local_display_route_ =
std::find_if(routes.begin(), routes.end(),
[](const media_router::MediaRoute& route) {
return route.is_local() && route.for_display();
}) != routes.end();
MaybeAddOrRemoveAction();
}
void MediaRouterActionController::OnDialogShown() {
dialog_count_++;
MaybeAddOrRemoveAction();
for (Observer& observer : observers_)
observer.ActivateIcon();
}
void MediaRouterActionController::OnDialogHidden() {
DCHECK_GT(dialog_count_, 0u);
if (dialog_count_)
dialog_count_--;
if (dialog_count_ == 0) {
for (Observer& observer : observers_)
observer.DeactivateIcon();
// Call MaybeAddOrRemoveAction() asynchronously, so that the action icon
// doesn't get hidden until we have a chance to show a context menu.
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&MediaRouterActionController::MaybeAddOrRemoveAction,
weak_factory_.GetWeakPtr()));
}
}
void MediaRouterActionController::OnContextMenuShown() {
DCHECK(!context_menu_shown_);
context_menu_shown_ = true;
// If the context menu was shown, right mouse button must have been released.
keep_visible_for_right_mouse_button_ = false;
MaybeAddOrRemoveAction();
}
void MediaRouterActionController::OnContextMenuHidden() {
DCHECK(context_menu_shown_);
context_menu_shown_ = false;
MaybeAddOrRemoveAction();
}
void MediaRouterActionController::KeepIconOnRightMousePressed() {
DCHECK(!keep_visible_for_right_mouse_button_);
keep_visible_for_right_mouse_button_ = true;
}
void MediaRouterActionController::MaybeHideIconOnRightMouseReleased() {
keep_visible_for_right_mouse_button_ = false;
MaybeAddOrRemoveAction();
}
void MediaRouterActionController::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void MediaRouterActionController::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
bool MediaRouterActionController::ShouldEnableAction() const {
return shown_by_policy_ || has_local_display_route_ || has_issue_ ||
dialog_count_ || context_menu_shown_ ||
keep_visible_for_right_mouse_button_ ||
GetAlwaysShowActionPref(profile_);
}
MediaRouterActionController::MediaRouterActionController(
Profile* profile,
media_router::MediaRouter* router)
: media_router::IssuesObserver(router->GetIssueManager()),
media_router::MediaRoutesObserver(router),
profile_(profile),
shown_by_policy_(
MediaRouterActionController::IsActionShownByPolicy(profile)),
weak_factory_(this) {
CHECK(profile_);
media_router::IssuesObserver::Init();
pref_change_registrar_.Init(profile->GetPrefs());
pref_change_registrar_.Add(
prefs::kShowCastIconInToolbar,
base::Bind(&MediaRouterActionController::MaybeAddOrRemoveAction,
base::Unretained(this)));
}
void MediaRouterActionController::MaybeAddOrRemoveAction() {
if (ShouldEnableAction()) {
for (Observer& observer : observers_)
observer.ShowIcon();
} else {
for (Observer& observer : observers_)
observer.HideIcon();
}
}