#include "chrome/installer/setup/installer_crash_reporting.h"
#include <iterator>
#include <memory>
#include <vector>
#include "base/command_line.h"
#include "base/debug/leak_annotations.h"
#include "base/files/file_path.h"
#include "base/notreached.h"
#include "base/path_service.h"
#include "base/strings/to_string.h"
#include "base/strings/utf_string_conversions.h"
#include "base/version.h"
#include "base/win/registry.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/install_static/install_details.h"
#include "chrome/installer/setup/installer_crash_reporter_client.h"
#include "chrome/installer/setup/installer_state.h"
#include "chrome/installer/util/logging_installer.h"
#include "components/crash/core/app/crashpad.h"
#include "components/crash/core/common/crash_key.h"
#include "components/crash/core/common/crash_keys.h"
namespace installer {
namespace {
const char* OperationToString(InstallerState::Operation operation) {
switch (operation) {
case InstallerState::SINGLE_INSTALL_OR_UPDATE:
return "single-install-or-update";
case InstallerState::UNINSTALL:
return "uninstall";
case InstallerState::UNINITIALIZED:
break;
}
NOTREACHED();
}
bool GetSystemTemp(base::FilePath* temp) {
if (base::PathService::Get(base::DIR_SYSTEM_TEMP, temp)) {
return true;
}
base::win::RegKey reg_key(
HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
KEY_READ);
std::wstring temp_wstring;
bool success = reg_key.ReadValue(L"TEMP", &temp_wstring) == ERROR_SUCCESS;
if (success)
*temp = base::FilePath(temp_wstring);
return success;
}
}
void ConfigureCrashReporting(const InitialPreferences& initial_prefs,
const InstallerState& installer_state) {
InstallerCrashReporterClient* crash_client =
new InstallerCrashReporterClient(!installer_state.system_install());
ANNOTATE_LEAKING_OBJECT_PTR(crash_client);
crash_reporter::SetCrashReporterClient(crash_client);
crash_reporter::InitializeCrashKeys();
if (installer_state.system_install()) {
base::FilePath temp_dir;
if (GetSystemTemp(&temp_dir)) {
base::FilePath crash_dir = temp_dir.Append(FILE_PATH_LITERAL("Crashpad"));
base::PathService::OverrideAndCreateIfNeeded(chrome::DIR_CRASH_DUMPS,
crash_dir, true, true);
} else {
return;
}
}
crash_reporter::InitializeCrashpadWithEmbeddedHandler(
true, "Chrome Installer", "", base::FilePath(),
{GetLogFilePath(initial_prefs)});
}
void SetInitialCrashKeys(const InstallerState& state) {
using crash_reporter::CrashKeyString;
static CrashKeyString<64> operation("operation");
operation.Set(OperationToString(state.operation()));
static CrashKeyString<6> is_system_level("system-level");
is_system_level.Set(base::ToString(state.system_install()));
static CrashKeyString<256> state_crash_key("state-key");
const std::wstring state_key = state.state_key();
if (!state_key.empty())
state_crash_key.Set(base::WideToUTF8(state_key));
const auto& details = install_static::InstallDetails::Get();
static CrashKeyString<50> ap_value("ap");
ap_value.Set(base::WideToUTF8(details.update_ap()));
static CrashKeyString<32> update_cohort_name("cohort-name");
update_cohort_name.Set(base::WideToUTF8(details.update_cohort_name()));
}
void SetCrashKeysFromCommandLine(const base::CommandLine& command_line) {
crash_keys::SetSwitchesFromCommandLine(command_line, nullptr);
}
void SetCurrentVersionCrashKey(const base::Version& current_version) {
static crash_reporter::CrashKeyString<32> version_key("current-version");
if (current_version.IsValid())
version_key.Set(current_version.GetString());
else
version_key.Clear();
}
}