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 |