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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
ash / components / arc / power / arc_power_bridge.h [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_COMPONENTS_ARC_POWER_ARC_POWER_BRIDGE_H_
#define ASH_COMPONENTS_ARC_POWER_ARC_POWER_BRIDGE_H_
#include <map>
#include <memory>
#include <optional>
#include <string>
#include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h"
#include "ash/components/arc/mojom/anr.mojom.h"
#include "ash/components/arc/mojom/power.mojom.h"
#include "ash/components/arc/session/arc_service_manager.h"
#include "ash/components/arc/session/connection_observer.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/singleton.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chromeos/ash/components/dbus/concierge/concierge_client.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "components/keyed_service/core/keyed_service.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/wake_lock.mojom.h"
#include "services/device/public/mojom/wake_lock_provider.mojom.h"
#include "ui/display/manager/display_configurator.h"
namespace content {
class BrowserContext;
} // namespace content
namespace arc {
class ArcBridgeService;
class ArcPowerBridge; // So we can declare the factory first.
// Singleton factory for ArcPowerBridge.
class ArcPowerBridgeFactory
: public internal::ArcBrowserContextKeyedServiceFactoryBase<
ArcPowerBridge,
ArcPowerBridgeFactory> {
public:
// Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
static constexpr const char* kName = "ArcPowerBridgeFactory";
static ArcPowerBridgeFactory* GetInstance();
private:
friend base::DefaultSingletonTraits<ArcPowerBridgeFactory>;
ArcPowerBridgeFactory() = default;
~ArcPowerBridgeFactory() override = default;
};
// ARC Power Client sets power management policy based on requests from
// ARC instances.
class ArcPowerBridge : public KeyedService,
public ConnectionObserver<mojom::PowerInstance>,
public chromeos::PowerManagerClient::Observer,
public display::DisplayConfigurator::Observer,
public mojom::PowerHost {
public:
class Observer : public base::CheckedObserver {
public:
// Notifies that wakefulness mode is changed.
virtual void OnWakefulnessChanged(mojom::WakefulnessMode mode) {}
virtual void OnPreAnr(mojom::AnrType type) {}
// Notifies about resume state of the underlying VM (ARCVM-exclusive).
// ARC Container does not communicate with CrosVM, and it doesn't
// instantiate services that care about this event.
virtual void OnVmResumed() {}
virtual void OnWillDestroyArcPowerBridge() {}
// Notifies when android idle state is changed.
virtual void OnAndroidIdleStateChange(::arc::mojom::IdleState state) {}
};
// Returns singleton instance for the given BrowserContext,
// or nullptr if the browser |context| is not allowed to use ARC.
static ArcPowerBridge* GetForBrowserContext(content::BrowserContext* context);
static ArcPowerBridge* GetForBrowserContextForTesting(
content::BrowserContext* context);
ArcPowerBridge(content::BrowserContext* context,
ArcBridgeService* bridge_service);
ArcPowerBridge(const ArcPowerBridge&) = delete;
ArcPowerBridge& operator=(const ArcPowerBridge&) = delete;
~ArcPowerBridge() override;
// Disables Android Idle Control logic locally.
// This is necessary because we are in the process of moving this control
// to a different class, and need to accommodate both cases.
// TODO(b/259622742): remove this once the new control is default.
void DisableAndroidIdleControl();
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
void SetUserIdHash(const std::string& user_id_hash);
// If |notify_brightness_timer_| is set, runs it and returns true. Returns
// false otherwise.
[[nodiscard]] bool TriggerNotifyBrightnessTimerForTesting();
// Runs the message loop until replies have been received for all pending
// device service requests in |wake_lock_requestors_|.
void FlushWakeLocksForTesting();
// ConnectionObserver<mojom::PowerInstance> overrides.
void OnConnectionReady() override;
void OnConnectionClosed() override;
// chromeos::PowerManagerClient::Observer overrides.
void SuspendImminent(power_manager::SuspendImminent::Reason reason) override;
void SuspendDone(base::TimeDelta sleep_duration) override;
void ScreenBrightnessChanged(
const power_manager::BacklightBrightnessChange& change) override;
void PowerChanged(const power_manager::PowerSupplyProperties& proto) override;
void BatterySaverModeStateChanged(
const power_manager::BatterySaverModeState& state) override;
// DisplayConfigurator::Observer overrides.
void OnPowerStateChanged(chromeos::DisplayPowerState power_state) override;
// mojom::PowerHost overrides.
void OnAcquireDisplayWakeLock(mojom::DisplayWakeLockType type) override;
void OnReleaseDisplayWakeLock(mojom::DisplayWakeLockType type) override;
void IsDisplayOn(IsDisplayOnCallback callback) override;
void OnScreenBrightnessUpdateRequest(double percent) override;
void OnWakefulnessChanged(mojom::WakefulnessMode mode) override;
void OnPreAnr(mojom::AnrType type) override;
void OnAnrRecoveryFailed(::arc::mojom::AnrType type) override;
void GetBatterySaverModeState(
GetBatterySaverModeStateCallback callback) override;
void SetWakeLockProviderForTesting(
mojo::Remote<device::mojom::WakeLockProvider> provider) {
wake_lock_provider_ = std::move(provider);
}
static void EnsureFactoryBuilt();
// Notify ARC and patchpanel about change in power state, notification to
// patchpanel is used to decide whether to start/stop forwarding multicast
// traffic to ARC.
void NotifyAndroidIdleState(ArcBridgeService* bridge,
::arc::mojom::IdleState enabled);
private:
class WakeLockRequestor;
// Returns the WakeLockRequestor for |type|, creating one if needed.
WakeLockRequestor* GetWakeLockRequestor(device::mojom::WakeLockType type);
// Called on PowerManagerClient::GetScreenBrightnessPercent() completion.
void OnGetScreenBrightnessPercent(std::optional<double> percent);
// Called by Android when ready to suspend.
void OnAndroidSuspendReady(base::UnguessableToken token);
// Called by ConciergeClient when a response has been receive for the
// SuspendVm D-Bus call.
void OnConciergeSuspendVmResponse(
base::UnguessableToken token,
std::optional<vm_tools::concierge::SuccessFailureResponse> reply);
// Called by ConciergeClient when a response has been receive for the
// ResumeVm D-Bus call.
void OnConciergeResumeVmResponse(
std::optional<vm_tools::concierge::SuccessFailureResponse> reply);
// Called on PowerManagerClient::GetBatterySaverModeState() completion.
void OnBatterySaverModeStateReceived(
GetBatterySaverModeStateCallback callback,
std::optional<power_manager::BatterySaverModeState> state);
// Sends a PowerInstance::UpdateScreenBrightnessSettings mojo call to Android.
void UpdateAndroidScreenBrightness(double percent);
// Sends a PowerInstance::Resume mojo call to Android.
void DispatchAndroidResume();
const raw_ptr<ArcBridgeService>
arc_bridge_service_; // Owned by ArcServiceManager.
std::string user_id_hash_;
mojo::Remote<device::mojom::WakeLockProvider> wake_lock_provider_;
// Used to track Android wake lock requests and acquire and release device
// service wake locks as needed.
std::map<device::mojom::WakeLockType, std::unique_ptr<WakeLockRequestor>>
wake_lock_requestors_;
// Last time that the power manager notified about a brightness change.
base::TimeTicks last_brightness_changed_time_;
// Timer used to run UpdateAndroidScreenBrightness() to notify Android
// about brightness changes.
base::OneShotTimer notify_brightness_timer_;
// List of observers.
base::ObserverList<Observer> observer_list_;
// Represents whether a device suspend is currently underway, ie. a
// SuspendImminent event has been observed, but a SuspendDone event has not
// yet been observed.
bool is_suspending_ = false;
// Controls whether or not we switch Android's idle state upon events.
bool android_idle_control_disabled_ = false;
base::WeakPtrFactory<ArcPowerBridge> weak_ptr_factory_{this};
};
} // namespace arc
#endif // ASH_COMPONENTS_ARC_POWER_ARC_POWER_BRIDGE_H_