| Index: rlz/chromeos/lib/rlz_value_store_chromeos.cc
|
| diff --git a/rlz/win/lib/rlz_value_store_registry.cc b/rlz/chromeos/lib/rlz_value_store_chromeos.cc
|
| similarity index 10%
|
| copy from rlz/win/lib/rlz_value_store_registry.cc
|
| copy to rlz/chromeos/lib/rlz_value_store_chromeos.cc
|
| index 36c53d578a9f7ff6e9447c6e18602abcbea0ce7a..2f75887643a29e89ddb2ea7367bff28453468e29 100644
|
| --- a/rlz/win/lib/rlz_value_store_registry.cc
|
| +++ b/rlz/chromeos/lib/rlz_value_store_chromeos.cc
|
| @@ -2,383 +2,283 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "rlz/win/lib/rlz_value_store_registry.h"
|
| -
|
| -#include "base/win/registry.h"
|
| -#include "base/stringprintf.h"
|
| -#include "base/utf_string_conversions.h"
|
| -#include "rlz/lib/assert.h"
|
| +#include "rlz/chromeos/lib/rlz_value_store_chromeos.h"
|
| +
|
| +#include "base/file_path.h"
|
| +#include "base/file_util.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/singleton.h"
|
| +#include "base/prefs/json_pref_store.h"
|
| +#include "base/sequenced_task_runner.h"
|
| +#include "base/string_number_conversions.h"
|
| +#include "base/values.h"
|
| #include "rlz/lib/lib_values.h"
|
| +#include "rlz/lib/recursive_lock.h"
|
| #include "rlz/lib/rlz_lib.h"
|
| -#include "rlz/lib/string_utils.h"
|
| -#include "rlz/win/lib/registry_util.h"
|
|
|
| namespace rlz_lib {
|
|
|
| namespace {
|
|
|
| -//
|
| -// Registry keys:
|
| -//
|
| -// RLZ's are stored as:
|
| -// <AccessPointName> = <RLZ value> @ kRootKey\kLibKeyName\kRlzsSubkeyName.
|
| -//
|
| -// Events are stored as:
|
| -// <AccessPointName><EventName> = 1 @
|
| -// HKCU\kLibKeyName\kEventsSubkeyName\GetProductName(product).
|
| -//
|
| -// The OEM Deal Confirmation Code (DCC) is stored as
|
| -// kDccValueName = <DCC value> @ HKLM\kLibKeyName
|
| -//
|
| -// The last ping time, per product is stored as:
|
| -// GetProductName(product) = <last ping time> @
|
| -// HKCU\kLibKeyName\kPingTimesSubkeyName.
|
| -//
|
| -// The server does not care about any of these constants.
|
| -//
|
| -const char kLibKeyName[] = "Software\\Google\\Common\\Rlz";
|
| -const wchar_t kGoogleKeyName[] = L"Software\\Google";
|
| -const wchar_t kGoogleCommonKeyName[] = L"Software\\Google\\Common";
|
| -const char kRlzsSubkeyName[] = "RLZs";
|
| -const char kEventsSubkeyName[] = "Events";
|
| -const char kStatefulEventsSubkeyName[] = "StatefulEvents";
|
| -const char kPingTimesSubkeyName[] = "PTimes";
|
| -
|
| -std::wstring GetWideProductName(Product product) {
|
| - return ASCIIToWide(GetProductName(product));
|
| -}
|
| -
|
| -void AppendBrandToString(std::string* str) {
|
| - std::string brand(SupplementaryBranding::GetBrand());
|
| - if (!brand.empty())
|
| - base::StringAppendF(str, "\\_%s", brand.c_str());
|
| -}
|
| -
|
| -// Function to get the specific registry keys.
|
| -bool GetRegKey(const char* name, REGSAM access, base::win::RegKey* key) {
|
| - std::string key_location;
|
| - base::StringAppendF(&key_location, "%s\\%s", kLibKeyName, name);
|
| - AppendBrandToString(&key_location);
|
| -
|
| - LONG ret = ERROR_SUCCESS;
|
| - if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) {
|
| - ret = key->Create(HKEY_CURRENT_USER, ASCIIToWide(key_location).c_str(),
|
| - access);
|
| - } else {
|
| - ret = key->Open(HKEY_CURRENT_USER, ASCIIToWide(key_location).c_str(),
|
| - access);
|
| - }
|
| +// Product names.
|
| +const char kProductChrome[] = "chrome";
|
| +const char kProductOther[] = "other";
|
|
|
| - return ret == ERROR_SUCCESS;
|
| -}
|
| +// Key names.
|
| +const char kPingTimeKey[] = "ping_time";
|
| +const char kAccessPointKey[] = "access_points";
|
| +const char kProductEventKey[] = "product_events";
|
| +const char kStatefulEventKey[] = "stateful_events";
|
|
|
| -bool GetPingTimesRegKey(REGSAM access, base::win::RegKey* key) {
|
| - return GetRegKey(kPingTimesSubkeyName, access, key);
|
| -}
|
| +// Brand name used when there is no supplementary brand name.
|
| +const char kNoSupplementaryBrand[] = "_";
|
|
|
| +// RLZ store filename.
|
| +const FilePath::CharType kRLZDataFileName[] = FILE_PATH_LITERAL("RLZ Data");
|
|
|
| -bool GetEventsRegKey(const char* event_type,
|
| - const rlz_lib::Product* product,
|
| - REGSAM access, base::win::RegKey* key) {
|
| - std::string key_location;
|
| - base::StringAppendF(&key_location, "%s\\%s", kLibKeyName,
|
| - event_type);
|
| - AppendBrandToString(&key_location);
|
| +// RLZ store path for testing.
|
| +FilePath g_testing_rlz_store_path_;
|
|
|
| - if (product != NULL) {
|
| - std::string product_name = GetProductName(*product);
|
| - if (product_name.empty())
|
| - return false;
|
| -
|
| - base::StringAppendF(&key_location, "\\%s", product_name.c_str());
|
| - }
|
| -
|
| - LONG ret = ERROR_SUCCESS;
|
| - if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) {
|
| - ret = key->Create(HKEY_CURRENT_USER, ASCIIToWide(key_location).c_str(),
|
| - access);
|
| - } else {
|
| - ret = key->Open(HKEY_CURRENT_USER, ASCIIToWide(key_location).c_str(),
|
| - access);
|
| - }
|
| +// Returns file path of the RLZ storage.
|
| +FilePath GetRlzStorePath() {
|
| + return g_testing_rlz_store_path_.empty() ?
|
| + file_util::GetHomeDir().Append(kRLZDataFileName) :
|
| + g_testing_rlz_store_path_.Append(kRLZDataFileName);
|
| +}
|
|
|
| - return ret == ERROR_SUCCESS;
|
| +// Returns the dictionary key for storing access point-related prefs.
|
| +std::string GetKeyName(std::string key, AccessPoint access_point) {
|
| + std::string brand = SupplementaryBranding::GetBrand();
|
| + if (brand.empty())
|
| + brand = kNoSupplementaryBrand;
|
| + return key + "." + GetAccessPointName(access_point) + "." + brand;
|
| }
|
|
|
| -bool GetAccessPointRlzsRegKey(REGSAM access, base::win::RegKey* key) {
|
| - return GetRegKey(kRlzsSubkeyName, access, key);
|
| +// Returns the dictionary key for storing product-related prefs.
|
| +std::string GetKeyName(std::string key, Product product) {
|
| + std::string brand = SupplementaryBranding::GetBrand();
|
| + if (brand.empty())
|
| + brand = kNoSupplementaryBrand;
|
| + return key + "." + GetProductName(product) + "." + brand;
|
| }
|
|
|
| -bool ClearAllProductEventValues(rlz_lib::Product product, const char* key) {
|
| - std::wstring product_name = GetWideProductName(product);
|
| - if (product_name.empty())
|
| - return false;
|
| +} // namespace
|
|
|
| - base::win::RegKey reg_key;
|
| - GetEventsRegKey(key, NULL, KEY_WRITE, ®_key);
|
| - reg_key.DeleteKey(product_name.c_str());
|
| +// static
|
| +base::SequencedTaskRunner* RlzValueStoreChromeOS::io_task_runner_ = NULL;
|
|
|
| - // Verify that the value no longer exists.
|
| - base::win::RegKey product_events(
|
| - reg_key.Handle(), product_name.c_str(), KEY_READ);
|
| - if (product_events.Valid()) {
|
| - ASSERT_STRING("ClearAllProductEvents: Key deletion failed");
|
| - return false;
|
| - }
|
| +// static
|
| +bool RlzValueStoreChromeOS::created_;
|
|
|
| - return true;
|
| +// static
|
| +RlzValueStoreChromeOS* RlzValueStoreChromeOS::GetInstance() {
|
| + return Singleton<RlzValueStoreChromeOS>::get();
|
| }
|
|
|
| -// Deletes a registry key if it exists and has no subkeys or values.
|
| -// TODO: Move this to a registry_utils file and add unittest.
|
| -bool DeleteKeyIfEmpty(HKEY root_key, const wchar_t* key_name) {
|
| - if (!key_name) {
|
| - ASSERT_STRING("DeleteKeyIfEmpty: key_name is NULL");
|
| - return false;
|
| - } else { // Scope needed for RegKey
|
| - base::win::RegKey key(root_key, key_name, KEY_READ);
|
| - if (!key.Valid())
|
| - return true; // Key does not exist - nothing to do.
|
| -
|
| - base::win::RegistryKeyIterator key_iter(root_key, key_name);
|
| - if (key_iter.SubkeyCount() > 0)
|
| - return true; // Not empty, so nothing to do
|
| -
|
| - base::win::RegistryValueIterator value_iter(root_key, key_name);
|
| - if (value_iter.ValueCount() > 0)
|
| - return true; // Not empty, so nothing to do
|
| - }
|
| -
|
| - // The key is empty - delete it now.
|
| - base::win::RegKey key(root_key, L"", KEY_WRITE);
|
| - return key.DeleteKey(key_name) == ERROR_SUCCESS;
|
| +// static
|
| +void RlzValueStoreChromeOS::SetIOTaskRunner(
|
| + base::SequencedTaskRunner* io_task_runner) {
|
| + io_task_runner_ = io_task_runner;
|
| + // Make sure |io_task_runner_| lives until constructor is called.
|
| + io_task_runner_->AddRef();
|
| }
|
|
|
| -} // namespace
|
| -
|
| // static
|
| -std::wstring RlzValueStoreRegistry::GetWideLibKeyName() {
|
| - return ASCIIToWide(kLibKeyName);
|
| +void RlzValueStoreChromeOS::ResetForTesting() {
|
| + // Make sure we don't create an instance if it didn't exist.
|
| + if (created_)
|
| + GetInstance()->ReadPrefs();
|
| }
|
|
|
| -bool RlzValueStoreRegistry::HasAccess(AccessType type) {
|
| - return HasUserKeyAccess(type == kWriteAccess);
|
| +RlzValueStoreChromeOS::RlzValueStoreChromeOS() {
|
| + ReadPrefs();
|
| + created_ = true;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::WritePingTime(Product product, int64 time) {
|
| - base::win::RegKey key;
|
| - std::wstring product_name = GetWideProductName(product);
|
| - return GetPingTimesRegKey(KEY_WRITE, &key) &&
|
| - key.WriteValue(product_name.c_str(), &time, sizeof(time),
|
| - REG_QWORD) == ERROR_SUCCESS;
|
| +RlzValueStoreChromeOS::~RlzValueStoreChromeOS() {
|
| }
|
|
|
| -bool RlzValueStoreRegistry::ReadPingTime(Product product, int64* time) {
|
| - base::win::RegKey key;
|
| - std::wstring product_name = GetWideProductName(product);
|
| - return GetPingTimesRegKey(KEY_READ, &key) &&
|
| - key.ReadInt64(product_name.c_str(), time) == ERROR_SUCCESS;
|
| +bool RlzValueStoreChromeOS::HasAccess(AccessType type) {
|
| + return type == kReadAccess || !rlz_store_->ReadOnly();
|
| }
|
|
|
| -bool RlzValueStoreRegistry::ClearPingTime(Product product) {
|
| - base::win::RegKey key;
|
| - GetPingTimesRegKey(KEY_WRITE, &key);
|
| -
|
| - std::wstring product_name = GetWideProductName(product);
|
| - key.DeleteValue(product_name.c_str());
|
| +bool RlzValueStoreChromeOS::WritePingTime(Product product, int64 time) {
|
| + std::string value = base::Int64ToString(time);
|
| + rlz_store_->SetValue(GetKeyName(kPingTimeKey, product),
|
| + base::Value::CreateStringValue(value));
|
| + return true;
|
| +}
|
|
|
| - // Verify deletion.
|
| - uint64 value;
|
| - DWORD size = sizeof(value);
|
| - if (key.ReadValue(
|
| - product_name.c_str(), &value, &size, NULL) == ERROR_SUCCESS) {
|
| - ASSERT_STRING("RlzValueStoreRegistry::ClearPingTime: Failed to delete.");
|
| - return false;
|
| - }
|
| +bool RlzValueStoreChromeOS::ReadPingTime(Product product, int64* time) {
|
| + const base::Value* value = NULL;
|
| + rlz_store_->GetValue(GetKeyName(kPingTimeKey, product), &value);
|
| + std::string s_value;
|
| + return value && value->GetAsString(&s_value) &&
|
| + base::StringToInt64(s_value, time);
|
| +}
|
|
|
| +bool RlzValueStoreChromeOS::ClearPingTime(Product product) {
|
| + rlz_store_->RemoveValue(GetKeyName(kPingTimeKey, product));
|
| return true;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::WriteAccessPointRlz(AccessPoint access_point,
|
| +bool RlzValueStoreChromeOS::WriteAccessPointRlz(AccessPoint access_point,
|
| const char* new_rlz) {
|
| - const char* access_point_name = GetAccessPointName(access_point);
|
| - if (!access_point_name)
|
| - return false;
|
| -
|
| - std::wstring access_point_name_wide(ASCIIToWide(access_point_name));
|
| - base::win::RegKey key;
|
| - GetAccessPointRlzsRegKey(KEY_WRITE, &key);
|
| -
|
| - if (!RegKeyWriteValue(key, access_point_name_wide.c_str(), new_rlz)) {
|
| - ASSERT_STRING("SetAccessPointRlz: Could not write the new RLZ value");
|
| - return false;
|
| - }
|
| + rlz_store_->SetValue(
|
| + GetKeyName(kAccessPointKey, access_point),
|
| + base::Value::CreateStringValue(new_rlz));
|
| return true;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::ReadAccessPointRlz(AccessPoint access_point,
|
| +bool RlzValueStoreChromeOS::ReadAccessPointRlz(AccessPoint access_point,
|
| char* rlz,
|
| size_t rlz_size) {
|
| - const char* access_point_name = GetAccessPointName(access_point);
|
| - if (!access_point_name)
|
| - return false;
|
| -
|
| - size_t size = rlz_size;
|
| - base::win::RegKey key;
|
| - GetAccessPointRlzsRegKey(KEY_READ, &key);
|
| - if (!RegKeyReadValue(key, ASCIIToWide(access_point_name).c_str(),
|
| - rlz, &size)) {
|
| - rlz[0] = 0;
|
| - if (size > rlz_size) {
|
| - ASSERT_STRING("GetAccessPointRlz: Insufficient buffer size");
|
| - return false;
|
| - }
|
| + const base::Value* value = NULL;
|
| + rlz_store_->GetValue(
|
| + GetKeyName(kAccessPointKey, access_point), &value);
|
| + std::string s_value;
|
| + if (value)
|
| + value->GetAsString(&s_value);
|
| + if (s_value.size() < rlz_size) {
|
| + strncpy(rlz, s_value.c_str(), rlz_size);
|
| + return true;
|
| }
|
| - return true;
|
| + if (rlz_size > 0)
|
| + *rlz = '\0';
|
| + return false;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::ClearAccessPointRlz(AccessPoint access_point) {
|
| - const char* access_point_name = GetAccessPointName(access_point);
|
| - if (!access_point_name)
|
| - return false;
|
| -
|
| - std::wstring access_point_name_wide(ASCIIToWide(access_point_name));
|
| - base::win::RegKey key;
|
| - GetAccessPointRlzsRegKey(KEY_WRITE, &key);
|
| -
|
| - key.DeleteValue(access_point_name_wide.c_str());
|
| -
|
| - // Verify deletion.
|
| - DWORD value;
|
| - if (key.ReadValueDW(access_point_name_wide.c_str(), &value) ==
|
| - ERROR_SUCCESS) {
|
| - ASSERT_STRING("SetAccessPointRlz: Could not clear the RLZ value.");
|
| - return false;
|
| - }
|
| +bool RlzValueStoreChromeOS::ClearAccessPointRlz(AccessPoint access_point) {
|
| + rlz_store_->RemoveValue(
|
| + GetKeyName(kAccessPointKey, access_point));
|
| return true;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::AddProductEvent(Product product,
|
| +bool RlzValueStoreChromeOS::AddProductEvent(Product product,
|
| const char* event_rlz) {
|
| - std::wstring event_rlz_wide(ASCIIToWide(event_rlz));
|
| - base::win::RegKey reg_key;
|
| - GetEventsRegKey(kEventsSubkeyName, &product, KEY_WRITE, ®_key);
|
| - if (reg_key.WriteValue(event_rlz_wide.c_str(), 1) != ERROR_SUCCESS) {
|
| - ASSERT_STRING("AddProductEvent: Could not write the new event value");
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| + return AddValueToList(GetKeyName(kProductEventKey, product),
|
| + base::Value::CreateStringValue(event_rlz));
|
| }
|
|
|
| -bool RlzValueStoreRegistry::ReadProductEvents(Product product,
|
| - std::vector<std::string>* events) {
|
| - // Open the events key.
|
| - base::win::RegKey events_key;
|
| - GetEventsRegKey(kEventsSubkeyName, &product, KEY_READ, &events_key);
|
| - if (!events_key.Valid())
|
| +bool RlzValueStoreChromeOS::ReadProductEvents(
|
| + Product product,
|
| + std::vector<std::string>* events) {
|
| + base::ListValue* events_list = GetList(GetKeyName(kProductEventKey, product));
|
| + if (!events_list)
|
| return false;
|
| -
|
| - // Append the events to the buffer.
|
| - int num_values = 0;
|
| - LONG result = ERROR_SUCCESS;
|
| - for (num_values = 0; result == ERROR_SUCCESS; ++num_values) {
|
| - // Max 32767 bytes according to MSDN, but we never use that much.
|
| - const size_t kMaxValueNameLength = 2048;
|
| - char buffer[kMaxValueNameLength];
|
| - DWORD size = arraysize(buffer);
|
| -
|
| - result = RegEnumValueA(events_key.Handle(), num_values, buffer, &size,
|
| - NULL, NULL, NULL, NULL);
|
| - if (result == ERROR_SUCCESS)
|
| - events->push_back(std::string(buffer));
|
| + events->clear();
|
| + for (size_t i = 0; i < events_list->GetSize(); ++i) {
|
| + std::string event;
|
| + if (events_list->GetString(i, &event))
|
| + events->push_back(event);
|
| }
|
| -
|
| - return result == ERROR_NO_MORE_ITEMS;
|
| + return true;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::ClearProductEvent(Product product,
|
| +bool RlzValueStoreChromeOS::ClearProductEvent(Product product,
|
| const char* event_rlz) {
|
| - std::wstring event_rlz_wide(ASCIIToWide(event_rlz));
|
| - base::win::RegKey key;
|
| - GetEventsRegKey(kEventsSubkeyName, &product, KEY_WRITE, &key);
|
| - key.DeleteValue(event_rlz_wide.c_str());
|
| -
|
| - // Verify deletion.
|
| - DWORD value;
|
| - if (key.ReadValueDW(event_rlz_wide.c_str(), &value) == ERROR_SUCCESS) {
|
| - ASSERT_STRING("ClearProductEvent: Could not delete the event value.");
|
| - return false;
|
| - }
|
| + base::StringValue event_value(event_rlz);
|
| + return RemoveValueFromList(GetKeyName(kProductEventKey, product),
|
| + event_value);
|
| +}
|
|
|
| +bool RlzValueStoreChromeOS::ClearAllProductEvents(Product product) {
|
| + rlz_store_->RemoveValue(GetKeyName(kProductEventKey, product));
|
| return true;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::ClearAllProductEvents(Product product) {
|
| - return ClearAllProductEventValues(product, kEventsSubkeyName);
|
| +bool RlzValueStoreChromeOS::AddStatefulEvent(Product product,
|
| + const char* event_rlz) {
|
| + return AddValueToList(GetKeyName(kStatefulEventKey, product),
|
| + base::Value::CreateStringValue(event_rlz));
|
| }
|
|
|
| -bool RlzValueStoreRegistry::AddStatefulEvent(Product product,
|
| - const char* event_rlz) {
|
| - base::win::RegKey key;
|
| - std::wstring event_rlz_wide(ASCIIToWide(event_rlz));
|
| - if (!GetEventsRegKey(kStatefulEventsSubkeyName, &product, KEY_WRITE, &key) ||
|
| - key.WriteValue(event_rlz_wide.c_str(), 1) != ERROR_SUCCESS) {
|
| - ASSERT_STRING(
|
| - "AddStatefulEvent: Could not write the new stateful event");
|
| - return false;
|
| - }
|
| +bool RlzValueStoreChromeOS::IsStatefulEvent(Product product,
|
| + const char* event_rlz) {
|
| + base::ListValue* events_list =
|
| + GetList(GetKeyName(kStatefulEventKey, product));
|
| + base::StringValue event_value(event_rlz);
|
| + return events_list && events_list->Find(event_value) != events_list->end();
|
| +}
|
|
|
| +bool RlzValueStoreChromeOS::ClearAllStatefulEvents(Product product) {
|
| + rlz_store_->RemoveValue(GetKeyName(kStatefulEventKey, product));
|
| return true;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::IsStatefulEvent(Product product,
|
| - const char* event_rlz) {
|
| - DWORD value;
|
| - base::win::RegKey key;
|
| - GetEventsRegKey(kStatefulEventsSubkeyName, &product, KEY_READ, &key);
|
| - std::wstring event_rlz_wide(ASCIIToWide(event_rlz));
|
| - return key.ReadValueDW(event_rlz_wide.c_str(), &value) == ERROR_SUCCESS;
|
| +void RlzValueStoreChromeOS::CollectGarbage() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void RlzValueStoreChromeOS::ReadPrefs() {
|
| + DCHECK(io_task_runner_)
|
| + << "Calling GetInstance or ResetForTesting before SetIOTaskRunner?";
|
| + rlz_store_ = new JsonPrefStore(GetRlzStorePath(), io_task_runner_);
|
| + rlz_store_->ReadPrefs();
|
| + switch (rlz_store_->GetReadError()) {
|
| + case PersistentPrefStore::PREF_READ_ERROR_NONE:
|
| + case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
|
| + break;
|
| + default:
|
| + LOG(ERROR) << "Error read RLZ store: " << rlz_store_->GetReadError();
|
| + }
|
| + // Restore refcount modified by SetIOTaskRunner().
|
| + io_task_runner_->Release();
|
| + io_task_runner_ = NULL;
|
| }
|
|
|
| -bool RlzValueStoreRegistry::ClearAllStatefulEvents(Product product) {
|
| - return ClearAllProductEventValues(product, kStatefulEventsSubkeyName);
|
| +base::ListValue* RlzValueStoreChromeOS::GetList(std::string list_name) {
|
| + base::Value* list_value = NULL;
|
| + rlz_store_->GetMutableValue(list_name, &list_value);
|
| + base::ListValue* list = NULL;
|
| + if (!list_value || !list_value->GetAsList(&list))
|
| + return NULL;
|
| + return list;
|
| }
|
|
|
| -void RlzValueStoreRegistry::CollectGarbage() {
|
| - // Delete each of the known subkeys if empty.
|
| - const char* subkeys[] = {
|
| - kRlzsSubkeyName,
|
| - kEventsSubkeyName,
|
| - kStatefulEventsSubkeyName,
|
| - kPingTimesSubkeyName
|
| - };
|
| -
|
| - for (int i = 0; i < arraysize(subkeys); i++) {
|
| - std::string subkey_name;
|
| - base::StringAppendF(&subkey_name, "%s\\%s", kLibKeyName, subkeys[i]);
|
| - AppendBrandToString(&subkey_name);
|
| -
|
| - VERIFY(DeleteKeyIfEmpty(HKEY_CURRENT_USER,
|
| - ASCIIToWide(subkey_name).c_str()));
|
| +bool RlzValueStoreChromeOS::AddValueToList(std::string list_name,
|
| + base::Value* value) {
|
| + base::ListValue* list = GetList(list_name);
|
| + if (!list) {
|
| + list = new base::ListValue;
|
| + rlz_store_->SetValue(list_name, list);
|
| }
|
| + if (list->AppendIfNotPresent(value))
|
| + rlz_store_->ReportValueChanged(list_name);
|
| + return true;
|
| +}
|
|
|
| - // Delete the library key and its parents too now if empty.
|
| - VERIFY(DeleteKeyIfEmpty(HKEY_CURRENT_USER, GetWideLibKeyName().c_str()));
|
| - VERIFY(DeleteKeyIfEmpty(HKEY_CURRENT_USER, kGoogleCommonKeyName));
|
| - VERIFY(DeleteKeyIfEmpty(HKEY_CURRENT_USER, kGoogleKeyName));
|
| +bool RlzValueStoreChromeOS::RemoveValueFromList(std::string list_name,
|
| + const base::Value& value) {
|
| + base::ListValue* list = GetList(list_name);
|
| + if (!list)
|
| + return false;
|
| + rlz_store_->MarkNeedsEmptyValue(list_name);
|
| + size_t index;
|
| + if (list->Remove(value, &index))
|
| + rlz_store_->ReportValueChanged(list_name);
|
| + return true;
|
| }
|
|
|
| -ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() {
|
| - if (!lock_.failed())
|
| - store_.reset(new RlzValueStoreRegistry);
|
| +
|
| +ScopedRlzValueStoreLock::ScopedRlzValueStoreLock()
|
| + : store_(RlzValueStoreChromeOS::GetInstance()) {
|
| + DCHECK(store_->CalledOnValidThread());
|
| }
|
|
|
| ScopedRlzValueStoreLock::~ScopedRlzValueStoreLock() {
|
| }
|
|
|
| RlzValueStore* ScopedRlzValueStoreLock::GetStore() {
|
| - return store_.get();
|
| + return store_;
|
| }
|
|
|
| +namespace testing {
|
| +
|
| +void SetRlzStoreDirectory(const FilePath& directory) {
|
| + g_testing_rlz_store_path_ = directory;
|
| +}
|
| +
|
| +} // namespace testing
|
| +
|
| } // namespace rlz_lib
|
|
|