File: arc_vmm_manager.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; 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,811; 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 (183 lines) | stat: -rw-r--r-- 6,834 bytes parent folder | download | duplicates (5)
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
// Copyright 2023 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_ASH_ARC_VMM_ARC_VMM_MANAGER_H_
#define CHROME_BROWSER_ASH_ARC_VMM_ARC_VMM_MANAGER_H_

#include <string>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/arc/vmm/arc_system_state_observation.h"
#include "chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.h"
#include "chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h"
#include "chromeos/ash/components/dbus/vm_concierge/concierge_service.pb.h"
#include "chromeos/ash/experiences/arc/mojom/app.mojom.h"
#include "chromeos/ash/experiences/arc/session/connection_holder.h"
#include "chromeos/ash/experiences/arc/session/connection_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/browser_context.h"

namespace arc {

class ArcBridgeService;

enum class SwapState {
  ENABLE,
  FORCE_ENABLE,
  DISABLE,
};

// ARCVM vmm features manager.
class ArcVmmManager : public KeyedService,
                      public arc::ConnectionObserver<arc::mojom::AppInstance>,
                      public ash::ConciergeClient::VmObserver {
 public:
  class Observer : public base::CheckedObserver {
   public:
    virtual void OnArcVmSwappingOut() {}
    virtual void OnArcVmSwappingIn() {}

   protected:
    ~Observer() override = default;
  };

  // Returns singleton instance for the given BrowserContext, or nullptr if
  // the browser |context| is not allowed to use ARC.
  static ArcVmmManager* GetForBrowserContext(content::BrowserContext* context);
  static ArcVmmManager* GetForBrowserContextForTesting(
      content::BrowserContext* context);

  ArcVmmManager(content::BrowserContext* context, ArcBridgeService* bridge);

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

  ~ArcVmmManager() override;

  // SetSwapState change the ARCVM vmm swap state in crosvm. When swap enabled,
  // the crosvm process will be STOP and guest memory will be moved to the
  // staging memory.
  void SetSwapState(SwapState state);

  // Is the ARCVM on "swapped" state. If it's true, the ARC app launch maybe
  // slower than usual.
  bool IsSwapped() const;

  void set_user_id_hash(const std::string& user_id_hash) {
    user_id_hash_ = user_id_hash;
  }

  static void EnsureFactoryBuilt();

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // arc::ConnectionObserver:
  void OnConnectionReady() override;
  void OnConnectionClosed() override;

  // ash::ConciergeClient::VmObserver override:
  void OnVmSwapping(
      const vm_tools::concierge::VmSwappingSignal& signal) override;

 private:
  friend class ArcVmmManagerTest;
  friend class ArcVmmManagerBrowserTest;
  // Accelerator target for experimental usage. Ctrl + Alt + Shift + O / P for
  // enable or disable vmm swap.
  class AcceleratorTarget;

  void SendSwapRequest(vm_tools::concierge::SwapOperation operation,
                       base::OnceClosure success_callback);

  // Wrapped function of `SendSwapRequest`. Verify if the latest operation still
  // match the calling operation. If so, pass the params to SendSwapRequest, or
  // do nothing.
  // Prefer use it in the chain of callbacks. Before enable vmm swap, the memory
  // shrink may need take several minutes. During this time, if the "disable"
  // request come, we need make sure not send the "enable" request after finish
  // memory shrink.
  void VerifyThenSendSwapRequest(vm_tools::concierge::SwapOperation operation,
                                 base::OnceClosure success_callback);

  void SendAggressiveBalloonRequest(bool enable,
                                    base::OnceClosure success_callback);

  // Wrapped function of `SendAggressiveBalloonRequest`. Verify if the latest
  // operation still match the calling operation. If so, pass the params to
  // SendAggressiveBalloonRequest, or do nothing.
  // Prefer use it in the chain of callbacks, as the same with
  // `VerifyThenSendSwapRequest`.
  void VerifyThenSendAggressiveBalloonRequest(
      bool enable,
      base::OnceClosure success_callback);

  void PostWithSwapDelay(base::OnceClosure callback);

  // Called by `SendSwapRequest` and should not be called by other caller.
  // Enable aggressive balloon and reclaim ARCVM guest memory.
  // Shrink memory before enable swap. The function send enable swap request
  // after shrink success.
  void ShrinkArcVmMemoryAndEnableSwap(
      vm_tools::concierge::SwapOperation requested_operation);

  // Called by callback from `ShrinkArcVmMemoryAndEnableSwap` and should not be
  // called by other caller. Update shrink result.
  void SetShrinkResult(bool success);

  SwapState latest_swap_state_ = SwapState::DISABLE;

  // List of observers.
  base::ObserverList<Observer> observer_list_;

  // Log the time stamp and result of last shrink memory request.
  std::optional<base::Time> last_shrink_timestamp_;
  std::optional<bool> last_shrink_result_;

  // Repeat timer for checking and trimming ARCVM memory regularly. According
  // current design in concierge, if the vmm swap status is enabled, the vmm
  // manager needs to go through the "enable" process (i.e. trim memory, set
  // aggressive balloon, send enable vmm swap dbus request) once an hour.
  base::OneShotTimer enabled_state_heartbeat_timer_;

  // The default delay from swap enabled and swap out. Basically it's used for
  // keyboard swap. In finch, it will be replaced by the flag parameter.
  base::TimeDelta swap_out_delay_ = base::Seconds(3);

  // Accelerator for experimental usage. Always behind the feature flag.
  std::unique_ptr<AcceleratorTarget> accelerator_;

  // Swap request scheduler for experimental usage. Always behind the feature
  // flag and parameters.
  std::unique_ptr<ArcVmmSwapScheduler> scheduler_;

  bool arc_connected_ = false;

  std::string user_id_hash_;

  base::RepeatingCallback<
      void(ArcVmWorkingSetTrimExecutor::ResultCallback, ArcVmReclaimType, int)>
      trim_call_;

  raw_ptr<content::BrowserContext> context_ = nullptr;
  raw_ptr<ArcBridgeService> bridge_service_ = nullptr;

  base::ScopedObservation<
      ConnectionHolder<mojom::AppInstance, mojom::AppHost>,
      ConnectionHolder<mojom::AppInstance, mojom::AppHost>::Observer>
      app_instance_observation_{this};

  base::ScopedObservation<ash::ConciergeClient,
                          ash::ConciergeClient::VmObserver>
      concierge_observation_{this};

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

}  // namespace arc

#endif  // CHROME_BROWSER_ASH_ARC_VMM_ARC_VMM_MANAGER_H_