File: dbus_memory_pressure_evaluator_linux.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (141 lines) | stat: -rw-r--r-- 5,531 bytes parent folder | download
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
// Copyright 2021 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_DBUS_MEMORY_PRESSURE_EVALUATOR_LINUX_H_
#define CHROME_BROWSER_DBUS_MEMORY_PRESSURE_EVALUATOR_LINUX_H_

#include <memory>
#include <string>

#include "base/functional/callback_forward.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/memory_pressure/system_memory_pressure_evaluator.h"
#include "dbus/bus.h"

namespace dbus {
class Response;
class Signal;
}  // namespace dbus

namespace memory_pressure {
class MemoryPressureVoter;
}  // namespace memory_pressure

// A memory pressure evaluator that uses the low-memory-monitor service
// (abbreviated in the code as "LMM") to monitor the memory pressure. If the
// service is not available, it can use the XDG memory monitor portal as a
// fallback (which itself is a thin wrapper over LMM).
//
// The LMM API is described here:
// https://hadess.pages.freedesktop.org/low-memory-monitor/
// and the portal API wrapper is here:
// https://flatpak.github.io/xdg-desktop-portal/portal-docs.html#gdbus-org.freedesktop.portal.MemoryMonitor
class DbusMemoryPressureEvaluatorLinux
    : public memory_pressure::SystemMemoryPressureEvaluator {
 public:
  explicit DbusMemoryPressureEvaluatorLinux(
      std::unique_ptr<memory_pressure::MemoryPressureVoter> voter);
  ~DbusMemoryPressureEvaluatorLinux() override;

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

 private:
  friend class DbusMemoryPressureEvaluatorLinuxTest;
  friend class DbusMemoryPressureEvaluatorLinuxSignalConnectionTest;

  // Constants for D-Bus services, object paths, methods, and signals. In-class
  // so they can be shared with the tests.
  static const char kMethodNameHasOwner[];
  static const char kMethodListActivatableNames[];

  static const char kLmmService[];
  static const char kLmmObject[];
  static const char kLmmInterface[];

  static const char kXdgPortalService[];
  static const char kXdgPortalObject[];
  static const char kXdgPortalMemoryMonitorInterface[];

  static const char kLowMemoryWarningSignal[];

  static const base::TimeDelta kResetVotePeriod;

  // The public constructor just delegates to this private one, but it's
  // separated so that the test cases can pass in the mock bus instances.
  DbusMemoryPressureEvaluatorLinux(
      std::unique_ptr<memory_pressure::MemoryPressureVoter> voter,
      scoped_refptr<dbus::Bus> system_bus,
      scoped_refptr<dbus::Bus> session_bus);

  // Checks if LMM itself is available, setting up the memory pressure signal
  // handler if so. Otherwise, checks if the portal is available instead.
  void CheckIfLmmIsAvailable();
  // Handles the availability response from above.
  void CheckIfLmmIsAvailableResponse(bool is_available);

  // Checks if the portal service is available, setting up the memory pressure
  // signal handler if so.
  void CheckIfPortalIsAvailable();
  // Handles the availability response from above.
  void CheckIfPortalIsAvailableResponse(bool is_available);

  // Checks if the given service is available, calling callback(true) if so or
  // callback(false) otherwise.
  void CheckIfServiceIsAvailable(scoped_refptr<dbus::Bus> bus,
                                 const std::string& service,
                                 base::OnceCallback<void(bool)> callback);

  void OnNameHasOwnerResponse(scoped_refptr<dbus::Bus> bus,
                              const std::string& service,
                              base::OnceCallback<void(bool)> callback,
                              dbus::Response* response);
  void OnListActivatableNamesResponse(const std::string& service,
                                      base::OnceCallback<void(bool)> callback,
                                      dbus::Response* response);

  // Shuts down the given bus on the D-Bus thread and clears the pointer.
  void ResetBus(scoped_refptr<dbus::Bus>& bus);

  void OnSignalConnected(const std::string& interface,
                         const std::string& signal,
                         bool connected);

  void OnLowMemoryWarning(dbus::Signal* signal);

  // Converts a pressure level from LMM to base's memory pressure constants.
  base::MemoryPressureListener::MemoryPressureLevel LmmToBasePressureLevel(
      uint8_t lmm_level);

  void UpdateLevel(base::MemoryPressureListener::MemoryPressureLevel new_level);

  scoped_refptr<dbus::Bus> system_bus_;
  scoped_refptr<dbus::Bus> session_bus_;
  raw_ptr<dbus::ObjectProxy> object_proxy_ = nullptr;

  // The values used to determine how to translate LMM memory pressure levels to
  // Chrome's are stored here, gathered from feature params.
  uint8_t moderate_level_;
  uint8_t critical_level_;

  // LMM never emits signals once the memory pressure has ended, so we need to
  // estimate when that is the case by checking when the monitor has gone silent
  // for a while.
  base::OneShotTimer reset_vote_timer_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<DbusMemoryPressureEvaluatorLinux> weak_ptr_factory_{
      this};
};

#endif  // CHROME_BROWSER_DBUS_MEMORY_PRESSURE_EVALUATOR_LINUX_H_