File: dark_resume_controller.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (137 lines) | stat: -rw-r--r-- 6,103 bytes parent folder | download | duplicates (9)
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 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_COMPONENTS_POWER_DARK_RESUME_CONTROLLER_H_
#define CHROMEOS_ASH_COMPONENTS_POWER_DARK_RESUME_CONTROLLER_H_

#include "base/component_export.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/unguessable_token.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.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"

namespace ash::system {

// This class listens to dark resume events from the power manager and makes
// decisions on whether to re-suspend the device or keep the device in dark
// resume based on the wake locks activated at the time of a dark resume. It -
//
// 1. Starts a timer to check for any activated app suspension wake locks. This
// gives services time to do work in dark resume. They can activate a wake lock
// to indicate to the system that they are still doing work.
//
// 2. After the timer in 1 expires, an observer for wake lock deactivation is
// set. Also a hard timeout timer is scheduled.
//
// 3. If no wake lock is held then the observer gets notified immediately and
// the power manager is requested to re-suspend the system.
//
// 4. If an app suspension wake lock is acquired then either -
// - The observer from 2 is notified when the wake lock is deactivated and the
// power manager is requested to re-suspend the system.
// Or
// - The hard timeout timer from 2 fires and the power manager is requested to
// re-suspend the system.
//
// 5. If the system transitions to a full resume all dark resume related state
// and timers are cleared as the system wakes up.
class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_POWER) DarkResumeController
    : public chromeos::PowerManagerClient::Observer,
      public device::mojom::WakeLockObserver {
 public:
  explicit DarkResumeController(
      mojo::PendingRemote<device::mojom::WakeLockProvider> wake_lock_provider);

  DarkResumeController(const DarkResumeController&) = delete;
  DarkResumeController& operator=(const DarkResumeController&) = delete;

  ~DarkResumeController() override;

  // Time after a dark resume when wake lock count is checked and a decision is
  // made to re-suspend or wait for wake lock release.
  static constexpr base::TimeDelta kDarkResumeWakeLockCheckTimeout =
      base::Seconds(3);

  // chromeos::PowerManagerClient::Observer overrides.
  void PowerManagerInitialized() override;
  void DarkSuspendImminent() override;
  void SuspendDone(base::TimeDelta sleep_duration) override;

  // mojom::WakeLockObserver overrides.
  void OnWakeLockDeactivated(device::mojom::WakeLockType type) override;

  // Return true iff all dark resume related state is set i.e the suspend
  // readiness token is set and wake lock release event has observers.
  bool IsDarkResumeStateSetForTesting() const;

  // Return true iff all dark resume related state is reset i.e. suspend
  // readiness token is empty, wake lock release event has no observers,
  // wake lock check timer is reset, hard timeout timer is reset and there are
  // no in flight tasks. This should be true when device exits dark resume
  // either by re-suspending or transitioning to full resume.
  bool IsDarkResumeStateClearedForTesting() const;

  // Returns |dark_resume_hard_timeout_|.
  base::TimeDelta GetHardTimeoutForTesting() const;

 private:
  // Called |kDarkResumeWakeLockCheckTimeout| after a dark resume. Checks if
  // app suspension wake locks are held. If no wake locks are held then
  // re-suspends the device else schedules HandleDarkResumeHardTimeout.
  void HandleDarkResumeWakeLockCheckTimeout();

  // Called |kDarkResumeHardTimeout| after a
  // HandleDarkResumeWakeLockCheckTimeout. Clears all dark resume state and
  // re-suspends the device.
  void HandleDarkResumeHardTimeout();

  // Clears all state associated with dark resume.
  void ClearDarkResumeState();

  // Used for acquiring, releasing and observing wake locks.
  mojo::Remote<device::mojom::WakeLockProvider> wake_lock_provider_;

  // Used when system is ready to suspend after a DarkSupendImminent i.e.
  // after a dark resume.
  base::UnguessableToken block_suspend_token_;

  // The receiver used to implement device::mojom::WakeLockObserver.
  mojo::Receiver<device::mojom::WakeLockObserver> wake_lock_observer_receiver_{
      this};

  // Timer used to schedule HandleDarkResumeWakeLockCheckTimeout.
  base::OneShotTimer wake_lock_check_timer_;

  // Timer used to schedule HandleDarkResumeHardTimeout.
  base::OneShotTimer hard_timeout_timer_;

  // Max time to wait for wake lock release after a wake lock check after a dark
  // resume. After this time the system is asked to re-suspend. This is
  // initialized via PowerManagerClient when it's initialization is complete in
  // |PowerManagerInitialized|. Till then there may be a very small window after
  // booth when it takes a default value.
  base::TimeDelta dark_resume_hard_timeout_;

  // Used for checking if HandleDarkResumeWakeLockCheckTimeout and
  // HandleDarkResumeHardTimeout run on the same sequence.
  SEQUENCE_CHECKER(dark_resume_tasks_sequence_checker_);

  // This is invalidated in ClearDarkResumeState as a fail safe measure to clear
  // any lingering timer callbacks or wake lock observer callbacks. This is a
  // good to have but not a necessity as ClearDarkResumeState cancels any dark
  // resume state machine related tasks via other means. In the future if other
  // tasks or callbacks need to be added separate from the dark resume state
  // machine lifetime then a separate factory needs to be created and used.
  base::WeakPtrFactory<DarkResumeController> weak_ptr_factory_{this};
};

}  // namespace ash::system

#endif  // CHROMEOS_ASH_COMPONENTS_POWER_DARK_RESUME_CONTROLLER_H_