File: device_settings_service.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 (338 lines) | stat: -rw-r--r-- 13,150 bytes parent folder | download | duplicates (3)
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
// Copyright 2012 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_DEVICE_SETTINGS_SERVICE_H_
#define CHROME_BROWSER_ASH_SETTINGS_DEVICE_SETTINGS_SERVICE_H_

#include <memory>
#include <string>
#include <vector>

#include "base/containers/circular_deque.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
#include "components/ownership/owner_settings_service.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/cloud_policy_validator.h"
#include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/policy/proto/device_management_backend.pb.h"

class PrefService;

namespace ownership {
class OwnerKeyUtil;
class PublicKey;
}  // namespace ownership

namespace policy {
namespace off_hours {
class DeviceOffHoursController;
}  // namespace off_hours
}  // namespace policy

namespace ash {

class SessionManagerOperation;

// Deals with the low-level interface to Chrome OS device settings. Device
// settings are stored in a protobuf that's protected by a cryptographic
// signature generated by a key in the device owner's possession. Key and
// settings are brokered by the session_manager daemon.
//
// The purpose of DeviceSettingsService is to keep track of the current key and
// settings blob. For reading and writing device settings, use CrosSettings
// instead, which provides a high-level interface that allows for manipulation
// of individual settings.
//
// DeviceSettingsService generates notifications for key and policy update
// events so interested parties can reload state as appropriate.
class DeviceSettingsService : public SessionManagerClient::Observer {
 public:
  // Indicates ownership status of the device (listed in upgrade order).
  enum class OwnershipStatus {
    // These values are persisted to logs. Entries should not be renumbered and
    // numeric values should never be reused.
    kOwnershipUnknown = 0,
    // Not yet owned.
    kOwnershipNone = 1,
    // Either consumer ownership or cloud management.
    kOwnershipTaken = 2,
    kMaxValue = kOwnershipTaken
  };

  using OwnershipStatusCallback = base::OnceCallback<void(OwnershipStatus)>;
  using PolicyDataCallback =
      base::OnceCallback<void(enterprise_management::PolicyData*)>;

  // Status codes for Load() and Store().
  // These values are logged to UMA. Entries should not be renumbered and
  // numeric values should never be reused. Please keep in sync with
  // "DeviceSettingsStatus" in src/tools/metrics/histograms/enums.xml.
  enum Status {
    STORE_SUCCESS,
    STORE_KEY_UNAVAILABLE,   // Owner key not yet configured.
    STORE_OPERATION_FAILED,  // IPC to session_manager daemon failed.
    STORE_NO_POLICY,         // No settings blob present.
    STORE_INVALID_POLICY,    // Invalid settings blob (proto parse failed).
    STORE_VALIDATION_ERROR,  // Policy validation failure.
    kMaxValue = STORE_VALIDATION_ERROR,
  };

  // Observer interface.
  class Observer {
   public:
    virtual ~Observer();

    // Indicates device ownership status changes.  This is triggered upon every
    // browser start since the transition from uninitialized (OWNERSHIP_UNKNOWN)
    // to initialized (either of OWNERSHIP_{NONE,TAKEN}) also counts as an
    // ownership change.
    virtual void OwnershipStatusChanged();

    // Gets called after updates to the device settings.
    virtual void DeviceSettingsUpdated();

    virtual void OnDeviceSettingsServiceShutdown();
  };

  // Manage singleton instance.
  static void Initialize();
  static bool IsInitialized();
  static void Shutdown();
  static DeviceSettingsService* Get();

  // Returns a human-readable string describing |status|.
  static const char* StatusToString(Status status);

  // Creates a device settings service instance. This is meant for unit tests,
  // production code uses the singleton returned by Get() above.
  DeviceSettingsService();

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

  ~DeviceSettingsService() override;

  // To be called on startup once threads are initialized and D-Bus is ready.
  // `local_state` must be valid until `StopProcessing()`. `local_state` may be
  // null only in tests.
  void StartProcessing(PrefService* local_state,
                       SessionManagerClient* session_manager_client,
                       scoped_refptr<ownership::OwnerKeyUtil> owner_key_util);

  // Prevents the service from making further calls to session_manager_client
  // and stops any pending operations.
  void StopProcessing();

  // Must only be used with a |device_mode| that has been read and verified by
  // the InstallAttributes class.
  void SetDeviceMode(policy::DeviceMode device_mode);

  const enterprise_management::PolicyData* policy_data() const {
    return policy_data_.get();
  }

  const enterprise_management::PolicyFetchResponse* policy_fetch_response()
      const {
    return policy_fetch_response_.get();
  }

  // Returns the currently active device settings. Returns nullptr if the device
  // settings have not been retrieved from session_manager yet.
  const enterprise_management::ChromeDeviceSettingsProto* device_settings()
      const {
    return device_settings_.get();
  }

  // Returns the currently used owner key.
  scoped_refptr<ownership::PublicKey> GetPublicKey();

  // Returns the status generated by the *last operation*.
  // WARNING: It is not correct to take this method as an indication of whether
  // DeviceSettingsService contains valid device settings. In order to answer
  // that question, simply check whether device_settings() is different from
  // nullptr.
  Status status() const { return store_status_; }

  // Returns the currently device off hours controller. The returned pointer is
  // guaranteed to be non-null.
  policy::off_hours::DeviceOffHoursController* device_off_hours_controller()
      const {
    return device_off_hours_controller_.get();
  }

  void SetDeviceOffHoursControllerForTesting(
      std::unique_ptr<policy::off_hours::DeviceOffHoursController> controller);

  // Triggers an attempt to pull the public half of the owner key from disk and
  // load the device settings.
  void Load();

  // Attempts to load asynchronously the settings if they haven't been loaded
  // already and no request is in the queue. The aim is to avoid additional
  // request when not needed. Should NOT be used when the settings need to be
  // renewed, like in invalidations flow or when an explicit request from user
  // to reload is received.
  void LoadIfNotPresent();

  // Synchronously pulls the public key and loads the device settings.
  void LoadImmediately();

  // Stores a policy blob to session_manager. The result of the operation is
  // reported through |callback|. If successful, the updated device settings are
  // present in policy_data() and device_settings() when the callback runs.
  void Store(std::unique_ptr<enterprise_management::PolicyFetchResponse> policy,
             base::OnceClosure callback);

  // Returns the ownership status. May return OWNERSHIP_UNKNOWN if the disk
  // hasn't been checked yet.
  OwnershipStatus GetOwnershipStatus();

  // Determines the ownership status and reports the result to |callback|. This
  // is guaranteed to never return OWNERSHIP_UNKNOWN.
  virtual void GetOwnershipStatusAsync(OwnershipStatusCallback callback);

  // Checks whether we have the private owner key.
  //
  // DEPRECATED (ygorshenin@, crbug.com/433840): this method should
  // not be used since private key is a profile-specific resource and
  // should be checked and used in a profile-aware manner, through
  // OwnerSettingsService.
  bool HasPrivateOwnerKey();

  // Sets the identity of the user that's interacting with the service. This is
  // relevant only for writing settings through SignAndStore().
  //
  // TODO (ygorshenin@, crbug.com/433840): get rid of the method when
  // write path for device settings will be removed from
  // DeviceSettingsProvider and all existing clients will be switched
  // to OwnerSettingsServiceAsh.
  void InitOwner(const std::string& username,
                 const base::WeakPtr<ownership::OwnerSettingsService>&
                     owner_settings_service);

  const std::string& GetUsername() const;

  ownership::OwnerSettingsService* GetOwnerSettingsService() const;

  // Mark that the device will establish consumer ownership. If the flag is set
  // and ownership is not taken, policy reload will be deferred until InitOwner
  // is called. So that the ownership status is flipped after the private part
  // of owner is fully loaded.
  void MarkWillEstablishConsumerOwnership();

  // Returns whether the current user should take ownership of the device
  // (effectively whether the user is the first consumer user on the device).
  bool GetWillEstablishConsumerOwnership() const {
    return will_establish_consumer_ownership_;
  }

  // Returns if the device is managed according to the device settings.
  bool IsDeviceManaged() const;

  // Returns if the device policy is loaded and contains the DM token.
  bool HasDmToken() const;

  // Adds an observer.
  void AddObserver(Observer* observer);
  // Removes an observer.
  void RemoveObserver(Observer* observer);

  // SessionManagerClient::Observer:
  void OwnerKeySet(bool success) override;
  void PropertyChangeComplete(bool success) override;
  void SessionStopping() override;

 private:
  friend class OwnerSettingsServiceAsh;

  // Enqueues a new operation. Takes ownership of |operation| and starts it
  // right away if there is no active operation currently.
  void Enqueue(std::unique_ptr<SessionManagerOperation> operation);

  // Enqueues a load operation.
  void EnqueueLoad(bool request_key_load);

  // Makes sure there's a reload operation so changes to the settings (and key,
  // in case |request_key_load| is set) are getting picked up.
  void EnsureReload(bool request_key_load);

  // Runs the next pending operation.
  void StartNextOperation();

  // Updates status, policy data and owner key from a finished operation.
  void HandleCompletedOperation(base::OnceClosure callback,
                                SessionManagerOperation* operation,
                                Status status);

  // Same as HandleCompletedOperation(), but also starts the next pending
  // operation if available.
  void HandleCompletedAsyncOperation(base::OnceClosure callback,
                                     SessionManagerOperation* operation,
                                     Status status);

  // Helper method for GetOwnershipStatusAsync to avoid data race upon
  // user sign-in.
  void ValidateOwnershipStatusAndNotify(OwnershipStatusCallback callback);

  // Run OwnershipStatusChanged() for observers.
  void NotifyOwnershipStatusChanged() const;

  // Run DeviceSettingsUpdated() for observers.
  void NotifyDeviceSettingsUpdated() const;

  // Processes pending callbacks from GetOwnershipStatusAsync().
  void RunPendingOwnershipStatusCallbacks();

  raw_ptr<PrefService> local_state_ = nullptr;

  raw_ptr<SessionManagerClient> session_manager_client_ = nullptr;
  scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_;

  Status store_status_ = STORE_SUCCESS;

  std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_;

  std::string username_;
  scoped_refptr<ownership::PublicKey> public_key_;
  base::WeakPtr<ownership::OwnerSettingsService> owner_settings_service_;
  // Ownership status before the current session manager operation.
  OwnershipStatus previous_ownership_status_ =
      OwnershipStatus::kOwnershipUnknown;

  std::unique_ptr<enterprise_management::PolicyFetchResponse>
      policy_fetch_response_;
  std::unique_ptr<enterprise_management::PolicyData> policy_data_;
  std::unique_ptr<enterprise_management::ChromeDeviceSettingsProto>
      device_settings_;

  policy::DeviceMode device_mode_ = policy::DEVICE_MODE_PENDING;

  // The queue of pending operations. The first operation on the queue is
  // currently active; it gets removed and destroyed once it completes.
  base::circular_deque<std::unique_ptr<SessionManagerOperation>>
      pending_operations_;

  base::ObserverList<Observer>::Unchecked observers_;

  // Whether the device will be establishing consumer ownership.
  bool will_establish_consumer_ownership_ = false;

  // Whether we received the signal that the session is stopping.
  bool session_stopping_ = false;

  std::unique_ptr<policy::off_hours::DeviceOffHoursController>
      device_off_hours_controller_;

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

std::ostream& operator<<(std::ostream&, DeviceSettingsService::OwnershipStatus);

}  // namespace ash

#endif  // CHROME_BROWSER_ASH_SETTINGS_DEVICE_SETTINGS_SERVICE_H_