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/common/child_process_logging.h" 6 7#import <Foundation/Foundation.h> 8 9#include "base/string_number_conversions.h" 10#include "base/string_util.h" 11#include "base/stringprintf.h" 12#include "base/utf_string_conversions.h" 13#include "chrome/installer/util/google_update_settings.h" 14#include "content/common/gpu/gpu_info.h" 15#include "googleurl/src/gurl.h" 16 17namespace child_process_logging { 18 19const int kMaxNumCrashURLChunks = 8; 20const int kMaxNumURLChunkValueLength = 255; 21const char *kUrlChunkFormatStr = "url-chunk-%d"; 22const char *kGuidParamName = "guid"; 23const char *kGPUVendorIdParamName = "gpu-vendid"; 24const char *kGPUDeviceIdParamName = "gpu-devid"; 25const char *kGPUDriverVersionParamName = "gpu-driver"; 26const char *kGPUPixelShaderVersionParamName = "gpu-psver"; 27const char *kGPUVertexShaderVersionParamName = "gpu-vsver"; 28const char *kGPUGLVersionParamName = "gpu-glver"; 29const char *kNumberOfViews = "num-views"; 30NSString* const kNumExtensionsName = @"num-extensions"; 31NSString* const kExtensionNameFormat = @"extension-%d"; 32 33static SetCrashKeyValueFuncPtr g_set_key_func; 34static ClearCrashKeyValueFuncPtr g_clear_key_func; 35 36// Account for the terminating null character. 37static const size_t kClientIdSize = 32 + 1; 38static char g_client_id[kClientIdSize]; 39 40void SetCrashKeyFunctions(SetCrashKeyValueFuncPtr set_key_func, 41 ClearCrashKeyValueFuncPtr clear_key_func) { 42 g_set_key_func = set_key_func; 43 g_clear_key_func = clear_key_func; 44} 45 46void SetActiveURLImpl(const GURL& url, 47 SetCrashKeyValueFuncPtr set_key_func, 48 ClearCrashKeyValueFuncPtr clear_key_func) { 49 50 NSString *kUrlChunkFormatStr_utf8 = [NSString 51 stringWithUTF8String:kUrlChunkFormatStr]; 52 53 // First remove any old url chunks we might have lying around. 54 for (int i = 0; i < kMaxNumCrashURLChunks; i++) { 55 // On Windows the url-chunk items are 1-based, so match that. 56 NSString *key = [NSString stringWithFormat:kUrlChunkFormatStr_utf8, i+1]; 57 clear_key_func(key); 58 } 59 60 const std::string& raw_url_utf8 = url.possibly_invalid_spec(); 61 NSString *raw_url = [NSString stringWithUTF8String:raw_url_utf8.c_str()]; 62 size_t raw_url_length = [raw_url length]; 63 64 // Bail on zero-length URLs. 65 if (raw_url_length == 0) { 66 return; 67 } 68 69 // Parcel the URL up into up to 8, 255 byte segments. 70 size_t start_ofs = 0; 71 for (int i = 0; 72 i < kMaxNumCrashURLChunks && start_ofs < raw_url_length; 73 ++i) { 74 75 // On Windows the url-chunk items are 1-based, so match that. 76 NSString *key = [NSString stringWithFormat:kUrlChunkFormatStr_utf8, i+1]; 77 NSRange range; 78 range.location = start_ofs; 79 range.length = std::min((size_t)kMaxNumURLChunkValueLength, 80 raw_url_length - start_ofs); 81 NSString *value = [raw_url substringWithRange:range]; 82 set_key_func(key, value); 83 84 // Next chunk. 85 start_ofs += kMaxNumURLChunkValueLength; 86 } 87} 88 89void SetClientIdImpl(const std::string& client_id, 90 SetCrashKeyValueFuncPtr set_key_func) { 91 NSString *key = [NSString stringWithUTF8String:kGuidParamName]; 92 NSString *value = [NSString stringWithUTF8String:client_id.c_str()]; 93 set_key_func(key, value); 94} 95 96void SetActiveURL(const GURL& url) { 97 if (g_set_key_func && g_clear_key_func) 98 SetActiveURLImpl(url, g_set_key_func, g_clear_key_func); 99} 100 101void SetClientId(const std::string& client_id) { 102 std::string str(client_id); 103 ReplaceSubstringsAfterOffset(&str, 0, "-", ""); 104 105 base::strlcpy(g_client_id, str.c_str(), kClientIdSize); 106 if (g_set_key_func) 107 SetClientIdImpl(str, g_set_key_func); 108 109 std::wstring wstr = ASCIIToWide(str); 110 GoogleUpdateSettings::SetMetricsId(wstr); 111} 112 113std::string GetClientId() { 114 return std::string(g_client_id); 115} 116 117void SetActiveExtensions(const std::set<std::string>& extension_ids) { 118 if (!g_set_key_func) 119 return; 120 121 // Log the count separately to track heavy users. 122 const int count = static_cast<int>(extension_ids.size()); 123 g_set_key_func(kNumExtensionsName, [NSString stringWithFormat:@"%i", count]); 124 125 // Record up to |kMaxReportedActiveExtensions| extensions, clearing 126 // keys if there aren't that many. 127 std::set<std::string>::const_iterator iter = extension_ids.begin(); 128 for (int i = 0; i < kMaxReportedActiveExtensions; ++i) { 129 NSString* key = [NSString stringWithFormat:kExtensionNameFormat, i]; 130 if (iter != extension_ids.end()) { 131 g_set_key_func(key, [NSString stringWithUTF8String:iter->c_str()]); 132 ++iter; 133 } else { 134 g_clear_key_func(key); 135 } 136 } 137} 138 139void SetGpuKeyValue(const char* param_name, const std::string& value_str, 140 SetCrashKeyValueFuncPtr set_key_func) { 141 NSString *key = [NSString stringWithUTF8String:param_name]; 142 NSString *value = [NSString stringWithUTF8String:value_str.c_str()]; 143 set_key_func(key, value); 144} 145 146void SetGpuInfoImpl(const GPUInfo& gpu_info, 147 SetCrashKeyValueFuncPtr set_key_func) { 148 SetGpuKeyValue(kGPUVendorIdParamName, 149 base::StringPrintf("0x%04x", gpu_info.vendor_id), 150 set_key_func); 151 SetGpuKeyValue(kGPUDeviceIdParamName, 152 base::StringPrintf("0x%04x", gpu_info.device_id), 153 set_key_func); 154 SetGpuKeyValue(kGPUDriverVersionParamName, 155 gpu_info.driver_version, 156 set_key_func); 157 SetGpuKeyValue(kGPUPixelShaderVersionParamName, 158 gpu_info.pixel_shader_version, 159 set_key_func); 160 SetGpuKeyValue(kGPUVertexShaderVersionParamName, 161 gpu_info.vertex_shader_version, 162 set_key_func); 163 SetGpuKeyValue(kGPUGLVersionParamName, 164 gpu_info.gl_version, 165 set_key_func); 166} 167 168void SetGpuInfo(const GPUInfo& gpu_info) { 169 if (g_set_key_func) 170 SetGpuInfoImpl(gpu_info, g_set_key_func); 171} 172 173 174void SetNumberOfViewsImpl(int number_of_views, 175 SetCrashKeyValueFuncPtr set_key_func) { 176 NSString *key = [NSString stringWithUTF8String:kNumberOfViews]; 177 NSString *value = [NSString stringWithFormat:@"%d", number_of_views]; 178 set_key_func(key, value); 179} 180 181void SetNumberOfViews(int number_of_views) { 182 if (g_set_key_func) 183 SetNumberOfViewsImpl(number_of_views, g_set_key_func); 184} 185 186} // namespace child_process_logging 187