Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: chrome/browser/chromeos/settings/device_settings_service.cc

Issue 10828032: Add DeviceSettingsService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/settings/device_settings_service.h"
6
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/lazy_instance.h"
10 #include "base/logging.h"
11 #include "base/message_loop.h"
12 #include "base/stl_util.h"
13 #include "chrome/browser/chromeos/settings/owner_key_util.h"
14 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
15 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
16 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
17 #include "chrome/common/chrome_notification_types.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/notification_source.h"
21 #include "crypto/rsa_private_key.h"
22
23 namespace em = enterprise_management;
24
25 namespace chromeos {
26
27 static base::LazyInstance<DeviceSettingsService> g_device_settings_service =
28 LAZY_INSTANCE_INITIALIZER;
29
30 OwnerKey::OwnerKey(scoped_ptr<std::vector<uint8> > public_key,
31 scoped_ptr<crypto::RSAPrivateKey> private_key)
32 : public_key_(public_key.Pass()),
33 private_key_(private_key.Pass()) {}
34
35 OwnerKey::~OwnerKey() {}
36
37 DeviceSettingsService::Observer::~Observer() {}
38
39 DeviceSettingsService::DeviceSettingsService()
40 : session_manager_client_(NULL),
41 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
42 store_status_(STORE_SUCCESS) {}
43
44 DeviceSettingsService::~DeviceSettingsService() {
45 DCHECK(pending_operations_.empty());
46 }
47
48 // static
49 DeviceSettingsService* DeviceSettingsService::Get() {
50 return g_device_settings_service.Pointer();
51 }
52
53 void DeviceSettingsService::Initialize(
54 SessionManagerClient* session_manager_client,
55 scoped_refptr<OwnerKeyUtil> owner_key_util) {
56 DCHECK(session_manager_client);
57 DCHECK(owner_key_util.get());
58 DCHECK(!session_manager_client_);
59 DCHECK(!owner_key_util_.get());
60
61 session_manager_client_ = session_manager_client;
62 owner_key_util_ = owner_key_util;
63
64 session_manager_client_->AddObserver(this);
65
66 StartNextOperation();
67 }
68
69 void DeviceSettingsService::Shutdown() {
70 STLDeleteContainerPointers(pending_operations_.begin(),
71 pending_operations_.end());
72 pending_operations_.clear();
73
74 session_manager_client_->RemoveObserver(this);
75 session_manager_client_ = NULL;
76 owner_key_util_ = NULL;
77 }
78
79 scoped_refptr<OwnerKey> DeviceSettingsService::GetOwnerKey() {
80 return owner_key_;
81 }
82
83 void DeviceSettingsService::Load() {
84 EnqueueLoad(false);
85 }
86
87 void DeviceSettingsService::SignAndStore(
88 scoped_ptr<em::ChromeDeviceSettingsProto> new_settings,
89 const base::Closure& callback) {
90 Enqueue(
91 new SignAndStoreSettingsOperation(
92 base::Bind(&DeviceSettingsService::HandleCompletedOperation,
93 weak_factory_.GetWeakPtr(),
94 callback),
95 new_settings.Pass(),
96 username_));
97 }
98
99 void DeviceSettingsService::Store(const std::string& policy_blob,
100 const base::Closure& callback) {
101 Enqueue(
102 new StoreSettingsOperation(
103 base::Bind(&DeviceSettingsService::HandleCompletedOperation,
104 weak_factory_.GetWeakPtr(),
105 callback),
106 policy_blob));
107 }
108
109 DeviceSettingsService::OwnershipStatus
110 DeviceSettingsService::GetOwnershipStatus() {
111 if (owner_key_.get())
112 return owner_key_->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE;
113
114 return OWNERSHIP_UNKNOWN;
115 }
116
117 void DeviceSettingsService::GetOwnershipStatusAsync(
118 const OwnershipStatusCallback& callback) {
119 if (owner_key_.get()) {
120 // If there is a key, report status immediately.
121 MessageLoop::current()->PostTask(
122 FROM_HERE,
123 base::Bind(callback,
124 owner_key_->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE,
125 owner_key_->private_key() != NULL));
126 } else {
127 // If the key hasn't been loaded yet, enqueue the callback to be fired when
128 // the next SessionManagerOperation completes. If no operation is pending,
129 // start a load operation to fetch the key and report the result.
130 pending_ownership_status_callbacks_.push_back(callback);
131 if (pending_operations_.empty())
132 EnqueueLoad(false);
133 }
134 }
135
136 bool DeviceSettingsService::HasPrivateOwnerKey() {
137 return owner_key_.get() && owner_key_->private_key();
138 }
139
140 void DeviceSettingsService::SetUsername(const std::string& username) {
141 username_ = username;
142
143 // The private key may have become available, so force a key reload.
144 owner_key_ = NULL;
145 EnsureReload(true);
146 }
147
148 const std::string& DeviceSettingsService::GetUsername() const {
149 return username_;
150 }
151
152 void DeviceSettingsService::AddObserver(Observer* observer) {
153 observers_.AddObserver(observer);
154 }
155
156 void DeviceSettingsService::RemoveObserver(Observer* observer) {
157 observers_.RemoveObserver(observer);
158 }
159
160 void DeviceSettingsService::OwnerKeySet(bool success) {
161 if (!success) {
162 LOG(ERROR) << "Owner key change failed.";
163 return;
164 }
165
166 owner_key_ = NULL;
167 EnsureReload(true);
168 }
169
170 void DeviceSettingsService::PropertyChangeComplete(bool success) {
171 if (!success) {
172 LOG(ERROR) << "Policy update failed.";
173 return;
174 }
175
176 EnsureReload(false);
177 }
178
179 void DeviceSettingsService::Enqueue(SessionManagerOperation* operation) {
180 pending_operations_.push_back(operation);
181 if (pending_operations_.front() == operation)
182 StartNextOperation();
183 }
184
185 void DeviceSettingsService::EnqueueLoad(bool force_key_load) {
186 SessionManagerOperation* operation =
187 new LoadSettingsOperation(
188 base::Bind(&DeviceSettingsService::HandleCompletedOperation,
189 weak_factory_.GetWeakPtr(),
190 base::Closure()));
191 operation->set_force_key_load(force_key_load);
192 Enqueue(operation);
193 }
194
195 void DeviceSettingsService::EnsureReload(bool force_key_load) {
196 if (!pending_operations_.empty())
197 pending_operations_.front()->RestartLoad(force_key_load);
198 else
199 EnqueueLoad(force_key_load);
200 }
201
202 void DeviceSettingsService::StartNextOperation() {
203 if (!pending_operations_.empty() &&
204 session_manager_client_ &&
205 owner_key_util_.get()) {
206 pending_operations_.front()->Start(session_manager_client_,
207 owner_key_util_, owner_key_);
208 }
209 }
210
211 void DeviceSettingsService::HandleCompletedOperation(
212 const base::Closure& callback,
213 SessionManagerOperation* operation,
214 Status status) {
215 DCHECK_EQ(operation, pending_operations_.front());
216 store_status_ = status;
217
218 OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN;
219 bool is_owner = false;
220 scoped_refptr<OwnerKey> new_key(operation->owner_key());
221 if (new_key.get()) {
222 ownership_status =
223 new_key->public_key() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE;
224 is_owner = (new_key->private_key() != NULL);
225 } else {
226 NOTREACHED() << "Failed to determine key status.";
227 }
228
229 bool new_owner_key = false;
230 if (owner_key_.get() != new_key.get()) {
231 owner_key_ = new_key;
232 new_owner_key = true;
233 }
234
235 if (status == STORE_SUCCESS) {
236 policy_data_ = operation->policy_data().Pass();
237 device_settings_ = operation->device_settings().Pass();
238 } else if (status != STORE_KEY_UNAVAILABLE) {
239 LOG(ERROR) << "Session manager operation failed: " << status;
240 }
241
242 if (new_owner_key) {
243 FOR_EACH_OBSERVER(Observer, observers_, OwnershipStatusChanged());
244 content::NotificationService::current()->Notify(
245 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
246 content::Source<DeviceSettingsService>(this),
247 content::NotificationService::NoDetails());
248 }
249
250 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated());
251
252 std::vector<OwnershipStatusCallback> callbacks;
253 callbacks.swap(pending_ownership_status_callbacks_);
254 for (std::vector<OwnershipStatusCallback>::iterator iter(callbacks.begin());
255 iter != callbacks.end(); ++iter) {
256 iter->Run(ownership_status, is_owner);
257 }
258
259 // The completion callback happens after the notification so clients can
260 // filter self-triggered updates.
261 if (!callback.is_null())
262 callback.Run();
263
264 // Only remove the pending operation here, so new operations triggered by any
265 // of the callbacks above are queued up properly.
266 pending_operations_.pop_front();
267 delete operation;
268
269 StartNextOperation();
270 }
271
272 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698