Chromium Code Reviews| Index: chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc |
| diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2cbe6f7adf9373dc98fe9cda7bfbf192c1096ab6 |
| --- /dev/null |
| +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc |
| @@ -0,0 +1,206 @@ |
| +// Copyright 2014 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. |
| + |
| +#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/logging.h" |
| +#include "base/stl_util.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "base/values.h" |
| + |
| +namespace chromeos { |
| + |
| +namespace { |
| + |
| +const char kKeyBluetoothAddress[] = "bluetoothAddress"; |
| +const char kKeyPermitRecord[] = "permitRecord"; |
| +const char kKeyId[] = "id"; |
| +const char kKeyPermitId[] = "permitRecord.id"; |
| +const char kKeyPsk[] = "psk"; |
| + |
| +const char kKeyLabelPrefix[] = "easy-unlock-"; |
| + |
| +} // namespace |
| + |
| +EasyUnlockKeyManager::EasyUnlockKeyManager() |
| + : operation_id_(0), |
| + weak_ptr_factory_(this) { |
| +} |
| + |
| +EasyUnlockKeyManager::~EasyUnlockKeyManager() { |
| + STLDeleteContainerPairSecondPointers(get_keys_ops_.begin(), |
| + get_keys_ops_.end()); |
| +} |
| + |
| +void EasyUnlockKeyManager::RefreshKeys(const UserContext& user_context, |
| + const base::ListValue& remote_devices, |
| + const CreateKeysCallback& callback) { |
| + // Must have the secret. |
| + DCHECK(!user_context.GetKey()->GetSecret().empty()); |
| + |
| + EasyUnlockDeviceKeyDataList devices; |
| + if (!RemoteDeviceListToDeviceDataList(remote_devices, &devices)) |
| + devices.clear(); |
| + |
| + // Only one pending request. |
| + DCHECK(!create_keys_op_); |
| + create_keys_op_.reset(new EasyUnlockCreateKeysOperation( |
| + user_context, |
| + devices, |
| + base::Bind(&EasyUnlockKeyManager::OnKeysCreated, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + user_context, |
| + devices, |
| + callback))); |
| + create_keys_op_->Start(); |
| +} |
| + |
| +void EasyUnlockKeyManager::RemoveKeys(const UserContext& user_context, |
| + size_t start_index, |
| + const RemoveKeysCallback& callback) { |
| + // Must have the secret. |
| + DCHECK(!user_context.GetKey()->GetSecret().empty()); |
| + // Only one pending request. |
| + DCHECK(!remove_keys_op_); |
| + |
| + remove_keys_op_.reset( |
| + new EasyUnlockRemoveKeysOperation( |
| + user_context, |
| + start_index, |
| + base::Bind(&EasyUnlockKeyManager::OnKeysRemoved, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + callback))); |
| + remove_keys_op_->Start(); |
| +} |
| + |
| +void EasyUnlockKeyManager::GetDeviceDataList( |
| + const UserContext& user_context, |
| + const GetDeviceDataListCallback& callback) { |
|
tbarzic
2014/09/10 19:01:11
should this be throttled if there is create_keys_o
xiyuan
2014/09/10 20:37:13
This should not happen (at least not for the same
tbarzic
2014/09/10 20:43:39
sg
|
| + const int op_id = GetNextOperationId(); |
| + scoped_ptr<EasyUnlockGetKeysOperation> op(new EasyUnlockGetKeysOperation( |
| + user_context, |
| + base::Bind(&EasyUnlockKeyManager::OnKeysFetched, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + op_id, |
| + callback))); |
| + op->Start(); |
| + get_keys_ops_[op_id] = op.release(); |
| +} |
| + |
| +// static |
| +void EasyUnlockKeyManager::DeviceDataToRemoteDeviceDictionary( |
| + const EasyUnlockDeviceKeyData& data, |
| + base::DictionaryValue* dict) { |
| + dict->SetString(kKeyBluetoothAddress, data.bluetooth_address); |
| + dict->SetString(kKeyPsk, data.psk); |
| + scoped_ptr<base::DictionaryValue> permit_record(new base::DictionaryValue); |
| + permit_record->SetString(kKeyId, data.public_key); |
| + dict->Set(kKeyPermitRecord, permit_record.release()); |
| +} |
| + |
| +// static |
| +bool EasyUnlockKeyManager::RemoteDeviceDictionaryToDeviceData( |
| + const base::DictionaryValue& dict, |
| + EasyUnlockDeviceKeyData* data) { |
| + std::string bluetooth_address; |
| + std::string public_key; |
| + std::string psk; |
| + |
| + if (!dict.GetString(kKeyBluetoothAddress, &bluetooth_address) || |
| + !dict.GetString(kKeyPermitId, &public_key) || |
| + !dict.GetString(kKeyPsk, &psk)) { |
| + return false; |
| + } |
| + |
| + data->bluetooth_address.swap(bluetooth_address); |
| + data->public_key.swap(public_key); |
| + data->psk.swap(psk); |
| + return true; |
| +} |
| + |
| +// static |
| +void EasyUnlockKeyManager::DeviceDataListToRemoteDeviceList( |
| + const EasyUnlockDeviceKeyDataList& data_list, |
| + base::ListValue* device_list) { |
| + device_list->Clear(); |
| + for (size_t i = 0; i < data_list.size(); ++i) { |
| + scoped_ptr<base::DictionaryValue> device_dict(new base::DictionaryValue); |
| + DeviceDataToRemoteDeviceDictionary(data_list[i], device_dict.get()); |
| + device_list->Append(device_dict.release()); |
| + } |
| +} |
| + |
| +// static |
| +bool EasyUnlockKeyManager::RemoteDeviceListToDeviceDataList( |
| + const base::ListValue& device_list, |
| + EasyUnlockDeviceKeyDataList* data_list) { |
| + EasyUnlockDeviceKeyDataList parsed_devices; |
| + for (base::ListValue::const_iterator it = device_list.begin(); |
| + it != device_list.end(); |
| + ++it) { |
| + const base::DictionaryValue* dict; |
| + if (!(*it)->GetAsDictionary(&dict) || !dict) |
| + return false; |
| + |
| + EasyUnlockDeviceKeyData data; |
| + if (!RemoteDeviceDictionaryToDeviceData(*dict, &data)) |
| + return false; |
| + |
| + parsed_devices.push_back(data); |
| + } |
| + |
| + data_list->swap(parsed_devices); |
| + return true; |
| +} |
| + |
| +// static |
| +std::string EasyUnlockKeyManager::GetKeyLabel(size_t key_index) { |
| + return base::StringPrintf("%s%zu", kKeyLabelPrefix, key_index); |
| +} |
| + |
| +int EasyUnlockKeyManager::GetNextOperationId() { |
| + return ++operation_id_; |
| +} |
| + |
| +void EasyUnlockKeyManager::OnKeysCreated( |
| + const UserContext& user_context, |
| + const EasyUnlockDeviceKeyDataList& devices, |
| + const CreateKeysCallback& callback, |
| + bool create_success) { |
| + scoped_ptr<EasyUnlockCreateKeysOperation> op = create_keys_op_.Pass(); |
| + if (!callback.is_null()) |
| + callback.Run(create_success); |
| + |
| + // Remove extra existing keys. |
| + RemoveKeys(user_context, devices.size(), RemoveKeysCallback()); |
| +} |
| + |
| +void EasyUnlockKeyManager::OnKeysRemoved(const RemoveKeysCallback& callback, |
| + bool remove_success) { |
| + scoped_ptr<EasyUnlockRemoveKeysOperation> op = remove_keys_op_.Pass(); |
| + if (!callback.is_null()) |
| + callback.Run(remove_success); |
| +} |
| + |
| +void EasyUnlockKeyManager::OnKeysFetched( |
| + int op_id, |
| + const GetDeviceDataListCallback& callback, |
| + bool fetch_success, |
| + const EasyUnlockDeviceKeyDataList& fetched_data) { |
| + std::map<int, EasyUnlockGetKeysOperation*>::iterator it = |
| + get_keys_ops_.find(op_id); |
| + scoped_ptr<EasyUnlockGetKeysOperation> op; |
| + if (it != get_keys_ops_.end()) { |
| + op.reset(it->second); |
| + get_keys_ops_.erase(it); |
| + } else { |
| + NOTREACHED(); |
| + } |
| + |
| + if (!callback.is_null()) |
| + callback.Run(fetch_success, fetched_data); |
| +} |
| + |
| +} // namespace chromeos |