15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/chromeos/lib/rlz_value_store_chromeos.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/base_paths.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/important_file_writer.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_file_value_serializer.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_string_value_serializer.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/path_service.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/lib_values.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "rlz/lib/recursive_cross_process_lock_posix.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rlz/lib/rlz_lib.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace rlz_lib { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Key names. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPingTimeKey[] = "ping_time"; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAccessPointKey[] = "access_points"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kProductEventKey[] = "product_events"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kStatefulEventKey[] = "stateful_events"; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Brand name used when there is no supplementary brand name. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNoSupplementaryBrand[] = "_"; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RLZ store filename. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kRLZDataFileName[] = 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FILE_PATH_LITERAL("RLZ Data"); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RLZ store lock filename 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kRLZLockFileName[] = 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FILE_PATH_LITERAL("RLZ Data.lock"); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RLZ store path for testing. 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath g_testing_rlz_store_path_; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns file path of the RLZ storage. 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetRlzStorePath() { 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath homedir; 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PathService::Get(base::DIR_HOME, &homedir); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_testing_rlz_store_path_.empty() ? 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) homedir.Append(kRLZDataFileName) : 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_testing_rlz_store_path_.Append(kRLZDataFileName); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns file path of the RLZ storage lock file. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetRlzStoreLockPath() { 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath homedir; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PathService::Get(base::DIR_HOME, &homedir); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return g_testing_rlz_store_path_.empty() ? 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) homedir.Append(kRLZLockFileName) : 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_testing_rlz_store_path_.Append(kRLZLockFileName); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the dictionary key for storing access point-related prefs. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetKeyName(std::string key, AccessPoint access_point) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string brand = SupplementaryBranding::GetBrand(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (brand.empty()) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) brand = kNoSupplementaryBrand; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return key + "." + GetAccessPointName(access_point) + "." + brand; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the dictionary key for storing product-related prefs. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetKeyName(std::string key, Product product) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string brand = SupplementaryBranding::GetBrand(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (brand.empty()) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) brand = kNoSupplementaryBrand; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return key + "." + GetProductName(product) + "." + brand; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)RlzValueStoreChromeOS::RlzValueStoreChromeOS(const base::FilePath& store_path) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : rlz_store_(new base::DictionaryValue), 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_path_(store_path), 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_only_(true) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadStore(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RlzValueStoreChromeOS::~RlzValueStoreChromeOS() { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WriteStore(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::HasAccess(AccessType type) { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type == kReadAccess || !read_only_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::WritePingTime(Product product, int64 time) { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_->SetString(GetKeyName(kPingTimeKey, product), 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(time)); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::ReadPingTime(Product product, int64* time) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string ping_time; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rlz_store_->GetString(GetKeyName(kPingTimeKey, product), &ping_time) && 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringToInt64(ping_time, time); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::ClearPingTime(Product product) { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_->Remove(GetKeyName(kPingTimeKey, product), NULL); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::WriteAccessPointRlz(AccessPoint access_point, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* new_rlz) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_->SetString( 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetKeyName(kAccessPointKey, access_point), new_rlz); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::ReadAccessPointRlz(AccessPoint access_point, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* rlz, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t rlz_size) { 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string rlz_value; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_->GetString(GetKeyName(kAccessPointKey, access_point), &rlz_value); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rlz_value.size() < rlz_size) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) strncpy(rlz, rlz_value.c_str(), rlz_size); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rlz_size > 0) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *rlz = '\0'; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::ClearAccessPointRlz(AccessPoint access_point) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_->Remove(GetKeyName(kAccessPointKey, access_point), NULL); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::AddProductEvent(Product product, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* event_rlz) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueToList(GetKeyName(kProductEventKey, product), 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new base::StringValue(event_rlz)); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::ReadProductEvents( 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Product product, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* events) { 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* events_list = NULL; ; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!rlz_store_->GetList(GetKeyName(kProductEventKey, product), &events_list)) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->clear(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < events_list->GetSize(); ++i) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events_list->GetString(i, &event)) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events->push_back(event); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::ClearProductEvent(Product product, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* event_rlz) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringValue event_value(event_rlz); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RemoveValueFromList(GetKeyName(kProductEventKey, product), 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_value); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::ClearAllProductEvents(Product product) { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_->Remove(GetKeyName(kProductEventKey, product), NULL); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::AddStatefulEvent(Product product, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* event_rlz) { 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueToList(GetKeyName(kStatefulEventKey, product), 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new base::StringValue(event_rlz)); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::IsStatefulEvent(Product product, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* event_rlz) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringValue event_value(event_rlz); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* events_list = NULL; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rlz_store_->GetList(GetKeyName(kStatefulEventKey, product), 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &events_list) && 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) events_list->Find(event_value) != events_list->end(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::ClearAllStatefulEvents(Product product) { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_->Remove(GetKeyName(kStatefulEventKey, product), NULL); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RlzValueStoreChromeOS::CollectGarbage() { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RlzValueStoreChromeOS::ReadStore() { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int error_code = 0; 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string error_msg; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JSONFileValueSerializer serializer(store_path_); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> value( 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) serializer.Deserialize(&error_code, &error_msg)); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (error_code) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case JSONFileValueSerializer::JSON_NO_SUCH_FILE: 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_only_ = false; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case JSONFileValueSerializer::JSON_NO_ERROR: 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_only_ = false; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_.reset(static_cast<base::DictionaryValue*>(value.release())); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Error reading RLZ store: " << error_msg; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RlzValueStoreChromeOS::WriteStore() { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json_data; 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JSONStringValueSerializer serializer(&json_data); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) serializer.set_pretty_print(true); 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> copy( 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rlz_store_->DeepCopyWithoutEmptyChildren()); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!serializer.Serialize(*copy.get())) { 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed to serialize RLZ data"; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::ImportantFileWriter::WriteFileAtomically(store_path_, json_data)) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Error writing RLZ store"; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::AddValueToList(std::string list_name, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Value* value) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* list_value = NULL; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!rlz_store_->GetList(list_name, &list_value)) { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) list_value = new base::ListValue; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rlz_store_->Set(list_name, list_value); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) list_value->AppendIfNotPresent(value); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RlzValueStoreChromeOS::RemoveValueFromList(std::string list_name, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Value& value) { 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* list_value = NULL; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!rlz_store_->GetList(list_name, &list_value)) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) list_value->Remove(value, &index); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RlzValueStoreChromeOS keeps its data in memory and only writes it to disk 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// when ScopedRlzValueStoreLock goes out of scope. Hence, if several 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ScopedRlzValueStoreLocks are nested, they all need to use the same store 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// object. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)RecursiveCrossProcessLock g_recursive_lock = 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RECURSIVE_CROSS_PROCESS_LOCK_INITIALIZER; 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This counts the nesting depth of |ScopedRlzValueStoreLock|. 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int g_lock_depth = 0; 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is the shared store object. Non-|NULL| only when |g_lock_depth > 0|. 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)RlzValueStoreChromeOS* g_store = NULL; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool got_cross_process_lock = 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_recursive_lock.TryGetCrossProcessLock(GetRlzStoreLockPath()); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // At this point, we hold the in-process lock, no matter the value of 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |got_cross_process_lock|. 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++g_lock_depth; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!got_cross_process_lock) { 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Acquiring cross-process lock failed, so simply return here. 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In-process lock will be released in dtor. 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!g_store); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (g_lock_depth > 1) { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reuse the already existing store object. 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(g_store); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_.reset(g_store); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is the topmost lock, create a new store object. 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!g_store); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_store = new RlzValueStoreChromeOS(GetRlzStorePath()); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_.reset(g_store); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedRlzValueStoreLock::~ScopedRlzValueStoreLock() { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --g_lock_depth; 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(g_lock_depth >= 0); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (g_lock_depth > 0) { 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Other locks are still using store_, so don't free it yet. 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ignore_result(store_.release()); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_store = NULL; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_recursive_lock.ReleaseLock(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RlzValueStore* ScopedRlzValueStoreLock::GetStore() { 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return store_.get(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace testing { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetRlzStoreDirectory(const base::FilePath& directory) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_testing_rlz_store_path_ = directory; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string RlzStoreFilenameStr() { 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetRlzStorePath().value(); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace testing 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace rlz_lib 343