Chromium Code Reviews| Index: chrome/browser/chromeos/login/device_settings_service.h |
| diff --git a/chrome/browser/chromeos/login/device_settings_service.h b/chrome/browser/chromeos/login/device_settings_service.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..53d76ae30038b39374f0559db5fbfefe7bc774b4 |
| --- /dev/null |
| +++ b/chrome/browser/chromeos/login/device_settings_service.h |
| @@ -0,0 +1,243 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_DEVICE_SETTINGS_SERVICE_H_ |
| +#define CHROME_BROWSER_CHROMEOS_LOGIN_DEVICE_SETTINGS_SERVICE_H_ |
| + |
| +#include <deque> |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/basictypes.h" |
| +#include "base/callback.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/observer_list.h" |
| +#include "base/synchronization/lock.h" |
| +#include "chrome/browser/policy/cloud_policy_validator.h" |
| +#include "chromeos/dbus/session_manager_client.h" |
| + |
| +namespace base { |
| +template <typename T> struct DefaultLazyInstanceTraits; |
| +} |
| + |
| +namespace crypto { |
| +class RSAPrivateKey; |
| +} |
| + |
| +namespace enterprise_management { |
| +class ChromeDeviceSettingsProto; |
| +class PolicyData; |
| +} |
| + |
| +namespace chromeos { |
| + |
| +class OwnerKeyUtil; |
| +class SessionManagerOperation; |
| + |
| +// Keeps the public and private halves of the owner key. Both may be missing, |
| +// but if the private key is present, the public half will be as well. This |
| +// class is immutable and refcounted in order to allow safe access from any |
| +// thread. |
| +class OwnerKey : public base::RefCountedThreadSafe<OwnerKey> { |
| + public: |
| + OwnerKey(scoped_ptr<std::vector<uint8> > public_key, |
| + scoped_ptr<crypto::RSAPrivateKey> private_key); |
| + |
| + const std::vector<uint8>* public_key() { |
| + return public_key_.get(); |
| + } |
| + crypto::RSAPrivateKey* private_key() { |
| + return private_key_.get(); |
| + } |
| + |
| + private: |
| + friend class base::RefCountedThreadSafe<OwnerKey>; |
| + ~OwnerKey(); |
| + |
| + scoped_ptr<std::vector<uint8> > public_key_; |
| + scoped_ptr<crypto::RSAPrivateKey> private_key_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(OwnerKey); |
| +}; |
| + |
| +// Deals with the low-level interface to Chromium 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 and reload state as appropriate. |
|
pastarmovj
2012/07/30 12:19:19
Hmm something is missing in this sentence.
Mattias Nissler (ping if slow)
2012/07/31 13:02:15
Done.
|
| +class DeviceSettingsService : public SessionManagerClient::Observer { |
| + public: |
| + // Indicates ownership status of the device. |
| + enum OwnershipStatus { |
| + // Listed in upgrade order. |
| + OWNERSHIP_UNKNOWN = 0, |
| + OWNERSHIP_NONE, |
| + OWNERSHIP_TAKEN |
| + }; |
| + |
| + typedef base::Callback<void(OwnershipStatus, bool)> OwnershipStatusCallback; |
| + |
| + // Status codes for Store(). |
| + enum Status { |
| + STORE_SUCCESS, |
| + STORE_KEY_UNAVAILABLE, // Owner key not yet configured. |
| + STORE_POLICY_ERROR, // Failure constructing the settings blob. |
| + STORE_OPERATION_FAILED, // IPC to session_manager daemon failed. |
| + STORE_NO_POLICY, // No settings blob present. |
| + STORE_INVALID_POLICY, // Invalid settings blob. |
| + STORE_VALIDATION_ERROR, // Policy validation failure. |
| + }; |
| + |
| + // Observer interface. |
| + class Observer { |
| + public: |
| + virtual ~Observer(); |
| + |
| + // Indicates device ownership status changes. |
| + virtual void OwnershipStatusChanged() = 0; |
| + |
| + // Gets call after updates to the device settings. |
| + virtual void DeviceSettingsUpdated() = 0; |
| + }; |
| + |
| + // Creates a device settings service instance. This is meant for unit tests, |
| + // production code uses the singleton returned by Get() below. |
| + DeviceSettingsService(); |
|
pastarmovj
2012/07/30 12:19:19
Isn't it better to create another static method li
Mattias Nissler (ping if slow)
2012/07/31 13:02:15
How would you call a constructor by coincidence? C
pastarmovj
2012/08/01 08:46:52
What I meant by "coincidence" is somebody doing th
|
| + ~DeviceSettingsService(); |
| + |
| + // Returns the singleton instance. |
| + static DeviceSettingsService* Get(); |
| + |
| + // To be called on startup once threads are initialized and DBus is ready. |
| + void Initialize(SessionManagerClient* session_manager_client, |
| + scoped_refptr<OwnerKeyUtil> owner_key_util); |
| + void Shutdown(); |
|
pastarmovj
2012/07/30 12:19:19
Please document with one line. Now it feels more l
Mattias Nissler (ping if slow)
2012/07/31 13:02:15
Done.
|
| + |
| + // Returns the currently active device settings. Returns NULL if the device |
| + // settings have not yet been retrieved from session_manager yet. |
|
pastarmovj
2012/07/30 12:19:19
yet...yet. Please remove one of them.
Mattias Nissler (ping if slow)
2012/07/31 13:02:15
Done.
|
| + const enterprise_management::PolicyData* policy_data() { |
| + return policy_data_.get(); |
| + } |
| + const enterprise_management::ChromeDeviceSettingsProto* |
| + device_settings() const { |
| + return device_settings_.get(); |
| + } |
| + |
| + // Returns the currently used owner key. |
| + scoped_refptr<OwnerKey> GetOwnerKey(); |
| + |
| + // Returns the status generated by the last operation. |
| + Status status() { |
| + return store_status_; |
| + } |
| + |
| + // Triggers an attempt to pull the public half of the owner key from disk and |
| + // load the device settings. |
| + void Load(); |
| + |
| + // Signs |settings| with the private half of the owner key and sends the |
| + // resulting policy blob to session manager for storage. 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 SignAndStore( |
| + scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> settings, |
| + const base::Closure& callback); |
| + |
| + // 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(const std::string& policy_blob, const base::Closure& callback); |
| + |
| + // This method can be run either on FILE or UI threads. If |blocking| flag |
| + // is specified then it is guaranteed to return either OWNERSHIP_NONE or |
| + // OWNERSHIP_TAKEN (and not OWNERSHIP_UNKNOWN), however in this case it may |
| + // occasionally block doing I/O. |
| + // |
| + // TODO(mnissler, pastarmovj): Remove the blocking flag and only allow this on |
| + // the UI thread. |
|
pastarmovj
2012/07/30 12:19:19
FYI: I have an idea how we can get rid of the call
Mattias Nissler (ping if slow)
2012/07/31 13:02:15
I've fixed DeviceSettingsProvider in the second pa
|
| + OwnershipStatus GetOwnershipStatus(bool blocking); |
| + |
| + // Determines the ownership status and reports the result to |callback|. This |
| + // is guaranteed to never return OWNERSHIP_UNKNOWN. |
| + void GetOwnershipStatusAsync(const OwnershipStatusCallback& callback); |
| + |
| + // Checks whether we have the private owner key. |
| + bool HasPrivateOwnerKey(); |
| + |
| + // Sets the identity of the user that's interacting with the service. This is |
| + // relevant only for writing settings through SignAndStore(). |
| + void SetUsername(const std::string& username); |
| + const std::string& GetUsername() const; |
| + |
| + // Adds an observer. |
| + void AddObserver(Observer* observer); |
| + // Removes and observer. |
| + void RemoveObserver(Observer* observer); |
| + |
| + // SessionManagerClient::Observer: |
| + virtual void OwnerKeySet(bool success) OVERRIDE; |
| + virtual void PropertyChangeComplete(bool success) OVERRIDE; |
| + |
| + private: |
| + // Enqueues a new operation. Takes ownership of |operation| and starts it |
| + // right away if there is no active operation currently. |
| + void Enqueue(SessionManagerOperation* operation); |
| + |
| + // Enqueues a load operation. |
| + void EnqueueLoad(bool force_key_load); |
| + |
| + // Makes sure there's a reload operation so changes to the settings (and key, |
| + // in case force_key_load is set) are getting picked up. |
| + void EnsureReload(bool force_key_load); |
| + |
| + // Runs the next pending operation. |
| + void StartNextOperation(); |
| + |
| + // Updates status, policy data and owner key from a finished operation. |
| + // Starts the next pending operation if available. |
| + void HandleCompletedOperation(const base::Closure& callback, |
| + SessionManagerOperation* operation, |
| + Status status); |
| + |
| + // Sets ownership status. May be called on either thread. |
| + void SetOwnershipStatus(OwnershipStatus new_status); |
| + |
| + SessionManagerClient* session_manager_client_; |
| + scoped_refptr<OwnerKeyUtil> owner_key_util_; |
| + |
| + base::WeakPtrFactory<DeviceSettingsService> weak_factory_; |
| + |
| + Status store_status_; |
| + |
| + OwnershipStatus ownership_status_; |
| + base::Lock ownership_status_lock_; |
| + std::vector<OwnershipStatusCallback> pending_ownership_status_callbacks_; |
| + |
| + std::string username_; |
| + scoped_refptr<OwnerKey> owner_key_; |
| + |
| + scoped_ptr<enterprise_management::PolicyData> policy_data_; |
| + scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> device_settings_; |
| + |
| + // The queue of pending operations. The first operation on the queue is |
| + // currently active; it gets removed and destroyed once it completes. |
| + std::deque<SessionManagerOperation*> pending_operations_; |
| + |
| + ObserverList<Observer, true> observers_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DeviceSettingsService); |
| +}; |
| + |
| +} // namespace chromeos |
| + |
| +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_DEVICE_SETTINGS_SERVICE_H_ |