chromium/chromeos/ash/components/dbus/resourced/resourced_client.h

// 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 CHROMEOS_ASH_COMPONENTS_DBUS_RESOURCED_RESOURCED_CLIENT_H_
#define CHROMEOS_ASH_COMPONENTS_DBUS_RESOURCED_RESOURCED_CLIENT_H_

#include <cstdint>
#include <vector>

#include "base/component_export.h"
#include "base/observer_list_types.h"
#include "base/process/process_handle.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "chromeos/dbus/common/dbus_callback.h"
#include "components/memory_pressure/reclaim_target.h"
#include "dbus/dbus_result.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/resource_manager/dbus-constants.h"

namespace dbus {
class Bus;
}

namespace ash {

class FakeResourcedClient;

// ResourcedClient is used to communicate with the org.chromium.ResourceManager
// service. The browser uses the ResourceManager service to get resource usage
// status.
class COMPONENT_EXPORT(RESOURCED) ResourcedClient {
 public:
  enum PressureLevel {
    // There is enough memory to use.
    NONE = 0,
    // Chrome is advised to free buffers that are cheap to re-allocate and not
    // immediately needed.
    MODERATE = 1,
    // Chrome is advised to free all possible memory.
    CRITICAL = 2,
  };

  // Observer class for memory pressure signal.
  class Observer : public base::CheckedObserver {
   public:
    ~Observer() override = default;

    virtual void OnMemoryPressure(PressureLevel level,
                                  memory_pressure::ReclaimTarget target) = 0;
  };

  // Indicates whether game mode is on, and which kind of game mode if it is on.
  // Borealis game mode will put more memory pressure on ARCVM processes than
  // will ARC game mode.
  // D-Bus serializes this as a u8, hence the uint8_t specifier.
  enum class GameMode : uint8_t {
    OFF = 0,
    BOREALIS = 1,
    ARC = 2,
  };

  enum class PressureLevelArcContainer {
    // There is enough memory to use.
    kNone = 0,
    // ARC container is advised to kill cached apps to free memory.
    kCached = 1,
    // ARC container is advised to kill perceptible apps to free memory.
    kPerceptible = 2,
    // ARC container is advised to kill foreground apps to free memory.
    kForeground = 3,
  };

  // Observer class for ARC container memory pressure signal.
  class ArcContainerObserver : public base::CheckedObserver {
   public:
    ~ArcContainerObserver() override = default;

    virtual void OnMemoryPressure(PressureLevelArcContainer level,
                                  uint64_t reclaim_target_kb) = 0;
  };

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

  // Creates and initializes the global instance. |bus| must not be null.
  static void Initialize(dbus::Bus* bus);

  // Creates and initializes a fake global instance if not already created.
  // The newly created object will persist until Shutdown() is called.
  static FakeResourcedClient* InitializeFake();

  // Destroys the global instance.
  static void Shutdown();

  // Returns the global instance which may be null if not initialized.
  static ResourcedClient* Get();

  // Attempts to enter or exit game mode depending on the value of |game_mode|.
  // Will automatically exit game mode once refresh_seconds is reached.
  // Callback will be called with whether game mode was on prior to this.
  virtual void SetGameModeWithTimeout(
      GameMode game_mode,
      uint32_t refresh_seconds,
      chromeos::DBusMethodCallback<GameMode> callback) = 0;

  using SetMemoryMarginsBpsCallback =
      base::OnceCallback<void(bool, uint64_t, uint64_t)>;

  // Informs resourced that it should use a different value for the critical
  // threshold. The value provided for |critical_bps| and |moderate_bps| must be
  // in basis points which represent one-one hundredth of a percent, eg. 1354
  // = 13.54%.
  virtual void SetMemoryMarginsBps(uint32_t critical_bps,
                                   uint32_t moderate_bps,
                                   SetMemoryMarginsBpsCallback callback) = 0;

  enum class Component {
    kAsh = 0,
    kLacros = 1,
  };

  struct Process {
    Process(base::ProcessHandle pid,
            bool is_protected,
            bool is_visible,
            bool is_focused,
            base::TimeTicks last_visible)
        : pid(pid),
          is_protected(is_protected),
          is_visible(is_visible),
          is_focused(is_focused),
          last_visible(last_visible) {}
    base::ProcessHandle pid;
    bool is_protected;
    bool is_visible;
    bool is_focused;
    base::TimeTicks last_visible;
  };

  virtual void ReportBrowserProcesses(
      Component component,
      const std::vector<Process>& processes) = 0;

  using SetQoSStateCallback = base::OnceCallback<void(dbus::DBusResult)>;

  // Set qos state of a process.
  virtual void SetProcessState(base::ProcessId,
                               resource_manager::ProcessState,
                               SetQoSStateCallback) = 0;

  // Set qos state of a thread.
  virtual void SetThreadState(base::ProcessId,
                              base::PlatformThreadId,
                              resource_manager::ThreadState,
                              SetQoSStateCallback) = 0;

  // Adds an observer to the observer list to listen on memory pressure events.
  virtual void AddObserver(Observer* observer) = 0;

  // Removes an observer from observer list.
  virtual void RemoveObserver(Observer* observer) = 0;

  virtual void AddArcContainerObserver(ArcContainerObserver* observer) = 0;

  virtual void RemoveArcContainerObserver(ArcContainerObserver* observer) = 0;

  // Registers |callback| to run when the ResourceManager service becomes
  // available. If the service is already available, or if connecting to the
  // name-owner-changed signal fails, |callback| will be run once
  // asynchronously.
  // Otherwise, |callback| will be run once in the future after the service
  // becomes available.
  virtual void WaitForServiceToBeAvailable(
      dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) = 0;

 protected:
  ResourcedClient();
  virtual ~ResourcedClient();
};

}  // namespace ash

#endif  // CHROMEOS_ASH_COMPONENTS_DBUS_RESOURCED_RESOURCED_CLIENT_H_