Home | History | Annotate | Download | only in common
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/common/child_process_logging.h"
      6 
      7 #include <windows.h>
      8 
      9 #include "base/command_line.h"
     10 #include "base/strings/string_number_conversions.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "chrome/common/chrome_constants.h"
     15 #include "chrome/common/metrics/variations/variations_util.h"
     16 #include "chrome/installer/util/google_update_settings.h"
     17 #include "gpu/config/gpu_info.h"
     18 #include "url/gurl.h"
     19 
     20 namespace child_process_logging {
     21 
     22 namespace {
     23 
     24 // exported in breakpad_win.cc: void __declspec(dllexport) __cdecl SetActiveURL.
     25 typedef void (__cdecl *MainSetActiveURL)(const wchar_t*);
     26 
     27 // exported in breakpad_win.cc: void __declspec(dllexport) __cdecl SetClientId.
     28 typedef void (__cdecl *MainSetClientId)(const wchar_t*);
     29 
     30 // exported in breakpad_win.cc:
     31 //   void __declspec(dllexport) __cdecl SetNumberOfExtensions.
     32 typedef void (__cdecl *MainSetNumberOfExtensions)(int);
     33 
     34 // exported in breakpad_win.cc:
     35 // void __declspec(dllexport) __cdecl SetExtensionID.
     36 typedef void (__cdecl *MainSetExtensionID)(size_t, const wchar_t*);
     37 
     38 // exported in breakpad_win.cc: void __declspec(dllexport) __cdecl SetGpuInfo.
     39 typedef void (__cdecl *MainSetGpuInfo)(const wchar_t*, const wchar_t*,
     40                                        const wchar_t*, const wchar_t*,
     41                                        const wchar_t*);
     42 
     43 // exported in breakpad_win.cc:
     44 //     void __declspec(dllexport) __cdecl SetPrinterInfo.
     45 typedef void (__cdecl *MainSetPrinterInfo)(const wchar_t*);
     46 
     47 // exported in breakpad_win.cc:
     48 //   void __declspec(dllexport) __cdecl SetNumberOfViews.
     49 typedef void (__cdecl *MainSetNumberOfViews)(int);
     50 
     51 // exported in breakpad_win.cc:
     52 //   void __declspec(dllexport) __cdecl SetCommandLine2
     53 typedef void (__cdecl *MainSetCommandLine)(const wchar_t**, size_t);
     54 
     55 // exported in breakpad_field_trial_win.cc:
     56 //   void __declspec(dllexport) __cdecl SetExperimentList3
     57 typedef void (__cdecl *MainSetExperimentList)(const wchar_t**, size_t, size_t);
     58 
     59 // Copied from breakpad_win.cc.
     60 void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings,
     61                                  std::vector<const wchar_t*>* cstrings) {
     62   cstrings->clear();
     63   cstrings->reserve(wstrings.size());
     64   for (size_t i = 0; i < wstrings.size(); ++i)
     65     cstrings->push_back(wstrings[i].c_str());
     66 }
     67 
     68 }  // namespace
     69 
     70 void SetActiveURL(const GURL& url) {
     71   static MainSetActiveURL set_active_url = NULL;
     72   // note: benign race condition on set_active_url.
     73   if (!set_active_url) {
     74     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
     75     if (!exe_module)
     76       return;
     77     set_active_url = reinterpret_cast<MainSetActiveURL>(
     78         GetProcAddress(exe_module, "SetActiveURL"));
     79     if (!set_active_url)
     80       return;
     81   }
     82 
     83   (set_active_url)(UTF8ToWide(url.possibly_invalid_spec()).c_str());
     84 }
     85 
     86 void SetClientId(const std::string& client_id) {
     87   std::string str(client_id);
     88   // Remove all instance of '-' char from the GUID. So BCD-WXY becomes BCDWXY.
     89   ReplaceSubstringsAfterOffset(&str, 0, "-", "");
     90 
     91   if (str.empty())
     92     return;
     93 
     94   std::wstring wstr = ASCIIToWide(str);
     95   std::wstring old_wstr;
     96   if (!GoogleUpdateSettings::GetMetricsId(&old_wstr) ||
     97       wstr != old_wstr)
     98     GoogleUpdateSettings::SetMetricsId(wstr);
     99 
    100   static MainSetClientId set_client_id = NULL;
    101   // note: benign race condition on set_client_id.
    102   if (!set_client_id) {
    103     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
    104     if (!exe_module)
    105       return;
    106     set_client_id = reinterpret_cast<MainSetClientId>(
    107         GetProcAddress(exe_module, "SetClientId"));
    108     if (!set_client_id)
    109       return;
    110   }
    111   (set_client_id)(wstr.c_str());
    112 }
    113 
    114 std::string GetClientId() {
    115   std::wstring wstr_client_id;
    116   if (GoogleUpdateSettings::GetMetricsId(&wstr_client_id))
    117     return WideToASCII(wstr_client_id);
    118   else
    119     return std::string();
    120 }
    121 
    122 void SetActiveExtensions(const std::set<std::string>& extension_ids) {
    123   static MainSetNumberOfExtensions set_number_of_extensions = NULL;
    124   // note: benign race condition on set_number_of_extensions.
    125   if (!set_number_of_extensions) {
    126     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
    127     if (!exe_module)
    128       return;
    129     set_number_of_extensions = reinterpret_cast<MainSetNumberOfExtensions>(
    130         GetProcAddress(exe_module, "SetNumberOfExtensions"));
    131     if (!set_number_of_extensions)
    132       return;
    133   }
    134 
    135   static MainSetExtensionID set_extension_id = NULL;
    136   // note: benign race condition on set_extension_id.
    137   if (!set_extension_id) {
    138     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
    139     if (!exe_module)
    140       return;
    141     set_extension_id = reinterpret_cast<MainSetExtensionID>(
    142         GetProcAddress(exe_module, "SetExtensionID"));
    143     if (!set_extension_id)
    144       return;
    145   }
    146 
    147   (set_number_of_extensions)(static_cast<int>(extension_ids.size()));
    148 
    149   std::set<std::string>::const_iterator iter = extension_ids.begin();
    150   for (size_t i = 0; i < kMaxReportedActiveExtensions; ++i) {
    151     if (iter != extension_ids.end()) {
    152       (set_extension_id)(i, ASCIIToWide(iter->c_str()).c_str());
    153       ++iter;
    154     } else {
    155       (set_extension_id)(i, L"");
    156     }
    157   }
    158 }
    159 
    160 void SetGpuInfo(const gpu::GPUInfo& gpu_info) {
    161   static MainSetGpuInfo set_gpu_info = NULL;
    162   // note: benign race condition on set_gpu_info.
    163   if (!set_gpu_info) {
    164     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
    165     if (!exe_module)
    166       return;
    167     set_gpu_info = reinterpret_cast<MainSetGpuInfo>(
    168         GetProcAddress(exe_module, "SetGpuInfo"));
    169     if (!set_gpu_info)
    170       return;
    171   }
    172   (set_gpu_info)(
    173       base::StringPrintf(L"0x%04x", gpu_info.gpu.vendor_id).c_str(),
    174       base::StringPrintf(L"0x%04x", gpu_info.gpu.device_id).c_str(),
    175       UTF8ToUTF16(gpu_info.driver_version).c_str(),
    176       UTF8ToUTF16(gpu_info.pixel_shader_version).c_str(),
    177       UTF8ToUTF16(gpu_info.vertex_shader_version).c_str());
    178 }
    179 
    180 void SetPrinterInfo(const char* printer_info) {
    181   static MainSetPrinterInfo set_printer_info = NULL;
    182   // note: benign race condition on set_printer_info.
    183   if (!set_printer_info) {
    184     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
    185     if (!exe_module)
    186       return;
    187     set_printer_info = reinterpret_cast<MainSetPrinterInfo>(
    188         GetProcAddress(exe_module, "SetPrinterInfo"));
    189     if (!set_printer_info)
    190       return;
    191   }
    192   (set_printer_info)(UTF8ToWide(printer_info).c_str());
    193 }
    194 
    195 void SetCommandLine(const CommandLine* command_line) {
    196   static MainSetCommandLine set_command_line = NULL;
    197   // note: benign race condition on set_command_line.
    198   if (!set_command_line) {
    199     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
    200     if (!exe_module)
    201       return;
    202     set_command_line = reinterpret_cast<MainSetCommandLine>(
    203         GetProcAddress(exe_module, "SetCommandLine2"));
    204     if (!set_command_line)
    205       return;
    206   }
    207 
    208   if (command_line->argv().empty())
    209     return;
    210 
    211   std::vector<const wchar_t*> cstrings;
    212   StringVectorToCStringVector(command_line->argv(), &cstrings);
    213   (set_command_line)(&cstrings[0], cstrings.size());
    214 }
    215 
    216 void SetExperimentList(const std::vector<string16>& experiments) {
    217   static MainSetExperimentList set_experiment_list = NULL;
    218   // note: benign race condition on set_experiment_list.
    219   if (!set_experiment_list) {
    220     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
    221     if (!exe_module)
    222       return;
    223     set_experiment_list = reinterpret_cast<MainSetExperimentList>(
    224         GetProcAddress(exe_module, "SetExperimentList3"));
    225     if (!set_experiment_list)
    226       return;
    227   }
    228 
    229   std::vector<string16> chunks;
    230   chrome_variations::GenerateVariationChunks(experiments, &chunks);
    231 
    232   // If the list is empty, notify the child process of the number of experiments
    233   // and exit early.
    234   if (chunks.empty()) {
    235     (set_experiment_list)(NULL, 0, 0);
    236     return;
    237   }
    238 
    239   std::vector<const wchar_t*> cstrings;
    240   StringVectorToCStringVector(chunks, &cstrings);
    241   (set_experiment_list)(&cstrings[0], cstrings.size(), experiments.size());
    242 }
    243 
    244 void SetNumberOfViews(int number_of_views) {
    245   static MainSetNumberOfViews set_number_of_views = NULL;
    246   // note: benign race condition on set_number_of_views.
    247   if (!set_number_of_views) {
    248     HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
    249     if (!exe_module)
    250       return;
    251     set_number_of_views = reinterpret_cast<MainSetNumberOfViews>(
    252         GetProcAddress(exe_module, "SetNumberOfViews"));
    253     if (!set_number_of_views)
    254       return;
    255   }
    256   (set_number_of_views)(number_of_views);
    257 }
    258 
    259 }  // namespace child_process_logging
    260