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
|
// 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 <optional>
#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 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 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(std::optional<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(std::optional<bool> is_available);
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_
|