Home | History | Annotate | Download | only in common
      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 
     17 namespace child_process_logging {
     18 
     19 const int kMaxNumCrashURLChunks = 8;
     20 const int kMaxNumURLChunkValueLength = 255;
     21 const char *kUrlChunkFormatStr = "url-chunk-%d";
     22 const char *kGuidParamName = "guid";
     23 const char *kGPUVendorIdParamName = "gpu-vendid";
     24 const char *kGPUDeviceIdParamName = "gpu-devid";
     25 const char *kGPUDriverVersionParamName = "gpu-driver";
     26 const char *kGPUPixelShaderVersionParamName = "gpu-psver";
     27 const char *kGPUVertexShaderVersionParamName = "gpu-vsver";
     28 const char *kGPUGLVersionParamName = "gpu-glver";
     29 const char *kNumberOfViews = "num-views";
     30 NSString* const kNumExtensionsName = @"num-extensions";
     31 NSString* const kExtensionNameFormat = @"extension-%d";
     32 
     33 static SetCrashKeyValueFuncPtr g_set_key_func;
     34 static ClearCrashKeyValueFuncPtr g_clear_key_func;
     35 
     36 // Account for the terminating null character.
     37 static const size_t kClientIdSize = 32 + 1;
     38 static char g_client_id[kClientIdSize];
     39 
     40 void 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 
     46 void 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 
     89 void 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 
     96 void 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 
    101 void 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 
    113 std::string GetClientId() {
    114   return std::string(g_client_id);
    115 }
    116 
    117 void 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 
    139 void 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 
    146 void 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 
    168 void SetGpuInfo(const GPUInfo& gpu_info) {
    169   if (g_set_key_func)
    170     SetGpuInfoImpl(gpu_info, g_set_key_func);
    171 }
    172 
    173 
    174 void 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 
    181 void 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