1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/installer/util/google_update_settings.h" 6 7 #include "base/files/file_util.h" 8 #include "base/lazy_instance.h" 9 #include "base/path_service.h" 10 #include "base/strings/string_util.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "base/synchronization/lock.h" 13 #include "chrome/common/chrome_paths.h" 14 15 namespace { 16 17 base::LazyInstance<std::string>::Leaky g_posix_client_id = 18 LAZY_INSTANCE_INITIALIZER; 19 base::LazyInstance<base::Lock>::Leaky g_posix_client_id_lock = 20 LAZY_INSTANCE_INITIALIZER; 21 22 // File name used in the user data dir to indicate consent. 23 const char kConsentToSendStats[] = "Consent To Send Stats"; 24 SetConsentFilePermissionIfNeeded(const base::FilePath & consent_file)25void SetConsentFilePermissionIfNeeded(const base::FilePath& consent_file) { 26 #if defined(OS_CHROMEOS) 27 // The consent file needs to be world readable. See http://crbug.com/383003 28 int permissions; 29 if (base::GetPosixFilePermissions(consent_file, &permissions) && 30 (permissions & base::FILE_PERMISSION_READ_BY_OTHERS) == 0) { 31 permissions |= base::FILE_PERMISSION_READ_BY_OTHERS; 32 base::SetPosixFilePermissions(consent_file, permissions); 33 } 34 #endif 35 } 36 37 } // namespace 38 39 // static GetCollectStatsConsent()40bool GoogleUpdateSettings::GetCollectStatsConsent() { 41 base::FilePath consent_file; 42 PathService::Get(chrome::DIR_USER_DATA, &consent_file); 43 consent_file = consent_file.Append(kConsentToSendStats); 44 45 if (!base::DirectoryExists(consent_file.DirName())) 46 return false; 47 48 std::string tmp_guid; 49 bool consented = base::ReadFileToString(consent_file, &tmp_guid); 50 if (consented) { 51 SetConsentFilePermissionIfNeeded(consent_file); 52 53 base::AutoLock lock(g_posix_client_id_lock.Get()); 54 g_posix_client_id.Get().assign(tmp_guid); 55 } 56 return consented; 57 } 58 59 // static SetCollectStatsConsent(bool consented)60bool GoogleUpdateSettings::SetCollectStatsConsent(bool consented) { 61 base::FilePath consent_dir; 62 PathService::Get(chrome::DIR_USER_DATA, &consent_dir); 63 if (!base::DirectoryExists(consent_dir)) 64 return false; 65 66 base::AutoLock lock(g_posix_client_id_lock.Get()); 67 68 base::FilePath consent_file = consent_dir.AppendASCII(kConsentToSendStats); 69 if (!consented) { 70 g_posix_client_id.Get().clear(); 71 return base::DeleteFile(consent_file, false); 72 } 73 74 const std::string& client_id = g_posix_client_id.Get(); 75 if (base::PathExists(consent_file) && client_id.empty()) 76 return true; 77 78 int size = client_id.size(); 79 bool write_success = 80 base::WriteFile(consent_file, client_id.c_str(), size) == size; 81 if (write_success) 82 SetConsentFilePermissionIfNeeded(consent_file); 83 return write_success; 84 } 85 86 // static 87 // TODO(gab): Implement storing/loading for all ClientInfo fields on POSIX. LoadMetricsClientInfo()88scoped_ptr<metrics::ClientInfo> GoogleUpdateSettings::LoadMetricsClientInfo() { 89 scoped_ptr<metrics::ClientInfo> client_info(new metrics::ClientInfo); 90 91 base::AutoLock lock(g_posix_client_id_lock.Get()); 92 if (g_posix_client_id.Get().empty()) 93 return scoped_ptr<metrics::ClientInfo>(); 94 client_info->client_id = g_posix_client_id.Get(); 95 96 return client_info.Pass(); 97 } 98 99 // static 100 // TODO(gab): Implement storing/loading for all ClientInfo fields on POSIX. StoreMetricsClientInfo(const metrics::ClientInfo & client_info)101void GoogleUpdateSettings::StoreMetricsClientInfo( 102 const metrics::ClientInfo& client_info) { 103 // Make sure that user has consented to send crashes. 104 if (!GoogleUpdateSettings::GetCollectStatsConsent()) 105 return; 106 107 { 108 // Since user has consented, write the metrics id to the file. 109 base::AutoLock lock(g_posix_client_id_lock.Get()); 110 g_posix_client_id.Get() = client_info.client_id; 111 } 112 GoogleUpdateSettings::SetCollectStatsConsent(true); 113 } 114 115 // GetLastRunTime and SetLastRunTime are not implemented for posix. Their 116 // current return values signal failure which the caller is designed to 117 // handle. 118 119 // static GetLastRunTime()120int GoogleUpdateSettings::GetLastRunTime() { 121 return -1; 122 } 123 124 // static SetLastRunTime()125bool GoogleUpdateSettings::SetLastRunTime() { 126 return false; 127 } 128