1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_TOOLBAR_CAST_CAST_TOOLBAR_BUTTON_CONTROLLER_H_
#define CHROME_BROWSER_UI_TOOLBAR_CAST_CAST_TOOLBAR_BUTTON_CONTROLLER_H_
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/profiles/profile.h"
#include "components/media_router/browser/issues_observer.h"
#include "components/media_router/browser/media_routes_observer.h"
#include "components/prefs/pref_change_registrar.h"
// Controller for the Cast toolbar icon that determines when to show and hide
// icon. There should be one instance of this class per profile, and it should
// only be used on the UI thread.
class CastToolbarButtonController : public media_router::IssuesObserver,
public media_router::MediaRoutesObserver {
public:
explicit CastToolbarButtonController(Profile* profile);
// Constructor for injecting dependencies in tests.
CastToolbarButtonController(Profile* profile,
media_router::MediaRouter* router);
CastToolbarButtonController(const CastToolbarButtonController&) = delete;
CastToolbarButtonController& operator=(const CastToolbarButtonController&) =
delete;
~CastToolbarButtonController() override;
// Whether the media router action is shown by an administrator policy.
static bool IsActionShownByPolicy(Profile* profile);
// Gets and sets the preference for whether the media router action should be
// pinned to the toolbar/overflow menu.
static bool GetAlwaysShowActionPref(Profile* profile);
static void SetAlwaysShowActionPref(Profile* profile, bool always_show);
// media_router::IssuesObserver:
void OnIssue(const media_router::Issue& issue) override;
void OnIssuesCleared() override;
// media_router::MediaRoutesObserver:
void OnRoutesUpdated(
const std::vector<media_router::MediaRoute>& routes) override;
// Called when a Media Router dialog is shown or hidden, and updates the
// visibility of the action icon. Overridden in tests.
virtual void OnDialogShown();
virtual void OnDialogHidden();
// Updates the icon for all browsers with the same profile.
void UpdateIcon();
// On Windows (with a right click) and Chrome OS (with touch), pressing the
// toolbar icon makes the dialog disappear, but the context menu does not
// appear until mouse/touch release. These methods ensure that the icon is
// still shown at mouse/touch release so that the context menu can be shown.
void KeepIconShownOnPressed();
void MaybeHideIconOnReleased();
// Returns |true| if the Media Router action should be present on the toolbar
// or the overflow menu.
bool ShouldEnableAction() const;
bool GetHasLocalDisplayRouteForTesting() { return has_local_display_route_; }
bool GetHasIssueForTesting() { return has_issue_; }
private:
friend class CastToolbarButtonControllerUnitTest;
// Adds or removes the Cast icon to/from the toolbar if necessary,
// depending on whether or not we have issues, local routes or a dialog.
virtual void MaybeToggleIconVisibility();
// Updates the kActionMediaRouterToggleMediaRemoting ActionItem based on
// changes to the pref.
void UpdateToggleMediaRouterRemotingAction();
// The profile |this| is associated with. There should be one instance of this
// class per profile.
const raw_ptr<Profile> profile_;
bool has_issue_ = false;
bool has_local_display_route_ = false;
// Whether the media router action is shown by an administrator policy.
bool shown_by_policy_;
// The number of dialogs that are currently open.
size_t dialog_count_ = 0;
// Whether the Cast toolbar icon is showing a context menu. The toolbar icon
// should not be hidden while a context menu is shown.
bool context_menu_shown_ = false;
// On Windows (with the right mouse button) and on Chrome OS (with touch),
// when the user presses the toolbar icon, the dialog gets hidden, but the
// context menu is not shown until mouse/touch release. If the icon is
// ephemeral, it gets hidden on press and can't show the context menu. So we
// must keep the icon shown while the right click or touch is held.
bool keep_visible_for_right_click_or_hold_ = false;
PrefChangeRegistrar pref_change_registrar_;
base::WeakPtrFactory<CastToolbarButtonController> weak_factory_{this};
};
#endif // CHROME_BROWSER_UI_TOOLBAR_CAST_CAST_TOOLBAR_BUTTON_CONTROLLER_H_
|