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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// Copyright 2024 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_BACKGROUND_GLIC_GLIC_BACKGROUND_MODE_MANAGER_H_
#define CHROME_BROWSER_BACKGROUND_GLIC_GLIC_BACKGROUND_MODE_MANAGER_H_
#include <map>
#include <memory>
#include "base/callback_list.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/background/glic/glic_launcher_configuration.h"
#include "chrome/browser/profiles/profile_manager_observer.h"
#include "chrome/browser/profiles/profile_observer.h"
#include "ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h"
class ScopedKeepAlive;
class StatusTray;
namespace ui {
class Accelerator;
}
namespace glic {
class GlicController;
class GlicStatusIcon;
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// LINT.IfChange(HotkeyUsage)
enum class HotkeyUsage {
kDefault = 0,
kCustom = 1,
kMaxValue = kCustom,
};
// LINT.ThenChange(//tools/metrics/histograms/metadata/glic/enums.xml:GlicHotkeyUsage)
// This is a global feature in the browser process that manages the
// enabling/disabling of glic background mode. When background mode is enabled,
// chrome is set to keep alive the browser process, so that this class can
// listen to a global hotkey, and provide a status icon for triggering the UI.
class GlicBackgroundModeManager
: public GlicLauncherConfiguration::Observer,
public ui::GlobalAcceleratorListener::Observer,
public ProfileManagerObserver,
public ProfileObserver {
public:
explicit GlicBackgroundModeManager(StatusTray* status_tray);
~GlicBackgroundModeManager() override;
static GlicBackgroundModeManager* GetInstance();
// GlicConfiguration::Observer
void OnEnabledChanged(bool enabled) override;
void OnGlobalHotkeyChanged(ui::Accelerator hotkey) override;
// ui::GlobalAcceleratorListener::Observer
void OnKeyPressed(const ui::Accelerator& accelerator) override;
void ExecuteCommand(const std::string& accelerator_group_id,
const std::string& command_id) override;
// ProfileManagerObserver:
void OnProfileAdded(Profile* profile) override;
// ProfileObserver:
void OnProfileWillBeDestroyed(Profile* profile) override;
void Shutdown();
ui::Accelerator RegisteredHotkeyForTesting() {
return actual_registered_hotkey_;
}
bool IsInBackgroundModeForTesting() {
CHECK_EQ(static_cast<bool>(keep_alive_), static_cast<bool>(status_icon_));
return keep_alive_ != nullptr;
}
GlicStatusIcon* GetStatusIconForTesting() { return status_icon_.get(); }
void EnterBackgroundMode();
void ExitBackgroundMode();
private:
void EnableLaunchOnStartup(bool should_launch);
void RegisterHotkey(ui::Accelerator updated_hotkey);
void UnregisterHotkey();
void UpdateState();
bool IsEnabledInAnyLoadedProfile();
// A helper class for observing pref changes.
std::unique_ptr<GlicLauncherConfiguration> configuration_;
// An abstraction used to show/hide the UI.
std::unique_ptr<GlicController> controller_;
std::unique_ptr<ScopedKeepAlive> keep_alive_;
// TODO(https://crbug.com/378139555): Figure out how to not dangle this
// pointer (and other instances of StatusTray).
raw_ptr<StatusTray, DanglingUntriaged> status_tray_;
// Class that represents the glic status icon. Only exists when the background
// mode is enabled.
std::unique_ptr<GlicStatusIcon> status_icon_;
// The current state of the launcher_enabled pref. Note that the pref is a
// local state and is thus per-installation. Each profile also has a
// "settings_policy" pref which can be used to disable the feature for a
// profile. Background mode is entered only if `enabled_pref` is true AND at
// least one loaded profile is enabled by policy.
bool enabled_pref_ = false;
// The actual registered hotkey may be different from the expected hotkey
// because the Glic launcher may be disabled or registration fails which
// results in no hotkey being registered and is represented with an empty
// accelerator.
ui::Accelerator expected_registered_hotkey_;
ui::Accelerator actual_registered_hotkey_;
// Listens to changes to IsEnabled() for profiles.
std::map<Profile*, base::CallbackListSubscription>
profile_enabled_subscriptions_;
std::map<Profile*, base::CallbackListSubscription>
profile_consent_subscriptions_;
using ScopedProfileObserver =
base::ScopedObservation<Profile, ProfileObserver>;
std::map<Profile*, ScopedProfileObserver> profile_observers_;
base::WeakPtrFactory<GlicBackgroundModeManager> weak_ptr_factory_{this};
};
} // namespace glic
#endif // CHROME_BROWSER_BACKGROUND_GLIC_GLIC_BACKGROUND_MODE_MANAGER_H_
|