chromium/chrome/installer/setup/installer_crash_reporter_client.cc

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/installer/setup/installer_crash_reporter_client.h"

#include "base/environment.h"
#include "base/file_version_info.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "build/branding_buildflags.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_version.h"
#include "chrome/common/env_vars.h"
#include "chrome/install_static/install_util.h"
#include "chrome/installer/setup/installer_crash_reporting.h"
#include "chrome/installer/util/google_update_settings.h"
#include "components/version_info/channel.h"

InstallerCrashReporterClient::InstallerCrashReporterClient(
    bool is_per_user_install)
    : is_per_user_install_(is_per_user_install) {}

InstallerCrashReporterClient::~InstallerCrashReporterClient() = default;

bool InstallerCrashReporterClient::ShouldCreatePipeName(
    const std::wstring& process_type) {
  return true;
}

bool InstallerCrashReporterClient::GetAlternativeCrashDumpLocation(
    std::wstring* crash_dir) {
  return false;
}

void InstallerCrashReporterClient::GetProductNameAndVersion(
    const std::wstring& exe_path,
    std::wstring* product_name,
    std::wstring* version,
    std::wstring* special_build,
    std::wstring* channel_name) {
  // Report crashes under the same product name as the browser. This string
  // MUST match server-side configuration.
  *product_name = base::ASCIIToWide(PRODUCT_SHORTNAME_STRING);

  std::unique_ptr<FileVersionInfo> version_info(
      FileVersionInfo::CreateFileVersionInfo(base::FilePath(exe_path)));
  if (version_info) {
    *version = base::AsWString(version_info->product_version());
    *special_build = base::AsWString(version_info->special_build());
  } else {
    *version = L"0.0.0.0-devel";
  }

  *channel_name =
      install_static::GetChromeChannelName(/*with_extended_stable=*/true);
}

bool InstallerCrashReporterClient::ShouldShowRestartDialog(
    std::wstring* title,
    std::wstring* message,
    bool* is_rtl_locale) {
  // There is no UX associated with the installer, so no dialog should be shown.
  return false;
}

bool InstallerCrashReporterClient::AboutToRestart() {
  // The installer should never be restarted after a crash.
  return false;
}

bool InstallerCrashReporterClient::GetIsPerUserInstall() {
  return is_per_user_install_;
}

bool InstallerCrashReporterClient::GetShouldDumpLargerDumps() {
  // Use large dumps for all but the stable channel.
  return install_static::GetChromeChannel() != version_info::Channel::STABLE;
}

int InstallerCrashReporterClient::GetResultCodeRespawnFailed() {
  // The restart dialog is never shown for the installer.
  NOTREACHED_IN_MIGRATION();
  return 0;
}

bool InstallerCrashReporterClient::GetCrashDumpLocation(
    std::wstring* crash_dir) {
  base::FilePath crash_directory_path;
  bool ret =
      base::PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_directory_path);
  if (ret)
    *crash_dir = crash_directory_path.value();
  return ret;
}

bool InstallerCrashReporterClient::IsRunningUnattended() {
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  return env->HasVar(env_vars::kHeadless);
}

bool InstallerCrashReporterClient::GetCollectStatsConsent() {
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  return GoogleUpdateSettings::GetCollectStatsConsent();
#else
  return false;
#endif
}

bool InstallerCrashReporterClient::GetCollectStatsInSample() {
  // TODO(grt): remove duplication of code.
  base::win::RegKey key(HKEY_CURRENT_USER,
                        install_static::GetRegistryPath().c_str(),
                        KEY_QUERY_VALUE | KEY_WOW64_32KEY);
  if (!key.Valid())
    return true;
  DWORD out_value = 0;
  if (key.ReadValueDW(install_static::kRegValueChromeStatsSample, &out_value) !=
      ERROR_SUCCESS) {
    return true;
  }
  return out_value == 1;
}

bool InstallerCrashReporterClient::ReportingIsEnforcedByPolicy(bool* enabled) {
  // From the generated policy/policy/policy_constants.cc:
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  static const wchar_t kRegistryChromePolicyKey[] =
      L"SOFTWARE\\Policies\\Google\\Chrome";
#else
  static const wchar_t kRegistryChromePolicyKey[] =
      L"SOFTWARE\\Policies\\Chromium";
#endif
  static const wchar_t kMetricsReportingEnabled[] = L"MetricsReportingEnabled";

  // Determine whether configuration management allows loading the crash
  // reporter. Since the configuration management infrastructure is not
  // initialized in the installer, the corresponding registry keys are read
  // directly. The return status indicates whether policy data was successfully
  // read. If it is true, |enabled| contains the value set by policy.
  DWORD value = 0;
  base::win::RegKey policy_key;
  static const HKEY kHives[] = {HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER};
  for (HKEY hive : kHives) {
    if (policy_key.Open(hive, kRegistryChromePolicyKey, KEY_READ) ==
            ERROR_SUCCESS &&
        policy_key.ReadValueDW(kMetricsReportingEnabled, &value) ==
            ERROR_SUCCESS) {
      *enabled = value != 0;
      return true;
    }
  }

  return false;
}

bool InstallerCrashReporterClient::EnableBreakpadForProcess(
    const std::string& process_type) {
  return true;
}