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

Side by Side Diff: rlz/chromeos/lib/rlz_value_store_chromeos.cc

Issue 11365107: [cros] RlzValueStore implementation for ChromeOS. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revert to Chrome-only Created 8 years, 1 month 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
« no previous file with comments | « rlz/chromeos/lib/rlz_value_store_chromeos.h ('k') | rlz/lib/financial_ping.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "rlz/win/lib/rlz_value_store_registry.h" 5 #include "rlz/chromeos/lib/rlz_value_store_chromeos.h"
6 6
7 #include "base/win/registry.h" 7 #include "base/file_path.h"
8 #include "base/stringprintf.h" 8 #include "base/file_util.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/logging.h"
10 #include "rlz/lib/assert.h" 10 #include "base/memory/singleton.h"
11 #include "base/prefs/json_pref_store.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/string_number_conversions.h"
14 #include "base/values.h"
11 #include "rlz/lib/lib_values.h" 15 #include "rlz/lib/lib_values.h"
16 #include "rlz/lib/recursive_lock.h"
12 #include "rlz/lib/rlz_lib.h" 17 #include "rlz/lib/rlz_lib.h"
13 #include "rlz/lib/string_utils.h"
14 #include "rlz/win/lib/registry_util.h"
15 18
16 namespace rlz_lib { 19 namespace rlz_lib {
17 20
18 namespace { 21 namespace {
19 22
20 // 23 // Product names.
21 // Registry keys: 24 const char kProductChrome[] = "chrome";
22 // 25 const char kProductOther[] = "other";
23 // RLZ's are stored as: 26
24 // <AccessPointName> = <RLZ value> @ kRootKey\kLibKeyName\kRlzsSubkeyName. 27 // Key names.
25 // 28 const char kPingTimeKey[] = "ping_time";
26 // Events are stored as: 29 const char kAccessPointKey[] = "access_points";
27 // <AccessPointName><EventName> = 1 @ 30 const char kProductEventKey[] = "product_events";
28 // HKCU\kLibKeyName\kEventsSubkeyName\GetProductName(product). 31 const char kStatefulEventKey[] = "stateful_events";
29 // 32
30 // The OEM Deal Confirmation Code (DCC) is stored as 33 // Brand name used when there is no supplementary brand name.
31 // kDccValueName = <DCC value> @ HKLM\kLibKeyName 34 const char kNoSupplementaryBrand[] = "_";
32 // 35
33 // The last ping time, per product is stored as: 36 // RLZ store filename.
34 // GetProductName(product) = <last ping time> @ 37 const FilePath::CharType kRLZDataFileName[] = FILE_PATH_LITERAL("RLZ Data");
35 // HKCU\kLibKeyName\kPingTimesSubkeyName. 38
36 // 39 // RLZ store path for testing.
37 // The server does not care about any of these constants. 40 FilePath g_testing_rlz_store_path_;
38 // 41
39 const char kLibKeyName[] = "Software\\Google\\Common\\Rlz"; 42 // Returns file path of the RLZ storage.
40 const wchar_t kGoogleKeyName[] = L"Software\\Google"; 43 FilePath GetRlzStorePath() {
41 const wchar_t kGoogleCommonKeyName[] = L"Software\\Google\\Common"; 44 return g_testing_rlz_store_path_.empty() ?
42 const char kRlzsSubkeyName[] = "RLZs"; 45 file_util::GetHomeDir().Append(kRLZDataFileName) :
43 const char kEventsSubkeyName[] = "Events"; 46 g_testing_rlz_store_path_.Append(kRLZDataFileName);
44 const char kStatefulEventsSubkeyName[] = "StatefulEvents"; 47 }
45 const char kPingTimesSubkeyName[] = "PTimes"; 48
46 49 // Returns the dictionary key for storing access point-related prefs.
47 std::wstring GetWideProductName(Product product) { 50 std::string GetKeyName(std::string key, AccessPoint access_point) {
48 return ASCIIToWide(GetProductName(product)); 51 std::string brand = SupplementaryBranding::GetBrand();
49 } 52 if (brand.empty())
50 53 brand = kNoSupplementaryBrand;
51 void AppendBrandToString(std::string* str) { 54 return key + "." + GetAccessPointName(access_point) + "." + brand;
52 std::string brand(SupplementaryBranding::GetBrand()); 55 }
53 if (!brand.empty()) 56
54 base::StringAppendF(str, "\\_%s", brand.c_str()); 57 // Returns the dictionary key for storing product-related prefs.
55 } 58 std::string GetKeyName(std::string key, Product product) {
56 59 std::string brand = SupplementaryBranding::GetBrand();
57 // Function to get the specific registry keys. 60 if (brand.empty())
58 bool GetRegKey(const char* name, REGSAM access, base::win::RegKey* key) { 61 brand = kNoSupplementaryBrand;
59 std::string key_location; 62 return key + "." + GetProductName(product) + "." + brand;
60 base::StringAppendF(&key_location, "%s\\%s", kLibKeyName, name);
61 AppendBrandToString(&key_location);
62
63 LONG ret = ERROR_SUCCESS;
64 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) {
65 ret = key->Create(HKEY_CURRENT_USER, ASCIIToWide(key_location).c_str(),
66 access);
67 } else {
68 ret = key->Open(HKEY_CURRENT_USER, ASCIIToWide(key_location).c_str(),
69 access);
70 }
71
72 return ret == ERROR_SUCCESS;
73 }
74
75 bool GetPingTimesRegKey(REGSAM access, base::win::RegKey* key) {
76 return GetRegKey(kPingTimesSubkeyName, access, key);
77 }
78
79
80 bool GetEventsRegKey(const char* event_type,
81 const rlz_lib::Product* product,
82 REGSAM access, base::win::RegKey* key) {
83 std::string key_location;
84 base::StringAppendF(&key_location, "%s\\%s", kLibKeyName,
85 event_type);
86 AppendBrandToString(&key_location);
87
88 if (product != NULL) {
89 std::string product_name = GetProductName(*product);
90 if (product_name.empty())
91 return false;
92
93 base::StringAppendF(&key_location, "\\%s", product_name.c_str());
94 }
95
96 LONG ret = ERROR_SUCCESS;
97 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) {
98 ret = key->Create(HKEY_CURRENT_USER, ASCIIToWide(key_location).c_str(),
99 access);
100 } else {
101 ret = key->Open(HKEY_CURRENT_USER, ASCIIToWide(key_location).c_str(),
102 access);
103 }
104
105 return ret == ERROR_SUCCESS;
106 }
107
108 bool GetAccessPointRlzsRegKey(REGSAM access, base::win::RegKey* key) {
109 return GetRegKey(kRlzsSubkeyName, access, key);
110 }
111
112 bool ClearAllProductEventValues(rlz_lib::Product product, const char* key) {
113 std::wstring product_name = GetWideProductName(product);
114 if (product_name.empty())
115 return false;
116
117 base::win::RegKey reg_key;
118 GetEventsRegKey(key, NULL, KEY_WRITE, &reg_key);
119 reg_key.DeleteKey(product_name.c_str());
120
121 // Verify that the value no longer exists.
122 base::win::RegKey product_events(
123 reg_key.Handle(), product_name.c_str(), KEY_READ);
124 if (product_events.Valid()) {
125 ASSERT_STRING("ClearAllProductEvents: Key deletion failed");
126 return false;
127 }
128
129 return true;
130 }
131
132 // Deletes a registry key if it exists and has no subkeys or values.
133 // TODO: Move this to a registry_utils file and add unittest.
134 bool DeleteKeyIfEmpty(HKEY root_key, const wchar_t* key_name) {
135 if (!key_name) {
136 ASSERT_STRING("DeleteKeyIfEmpty: key_name is NULL");
137 return false;
138 } else { // Scope needed for RegKey
139 base::win::RegKey key(root_key, key_name, KEY_READ);
140 if (!key.Valid())
141 return true; // Key does not exist - nothing to do.
142
143 base::win::RegistryKeyIterator key_iter(root_key, key_name);
144 if (key_iter.SubkeyCount() > 0)
145 return true; // Not empty, so nothing to do
146
147 base::win::RegistryValueIterator value_iter(root_key, key_name);
148 if (value_iter.ValueCount() > 0)
149 return true; // Not empty, so nothing to do
150 }
151
152 // The key is empty - delete it now.
153 base::win::RegKey key(root_key, L"", KEY_WRITE);
154 return key.DeleteKey(key_name) == ERROR_SUCCESS;
155 } 63 }
156 64
157 } // namespace 65 } // namespace
158 66
159 // static 67 // static
160 std::wstring RlzValueStoreRegistry::GetWideLibKeyName() { 68 base::SequencedTaskRunner* RlzValueStoreChromeOS::io_task_runner_ = NULL;
161 return ASCIIToWide(kLibKeyName); 69
162 } 70 // static
163 71 bool RlzValueStoreChromeOS::created_;
164 bool RlzValueStoreRegistry::HasAccess(AccessType type) { 72
165 return HasUserKeyAccess(type == kWriteAccess); 73 // static
166 } 74 RlzValueStoreChromeOS* RlzValueStoreChromeOS::GetInstance() {
167 75 return Singleton<RlzValueStoreChromeOS>::get();
168 bool RlzValueStoreRegistry::WritePingTime(Product product, int64 time) { 76 }
169 base::win::RegKey key; 77
170 std::wstring product_name = GetWideProductName(product); 78 // static
171 return GetPingTimesRegKey(KEY_WRITE, &key) && 79 void RlzValueStoreChromeOS::SetIOTaskRunner(
172 key.WriteValue(product_name.c_str(), &time, sizeof(time), 80 base::SequencedTaskRunner* io_task_runner) {
173 REG_QWORD) == ERROR_SUCCESS; 81 io_task_runner_ = io_task_runner;
174 } 82 // Make sure |io_task_runner_| lives until constructor is called.
175 83 io_task_runner_->AddRef();
176 bool RlzValueStoreRegistry::ReadPingTime(Product product, int64* time) { 84 }
177 base::win::RegKey key; 85
178 std::wstring product_name = GetWideProductName(product); 86 // static
179 return GetPingTimesRegKey(KEY_READ, &key) && 87 void RlzValueStoreChromeOS::ResetForTesting() {
180 key.ReadInt64(product_name.c_str(), time) == ERROR_SUCCESS; 88 // Make sure we don't create an instance if it didn't exist.
181 } 89 if (created_)
182 90 GetInstance()->ReadPrefs();
183 bool RlzValueStoreRegistry::ClearPingTime(Product product) { 91 }
184 base::win::RegKey key; 92
185 GetPingTimesRegKey(KEY_WRITE, &key); 93 RlzValueStoreChromeOS::RlzValueStoreChromeOS() {
186 94 ReadPrefs();
187 std::wstring product_name = GetWideProductName(product); 95 created_ = true;
188 key.DeleteValue(product_name.c_str()); 96 }
189 97
190 // Verify deletion. 98 RlzValueStoreChromeOS::~RlzValueStoreChromeOS() {
191 uint64 value; 99 }
192 DWORD size = sizeof(value); 100
193 if (key.ReadValue( 101 bool RlzValueStoreChromeOS::HasAccess(AccessType type) {
194 product_name.c_str(), &value, &size, NULL) == ERROR_SUCCESS) { 102 return type == kReadAccess || !rlz_store_->ReadOnly();
195 ASSERT_STRING("RlzValueStoreRegistry::ClearPingTime: Failed to delete."); 103 }
196 return false; 104
197 } 105 bool RlzValueStoreChromeOS::WritePingTime(Product product, int64 time) {
198 106 std::string value = base::Int64ToString(time);
199 return true; 107 rlz_store_->SetValue(GetKeyName(kPingTimeKey, product),
200 } 108 base::Value::CreateStringValue(value));
201 109 return true;
202 bool RlzValueStoreRegistry::WriteAccessPointRlz(AccessPoint access_point, 110 }
111
112 bool RlzValueStoreChromeOS::ReadPingTime(Product product, int64* time) {
113 const base::Value* value = NULL;
114 rlz_store_->GetValue(GetKeyName(kPingTimeKey, product), &value);
115 std::string s_value;
116 return value && value->GetAsString(&s_value) &&
117 base::StringToInt64(s_value, time);
118 }
119
120 bool RlzValueStoreChromeOS::ClearPingTime(Product product) {
121 rlz_store_->RemoveValue(GetKeyName(kPingTimeKey, product));
122 return true;
123 }
124
125 bool RlzValueStoreChromeOS::WriteAccessPointRlz(AccessPoint access_point,
203 const char* new_rlz) { 126 const char* new_rlz) {
204 const char* access_point_name = GetAccessPointName(access_point); 127 rlz_store_->SetValue(
205 if (!access_point_name) 128 GetKeyName(kAccessPointKey, access_point),
206 return false; 129 base::Value::CreateStringValue(new_rlz));
207 130 return true;
208 std::wstring access_point_name_wide(ASCIIToWide(access_point_name)); 131 }
209 base::win::RegKey key; 132
210 GetAccessPointRlzsRegKey(KEY_WRITE, &key); 133 bool RlzValueStoreChromeOS::ReadAccessPointRlz(AccessPoint access_point,
211
212 if (!RegKeyWriteValue(key, access_point_name_wide.c_str(), new_rlz)) {
213 ASSERT_STRING("SetAccessPointRlz: Could not write the new RLZ value");
214 return false;
215 }
216 return true;
217 }
218
219 bool RlzValueStoreRegistry::ReadAccessPointRlz(AccessPoint access_point,
220 char* rlz, 134 char* rlz,
221 size_t rlz_size) { 135 size_t rlz_size) {
222 const char* access_point_name = GetAccessPointName(access_point); 136 const base::Value* value = NULL;
223 if (!access_point_name) 137 rlz_store_->GetValue(
138 GetKeyName(kAccessPointKey, access_point), &value);
139 std::string s_value;
140 if (value)
141 value->GetAsString(&s_value);
142 if (s_value.size() < rlz_size) {
143 strncpy(rlz, s_value.c_str(), rlz_size);
144 return true;
145 }
146 if (rlz_size > 0)
147 *rlz = '\0';
148 return false;
149 }
150
151 bool RlzValueStoreChromeOS::ClearAccessPointRlz(AccessPoint access_point) {
152 rlz_store_->RemoveValue(
153 GetKeyName(kAccessPointKey, access_point));
154 return true;
155 }
156
157 bool RlzValueStoreChromeOS::AddProductEvent(Product product,
158 const char* event_rlz) {
159 return AddValueToList(GetKeyName(kProductEventKey, product),
160 base::Value::CreateStringValue(event_rlz));
161 }
162
163 bool RlzValueStoreChromeOS::ReadProductEvents(
164 Product product,
165 std::vector<std::string>* events) {
166 base::ListValue* events_list = GetList(GetKeyName(kProductEventKey, product));
167 if (!events_list)
224 return false; 168 return false;
225 169 events->clear();
226 size_t size = rlz_size; 170 for (size_t i = 0; i < events_list->GetSize(); ++i) {
227 base::win::RegKey key; 171 std::string event;
228 GetAccessPointRlzsRegKey(KEY_READ, &key); 172 if (events_list->GetString(i, &event))
229 if (!RegKeyReadValue(key, ASCIIToWide(access_point_name).c_str(), 173 events->push_back(event);
230 rlz, &size)) { 174 }
231 rlz[0] = 0; 175 return true;
232 if (size > rlz_size) { 176 }
233 ASSERT_STRING("GetAccessPointRlz: Insufficient buffer size"); 177
234 return false; 178 bool RlzValueStoreChromeOS::ClearProductEvent(Product product,
235 } 179 const char* event_rlz) {
236 } 180 base::StringValue event_value(event_rlz);
237 return true; 181 return RemoveValueFromList(GetKeyName(kProductEventKey, product),
238 } 182 event_value);
239 183 }
240 bool RlzValueStoreRegistry::ClearAccessPointRlz(AccessPoint access_point) { 184
241 const char* access_point_name = GetAccessPointName(access_point); 185 bool RlzValueStoreChromeOS::ClearAllProductEvents(Product product) {
242 if (!access_point_name) 186 rlz_store_->RemoveValue(GetKeyName(kProductEventKey, product));
187 return true;
188 }
189
190 bool RlzValueStoreChromeOS::AddStatefulEvent(Product product,
191 const char* event_rlz) {
192 return AddValueToList(GetKeyName(kStatefulEventKey, product),
193 base::Value::CreateStringValue(event_rlz));
194 }
195
196 bool RlzValueStoreChromeOS::IsStatefulEvent(Product product,
197 const char* event_rlz) {
198 base::ListValue* events_list =
199 GetList(GetKeyName(kStatefulEventKey, product));
200 base::StringValue event_value(event_rlz);
201 return events_list && events_list->Find(event_value) != events_list->end();
202 }
203
204 bool RlzValueStoreChromeOS::ClearAllStatefulEvents(Product product) {
205 rlz_store_->RemoveValue(GetKeyName(kStatefulEventKey, product));
206 return true;
207 }
208
209 void RlzValueStoreChromeOS::CollectGarbage() {
210 NOTIMPLEMENTED();
211 }
212
213 void RlzValueStoreChromeOS::ReadPrefs() {
214 DCHECK(io_task_runner_)
215 << "Calling GetInstance or ResetForTesting before SetIOTaskRunner?";
216 rlz_store_ = new JsonPrefStore(GetRlzStorePath(), io_task_runner_);
217 rlz_store_->ReadPrefs();
218 switch (rlz_store_->GetReadError()) {
219 case PersistentPrefStore::PREF_READ_ERROR_NONE:
220 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
221 break;
222 default:
223 LOG(ERROR) << "Error read RLZ store: " << rlz_store_->GetReadError();
224 }
225 // Restore refcount modified by SetIOTaskRunner().
226 io_task_runner_->Release();
227 io_task_runner_ = NULL;
228 }
229
230 base::ListValue* RlzValueStoreChromeOS::GetList(std::string list_name) {
231 base::Value* list_value = NULL;
232 rlz_store_->GetMutableValue(list_name, &list_value);
233 base::ListValue* list = NULL;
234 if (!list_value || !list_value->GetAsList(&list))
235 return NULL;
236 return list;
237 }
238
239 bool RlzValueStoreChromeOS::AddValueToList(std::string list_name,
240 base::Value* value) {
241 base::ListValue* list = GetList(list_name);
242 if (!list) {
243 list = new base::ListValue;
244 rlz_store_->SetValue(list_name, list);
245 }
246 if (list->AppendIfNotPresent(value))
247 rlz_store_->ReportValueChanged(list_name);
248 return true;
249 }
250
251 bool RlzValueStoreChromeOS::RemoveValueFromList(std::string list_name,
252 const base::Value& value) {
253 base::ListValue* list = GetList(list_name);
254 if (!list)
243 return false; 255 return false;
244 256 rlz_store_->MarkNeedsEmptyValue(list_name);
245 std::wstring access_point_name_wide(ASCIIToWide(access_point_name)); 257 size_t index;
246 base::win::RegKey key; 258 if (list->Remove(value, &index))
247 GetAccessPointRlzsRegKey(KEY_WRITE, &key); 259 rlz_store_->ReportValueChanged(list_name);
248 260 return true;
249 key.DeleteValue(access_point_name_wide.c_str()); 261 }
250 262
251 // Verify deletion. 263
252 DWORD value; 264 ScopedRlzValueStoreLock::ScopedRlzValueStoreLock()
253 if (key.ReadValueDW(access_point_name_wide.c_str(), &value) == 265 : store_(RlzValueStoreChromeOS::GetInstance()) {
254 ERROR_SUCCESS) { 266 DCHECK(store_->CalledOnValidThread());
255 ASSERT_STRING("SetAccessPointRlz: Could not clear the RLZ value.");
256 return false;
257 }
258 return true;
259 }
260
261 bool RlzValueStoreRegistry::AddProductEvent(Product product,
262 const char* event_rlz) {
263 std::wstring event_rlz_wide(ASCIIToWide(event_rlz));
264 base::win::RegKey reg_key;
265 GetEventsRegKey(kEventsSubkeyName, &product, KEY_WRITE, &reg_key);
266 if (reg_key.WriteValue(event_rlz_wide.c_str(), 1) != ERROR_SUCCESS) {
267 ASSERT_STRING("AddProductEvent: Could not write the new event value");
268 return false;
269 }
270
271 return true;
272 }
273
274 bool RlzValueStoreRegistry::ReadProductEvents(Product product,
275 std::vector<std::string>* events) {
276 // Open the events key.
277 base::win::RegKey events_key;
278 GetEventsRegKey(kEventsSubkeyName, &product, KEY_READ, &events_key);
279 if (!events_key.Valid())
280 return false;
281
282 // Append the events to the buffer.
283 int num_values = 0;
284 LONG result = ERROR_SUCCESS;
285 for (num_values = 0; result == ERROR_SUCCESS; ++num_values) {
286 // Max 32767 bytes according to MSDN, but we never use that much.
287 const size_t kMaxValueNameLength = 2048;
288 char buffer[kMaxValueNameLength];
289 DWORD size = arraysize(buffer);
290
291 result = RegEnumValueA(events_key.Handle(), num_values, buffer, &size,
292 NULL, NULL, NULL, NULL);
293 if (result == ERROR_SUCCESS)
294 events->push_back(std::string(buffer));
295 }
296
297 return result == ERROR_NO_MORE_ITEMS;
298 }
299
300 bool RlzValueStoreRegistry::ClearProductEvent(Product product,
301 const char* event_rlz) {
302 std::wstring event_rlz_wide(ASCIIToWide(event_rlz));
303 base::win::RegKey key;
304 GetEventsRegKey(kEventsSubkeyName, &product, KEY_WRITE, &key);
305 key.DeleteValue(event_rlz_wide.c_str());
306
307 // Verify deletion.
308 DWORD value;
309 if (key.ReadValueDW(event_rlz_wide.c_str(), &value) == ERROR_SUCCESS) {
310 ASSERT_STRING("ClearProductEvent: Could not delete the event value.");
311 return false;
312 }
313
314 return true;
315 }
316
317 bool RlzValueStoreRegistry::ClearAllProductEvents(Product product) {
318 return ClearAllProductEventValues(product, kEventsSubkeyName);
319 }
320
321 bool RlzValueStoreRegistry::AddStatefulEvent(Product product,
322 const char* event_rlz) {
323 base::win::RegKey key;
324 std::wstring event_rlz_wide(ASCIIToWide(event_rlz));
325 if (!GetEventsRegKey(kStatefulEventsSubkeyName, &product, KEY_WRITE, &key) ||
326 key.WriteValue(event_rlz_wide.c_str(), 1) != ERROR_SUCCESS) {
327 ASSERT_STRING(
328 "AddStatefulEvent: Could not write the new stateful event");
329 return false;
330 }
331
332 return true;
333 }
334
335 bool RlzValueStoreRegistry::IsStatefulEvent(Product product,
336 const char* event_rlz) {
337 DWORD value;
338 base::win::RegKey key;
339 GetEventsRegKey(kStatefulEventsSubkeyName, &product, KEY_READ, &key);
340 std::wstring event_rlz_wide(ASCIIToWide(event_rlz));
341 return key.ReadValueDW(event_rlz_wide.c_str(), &value) == ERROR_SUCCESS;
342 }
343
344 bool RlzValueStoreRegistry::ClearAllStatefulEvents(Product product) {
345 return ClearAllProductEventValues(product, kStatefulEventsSubkeyName);
346 }
347
348 void RlzValueStoreRegistry::CollectGarbage() {
349 // Delete each of the known subkeys if empty.
350 const char* subkeys[] = {
351 kRlzsSubkeyName,
352 kEventsSubkeyName,
353 kStatefulEventsSubkeyName,
354 kPingTimesSubkeyName
355 };
356
357 for (int i = 0; i < arraysize(subkeys); i++) {
358 std::string subkey_name;
359 base::StringAppendF(&subkey_name, "%s\\%s", kLibKeyName, subkeys[i]);
360 AppendBrandToString(&subkey_name);
361
362 VERIFY(DeleteKeyIfEmpty(HKEY_CURRENT_USER,
363 ASCIIToWide(subkey_name).c_str()));
364 }
365
366 // Delete the library key and its parents too now if empty.
367 VERIFY(DeleteKeyIfEmpty(HKEY_CURRENT_USER, GetWideLibKeyName().c_str()));
368 VERIFY(DeleteKeyIfEmpty(HKEY_CURRENT_USER, kGoogleCommonKeyName));
369 VERIFY(DeleteKeyIfEmpty(HKEY_CURRENT_USER, kGoogleKeyName));
370 }
371
372 ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() {
373 if (!lock_.failed())
374 store_.reset(new RlzValueStoreRegistry);
375 } 267 }
376 268
377 ScopedRlzValueStoreLock::~ScopedRlzValueStoreLock() { 269 ScopedRlzValueStoreLock::~ScopedRlzValueStoreLock() {
378 } 270 }
379 271
380 RlzValueStore* ScopedRlzValueStoreLock::GetStore() { 272 RlzValueStore* ScopedRlzValueStoreLock::GetStore() {
381 return store_.get(); 273 return store_;
382 } 274 }
275
276 namespace testing {
277
278 void SetRlzStoreDirectory(const FilePath& directory) {
279 g_testing_rlz_store_path_ = directory;
280 }
281
282 } // namespace testing
383 283
384 } // namespace rlz_lib 284 } // namespace rlz_lib
OLDNEW
« no previous file with comments | « rlz/chromeos/lib/rlz_value_store_chromeos.h ('k') | rlz/lib/financial_ping.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698