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

#include "chrome/app/chrome_breakpad_client.h"

#include "base/atomicops.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/safe_sprintf.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_result_codes.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/crash_keys.h"
#include "chrome/common/env_vars.h"
#include "chrome/installer/util/google_update_settings.h"

#if defined(OS_WIN)
#include <windows.h>

#include "base/file_version_info.h"
#include "base/win/registry.h"
#include "chrome/installer/util/google_chrome_sxs_distribution.h"
#include "chrome/installer/util/install_util.h"
#include "policy/policy_constants.h"
#endif

#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS)
#include "chrome/browser/crash_upload_list.h"
#include "chrome/common/chrome_version_info_posix.h"
#endif

#if defined(OS_POSIX)
#include "base/debug/dump_without_crashing.h"
#endif

#if defined(OS_ANDROID)
#include "chrome/common/descriptors_android.h"
#endif

#if defined(OS_CHROMEOS)
#include "chrome/common/chrome_version_info.h"
#include "chromeos/chromeos_switches.h"
#endif

namespace chrome {

namespace {

#if defined(OS_WIN)
// This is the minimum version of google update that is required for deferred
// crash uploads to work.
const char kMinUpdateVersion[] = "1.3.21.115";

// The value name prefix will be of the form {chrome-version}-{pid}-{timestamp}
// (i.e., "#####.#####.#####.#####-########-########") which easily fits into a
// 63 character buffer.
const char kBrowserCrashDumpPrefixTemplate[] = "%s-%08x-%08x";
const size_t kBrowserCrashDumpPrefixLength = 63;
char g_browser_crash_dump_prefix[kBrowserCrashDumpPrefixLength + 1] = {};

// These registry key to which we'll write a value for each crash dump attempt.
HKEY g_browser_crash_dump_regkey = NULL;

// A atomic counter to make each crash dump value name unique.
base::subtle::Atomic32 g_browser_crash_dump_count = 0;
#endif

}  // namespace

ChromeBreakpadClient::ChromeBreakpadClient() {}

ChromeBreakpadClient::~ChromeBreakpadClient() {}

void ChromeBreakpadClient::SetClientID(const std::string& client_id) {
  crash_keys::SetClientID(client_id);
}

#if defined(OS_WIN)
bool ChromeBreakpadClient::GetAlternativeCrashDumpLocation(
    base::FilePath* crash_dir) {
  // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate
  // location to write breakpad crash dumps can be set.
  scoped_ptr<base::Environment> env(base::Environment::Create());
  std::string alternate_crash_dump_location;
  if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_crash_dump_location)) {
    *crash_dir = base::FilePath::FromUTF8Unsafe(alternate_crash_dump_location);
    return true;
  }

  return false;
}

void ChromeBreakpadClient::GetProductNameAndVersion(
    const base::FilePath& exe_path,
    base::string16* product_name,
    base::string16* version,
    base::string16* special_build,
    base::string16* channel_name) {
  DCHECK(product_name);
  DCHECK(version);
  DCHECK(special_build);
  DCHECK(channel_name);

  scoped_ptr<FileVersionInfo> version_info(
      FileVersionInfo::CreateFileVersionInfo(exe_path));

  if (version_info.get()) {
    // Get the information from the file.
    *version = version_info->product_version();
    if (!version_info->is_official_build())
      version->append(base::ASCIIToUTF16("-devel"));

    *product_name = version_info->product_short_name();
    *special_build = version_info->special_build();
  } else {
    // No version info found. Make up the values.
    *product_name = base::ASCIIToUTF16("Chrome");
    *version = base::ASCIIToUTF16("0.0.0.0-devel");
  }

  std::wstring channel_string;
  GoogleUpdateSettings::GetChromeChannelAndModifiers(
      !GetIsPerUserInstall(exe_path), &channel_string);
  *channel_name = base::WideToUTF16(channel_string);
}

bool ChromeBreakpadClient::ShouldShowRestartDialog(base::string16* title,
                                                   base::string16* message,
                                                   bool* is_rtl_locale) {
  scoped_ptr<base::Environment> env(base::Environment::Create());
  if (!env->HasVar(env_vars::kShowRestart) ||
      !env->HasVar(env_vars::kRestartInfo) ||
      env->HasVar(env_vars::kMetroConnected)) {
    return false;
  }

  std::string restart_info;
  env->GetVar(env_vars::kRestartInfo, &restart_info);

  // The CHROME_RESTART var contains the dialog strings separated by '|'.
  // See ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment()
  // for details.
  std::vector<std::string> dlg_strings;
  base::SplitString(restart_info, '|', &dlg_strings);

  if (dlg_strings.size() < 3)
    return false;

  *title = base::UTF8ToUTF16(dlg_strings[0]);
  *message = base::UTF8ToUTF16(dlg_strings[1]);
  *is_rtl_locale = dlg_strings[2] == env_vars::kRtlLocale;
  return true;
}

bool ChromeBreakpadClient::AboutToRestart() {
  scoped_ptr<base::Environment> env(base::Environment::Create());
  if (!env->HasVar(env_vars::kRestartInfo))
    return false;

  env->SetVar(env_vars::kShowRestart, "1");
  return true;
}

bool ChromeBreakpadClient::GetDeferredUploadsSupported(
    bool is_per_user_install) {
  Version update_version = GoogleUpdateSettings::GetGoogleUpdateVersion(
      !is_per_user_install);
  if (!update_version.IsValid() ||
      update_version.IsOlderThan(std::string(kMinUpdateVersion)))
    return false;

  return true;
}

bool ChromeBreakpadClient::GetIsPerUserInstall(const base::FilePath& exe_path) {
  return InstallUtil::IsPerUserInstall(exe_path.value().c_str());
}

bool ChromeBreakpadClient::GetShouldDumpLargerDumps(bool is_per_user_install) {
  base::string16 channel_name(base::WideToUTF16(
      GoogleUpdateSettings::GetChromeChannel(!is_per_user_install)));

  // Capture more detail in crash dumps for beta and dev channel builds.
  if (channel_name == base::ASCIIToUTF16("dev") ||
      channel_name == base::ASCIIToUTF16("beta") ||
      channel_name == GoogleChromeSxSDistribution::ChannelName())
    return true;
  return false;
}

int ChromeBreakpadClient::GetResultCodeRespawnFailed() {
  return chrome::RESULT_CODE_RESPAWN_FAILED;
}

void ChromeBreakpadClient::InitBrowserCrashDumpsRegKey() {
  DCHECK(g_browser_crash_dump_regkey == NULL);

  base::win::RegKey regkey;
  if (regkey.Create(HKEY_CURRENT_USER,
                    chrome::kBrowserCrashDumpAttemptsRegistryPath,
                    KEY_ALL_ACCESS) != ERROR_SUCCESS) {
    return;
  }

  // We use the current process id and the current tick count as a (hopefully)
  // unique combination for the crash dump value. There's a small chance that
  // across a reboot we might have a crash dump signal written, and the next
  // browser process might have the same process id and tick count, but crash
  // before consuming the signal (overwriting the signal with an identical one).
  // For now, we're willing to live with that risk.
  int length = base::strings::SafeSPrintf(g_browser_crash_dump_prefix,
                                          kBrowserCrashDumpPrefixTemplate,
                                          chrome::kChromeVersion,
                                          ::GetCurrentProcessId(),
                                          ::GetTickCount());
  if (length <= 0) {
    NOTREACHED();
    g_browser_crash_dump_prefix[0] = '\0';
    return;
  }

  // Hold the registry key in a global for update on crash dump.
  g_browser_crash_dump_regkey = regkey.Take();
}

void ChromeBreakpadClient::RecordCrashDumpAttempt(bool is_real_crash) {
  // If we're not a browser (or the registry is unavailable to us for some
  // reason) then there's nothing to do.
  if (g_browser_crash_dump_regkey == NULL)
    return;

  // Generate the final value name we'll use (appends the crash number to the
  // base value name).
  const size_t kMaxValueSize = 2 * kBrowserCrashDumpPrefixLength;
  char value_name[kMaxValueSize + 1] = {};
  int length = base::strings::SafeSPrintf(
      value_name,
      "%s-%x",
      g_browser_crash_dump_prefix,
      base::subtle::NoBarrier_AtomicIncrement(&g_browser_crash_dump_count, 1));

  if (length > 0) {
    DWORD value_dword = is_real_crash ? 1 : 0;
    ::RegSetValueExA(g_browser_crash_dump_regkey, value_name, 0, REG_DWORD,
                     reinterpret_cast<BYTE*>(&value_dword),
                     sizeof(value_dword));
  }
}

bool ChromeBreakpadClient::ReportingIsEnforcedByPolicy(bool* breakpad_enabled) {
// Determine whether configuration management allows loading the crash reporter.
// Since the configuration management infrastructure is not initialized at this
// point, we read the corresponding registry key directly. The return status
// indicates whether policy data was successfully read. If it is true,
// |breakpad_enabled| contains the value set by policy.
  base::string16 key_name =
      base::UTF8ToUTF16(policy::key::kMetricsReportingEnabled);
  DWORD value = 0;
  base::win::RegKey hklm_policy_key(HKEY_LOCAL_MACHINE,
                                    policy::kRegistryChromePolicyKey, KEY_READ);
  if (hklm_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) {
    *breakpad_enabled = value != 0;
    return true;
  }

  base::win::RegKey hkcu_policy_key(HKEY_CURRENT_USER,
                                    policy::kRegistryChromePolicyKey, KEY_READ);
  if (hkcu_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) {
    *breakpad_enabled = value != 0;
    return true;
  }

  return false;
}
#endif

#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS)
void ChromeBreakpadClient::GetProductNameAndVersion(std::string* product_name,
                                                    std::string* version) {
  DCHECK(product_name);
  DCHECK(version);
#if defined(OS_ANDROID)
  *product_name = "Chrome_Android";
#elif defined(OS_CHROMEOS)
  *product_name = "Chrome_ChromeOS";
#else  // OS_LINUX
#if !defined(ADDRESS_SANITIZER)
  *product_name = "Chrome_Linux";
#else
  *product_name = "Chrome_Linux_ASan";
#endif
#endif

  *version = PRODUCT_VERSION;
}

base::FilePath ChromeBreakpadClient::GetReporterLogFilename() {
  return base::FilePath(CrashUploadList::kReporterLogFilename);
}
#endif

bool ChromeBreakpadClient::GetCrashDumpLocation(base::FilePath* crash_dir) {
  // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate
  // location to write breakpad crash dumps can be set.
  scoped_ptr<base::Environment> env(base::Environment::Create());
  std::string alternate_crash_dump_location;
  if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_crash_dump_location)) {
    base::FilePath crash_dumps_dir_path =
        base::FilePath::FromUTF8Unsafe(alternate_crash_dump_location);
    PathService::Override(chrome::DIR_CRASH_DUMPS, crash_dumps_dir_path);
  }

  return PathService::Get(chrome::DIR_CRASH_DUMPS, crash_dir);
}

size_t ChromeBreakpadClient::RegisterCrashKeys() {
  // Note: This is not called on Windows because Breakpad is initialized in the
  // EXE module, but code that uses crash keys is in the DLL module.
  // RegisterChromeCrashKeys() will be called after the DLL is loaded.
  return crash_keys::RegisterChromeCrashKeys();
}

bool ChromeBreakpadClient::IsRunningUnattended() {
  scoped_ptr<base::Environment> env(base::Environment::Create());
  return env->HasVar(env_vars::kHeadless);
}

bool ChromeBreakpadClient::GetCollectStatsConsent() {
  // Convert #define to a variable so that we can use if() rather than
  // #if below and so at least compile-test the Chrome code in
  // Chromium builds.
#if defined(GOOGLE_CHROME_BUILD)
  bool is_chrome_build = true;
#else
  bool is_chrome_build = false;
#endif

#if defined(OS_CHROMEOS)
  bool is_guest_session = CommandLine::ForCurrentProcess()->HasSwitch(
      chromeos::switches::kGuestSession);
  bool is_stable_channel =
      chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_STABLE;

  if (is_guest_session && is_stable_channel)
    return false;
#endif  // defined(OS_CHROMEOS)

#if defined(OS_ANDROID)
  // TODO(jcivelli): we should not initialize the crash-reporter when it was not
  // enabled. Right now if it is disabled we still generate the minidumps but we
  // do not upload them.
  return is_chrome_build;
#else  // !defined(OS_ANDROID)
  return is_chrome_build && GoogleUpdateSettings::GetCollectStatsConsent();
#endif  // defined(OS_ANDROID)
}

#if defined(OS_ANDROID)
int ChromeBreakpadClient::GetAndroidMinidumpDescriptor() {
  return kAndroidMinidumpDescriptor;
}
#endif

bool ChromeBreakpadClient::EnableBreakpadForProcess(
    const std::string& process_type) {
  return process_type == switches::kRendererProcess ||
         process_type == switches::kPluginProcess ||
         process_type == switches::kPpapiPluginProcess ||
         process_type == switches::kZygoteProcess ||
         process_type == switches::kGpuProcess;
}

}  // namespace chrome
