| OLD | NEW |
| (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 |
| OLD | NEW |