File: owner_pending_setting_controller.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (167 lines) | stat: -rw-r--r-- 7,093 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
// 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_ASH_SETTINGS_OWNER_PENDING_SETTING_CONTROLLER_H_
#define CHROME_BROWSER_ASH_SETTINGS_OWNER_PENDING_SETTING_CONTROLLER_H_

#include "base/callback_list.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/sequence_checker.h"
#include "base/values.h"
#include "chrome/browser/ash/settings/device_settings_service.h"
#include "chromeos/ash/components/settings/cros_settings.h"
#include "components/ownership/owner_settings_service.h"

class PrefService;
class Profile;

namespace ownership {
class OwnerSettingsService;
}

namespace ash {

// An extra layer on top of CrosSettings / OwnerSettingsService that allows for
// writing a setting before ownership is taken.
//
// Ordinarily, the OwnerSettingsService interface is used for writing settings,
// and the CrosSettings interface is used for reading them - but as the OSS
// cannot be used until the device has an owner, this class can be used instead,
// since writing the new value with SetEnabled works even before ownership is
// taken.
//
// If OSS is ready then the new value is written straight away, and if not, then
// a pending write is queued that is completed as soon as the OSS is ready.
// This write will complete even if Chrome is restarted in the meantime.
// The caller need not care whether the write was immediate or pending, as long
// as they also use this class to read the value of the device pref.
// IsEnabled will return the pending value until ownership is taken and the
// pending value is written - from then on it will return the signed, stored
// value from CrosSettings.
class OwnerPendingSettingController
    : public ownership::OwnerSettingsService::Observer {
 public:
  OwnerPendingSettingController() = delete;
  OwnerPendingSettingController(const OwnerPendingSettingController&) = delete;
  OwnerPendingSettingController& operator=(
      const OwnerPendingSettingController&) = delete;

  // Store the new value. This will happen straight away if |profile| is the
  // owner, and it will cause a pending write to be buffered and written later
  // if the device has no owner yet. It will write a warning and skip if the
  // device already has an owner, and |profile| is not that owner.
  void Set(Profile* profile, base::Value value);

  // Returns the latest value - regardless of whether this has been successfully
  // signed and persisted, or if it is still stored as a pending write. Can
  // return std::nullopt if there is no pending write and no signed value.
  std::optional<base::Value> GetValue() const;

  // Add an observer |callback| for changes to the setting.
  [[nodiscard]] base::CallbackListSubscription AddObserver(
      const base::RepeatingClosure& callback);

  // Called once ownership is taken, |service| is the service of the user taking
  // ownership.
  void OnOwnershipTaken(ownership::OwnerSettingsService* service);

  // Sets the callback which is called once when the pending |value| is
  // propagated to the device settings. Support only one callback at a time.
  // CHECKs if the second callback is being set.
  // It's different from the |AddObserver| API. Observers are called
  // immediately after |Set| is called with the different |value| setting.
  void SetOnDeviceSettingsStoredCallBack(base::OnceClosure callback);

  // ownership::OwnerSettingsService::Observer implementation:
  void OnSignedPolicyStored(bool success) override;
  void OnServiceShutdown() override;

  // Clears any value waiting to be written (from storage in local state).
  void ClearPendingValue();

 protected:
  OwnerPendingSettingController(const std::string& pref_name,
                                const std::string& pending_pref_name,
                                PrefService* local_state);
  ~OwnerPendingSettingController() override;

  // Delegates immediately to SetWithService if |service| is ready, otherwise
  // runs SetWithService asynchronously once |service| is ready.
  void SetWithServiceAsync(ownership::OwnerSettingsService* service,
                           base::Value value);

  // Callback used by SetWithServiceAsync.
  void SetWithServiceCallback(
      const base::WeakPtr<ownership::OwnerSettingsService>& service,
      const base::Value& value,
      bool is_owner);

  // Uses |service| to write the latest value, as long as |service| belongs
  // to the owner - otherwise just prints a warning.
  void SetWithService(ownership::OwnerSettingsService* service,
                      const base::Value& value);

  // Notifies observers if the value has changed.
  void NotifyObservers();

  base::WeakPtr<OwnerPendingSettingController> as_weak_ptr() {
    return weak_factory_.GetWeakPtr();
  }

  SEQUENCE_CHECKER(sequence_checker_);

  raw_ptr<PrefService> local_state_;
  std::optional<base::Value> value_notified_to_observers_;
  base::RepeatingClosureList callback_list_;
  base::CallbackListSubscription setting_subscription_;

  base::ScopedObservation<ownership::OwnerSettingsService,
                          ownership::OwnerSettingsService::Observer>
      owner_settings_service_observation_{this};

  // Indicates if the setting value is in the process of being set with the
  // service. There is a small period of time needed between start saving the
  // value and before the value is stored correctly in the service. We should
  // not use the setting value from the service if it is still in the process
  // of being saved.
  bool is_value_being_set_with_service_ = false;

 private:
  friend class StatsReportingControllerTest;

  // Gets the current ownership status - owned, unowned, or unknown.
  DeviceSettingsService::OwnershipStatus GetOwnershipStatus() const;

  // Get the owner-settings service for a particular profile. A variety of
  // different results can be returned, depending on the profile.
  // a) A ready-to-use service that we know belongs to the owner.
  // b) A ready-to-use service that we know does NOT belong to the owner.
  // c) A service that is NOT ready-to-use, which MIGHT belong to the owner.
  // d) nullptr (for instance, if |profile| is a guest).
  ownership::OwnerSettingsService* GetOwnerSettingsService(Profile* profile);

  // Return the value waiting to be written (stored in local_state), if one
  // exists.
  std::optional<base::Value> GetPendingValue() const;

  // Return the value signed and stored in CrosSettings, if one exists.
  std::optional<base::Value> GetSignedStoredValue() const;

  // Returns whether pending value should be used when determining the value
  // of `GetValue`.
  bool ShouldReadFromPendingValue() const;

  base::OnceClosure on_device_settings_stored_callback_;

  const std::string pref_name_;
  const std::string pending_pref_name_;

  base::WeakPtrFactory<OwnerPendingSettingController> weak_factory_{this};
};

}  // namespace ash

#endif  // CHROME_BROWSER_ASH_SETTINGS_OWNER_PENDING_SETTING_CONTROLLER_H_