Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / app / chrome_crash_reporter_client.cc
blob067ab53ef926ce7d0cce29e5af3f1e367bc9f3e2
1 // Copyright 2013 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.
5 #include "chrome/app/chrome_crash_reporter_client.h"
7 #include "base/command_line.h"
8 #include "base/environment.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/path_service.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/common/chrome_constants.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/chrome_result_codes.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/crash_keys.h"
19 #include "chrome/common/env_vars.h"
20 #include "chrome/installer/util/google_update_settings.h"
22 #if defined(OS_WIN)
23 #include <windows.h>
25 #include "base/file_version_info.h"
26 #include "base/win/registry.h"
27 #include "chrome/installer/util/google_chrome_sxs_distribution.h"
28 #include "chrome/installer/util/install_util.h"
29 #include "chrome/installer/util/util_constants.h"
30 #include "components/browser_watcher/crash_reporting_metrics_win.h"
31 #include "policy/policy_constants.h"
32 #endif
34 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS)
35 #include "chrome/browser/crash_upload_list.h"
36 #include "chrome/common/chrome_version_info_values.h"
37 #endif
39 #if defined(OS_POSIX)
40 #include "base/debug/dump_without_crashing.h"
41 #endif
43 #if defined(OS_ANDROID)
44 #include "chrome/common/descriptors_android.h"
45 #endif
47 #if defined(OS_CHROMEOS)
48 #include "chrome/common/chrome_version_info.h"
49 #include "chromeos/chromeos_switches.h"
50 #endif
52 namespace chrome {
54 namespace {
56 #if defined(OS_WIN)
57 // This is the minimum version of google update that is required for deferred
58 // crash uploads to work.
59 const char kMinUpdateVersion[] = "1.3.21.115";
60 #endif
62 } // namespace
64 ChromeCrashReporterClient::ChromeCrashReporterClient() {}
66 ChromeCrashReporterClient::~ChromeCrashReporterClient() {}
68 #if !defined(OS_MACOSX)
69 void ChromeCrashReporterClient::SetCrashReporterClientIdFromGUID(
70 const std::string& client_guid) {
71 crash_keys::SetMetricsClientIdFromGUID(client_guid);
73 #endif
75 #if defined(OS_WIN)
76 bool ChromeCrashReporterClient::GetAlternativeCrashDumpLocation(
77 base::FilePath* crash_dir) {
78 // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate
79 // location to write breakpad crash dumps can be set.
80 scoped_ptr<base::Environment> env(base::Environment::Create());
81 std::string alternate_crash_dump_location;
82 if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_crash_dump_location)) {
83 *crash_dir = base::FilePath::FromUTF8Unsafe(alternate_crash_dump_location);
84 return true;
87 return false;
90 void ChromeCrashReporterClient::GetProductNameAndVersion(
91 const base::FilePath& exe_path,
92 base::string16* product_name,
93 base::string16* version,
94 base::string16* special_build,
95 base::string16* channel_name) {
96 DCHECK(product_name);
97 DCHECK(version);
98 DCHECK(special_build);
99 DCHECK(channel_name);
101 scoped_ptr<FileVersionInfo> version_info(
102 FileVersionInfo::CreateFileVersionInfo(exe_path));
104 if (version_info.get()) {
105 // Get the information from the file.
106 *version = version_info->product_version();
107 if (!version_info->is_official_build())
108 version->append(base::ASCIIToUTF16("-devel"));
110 *product_name = version_info->product_short_name();
111 *special_build = version_info->special_build();
112 } else {
113 // No version info found. Make up the values.
114 *product_name = base::ASCIIToUTF16("Chrome");
115 *version = base::ASCIIToUTF16("0.0.0.0-devel");
118 GoogleUpdateSettings::GetChromeChannelAndModifiers(
119 !GetIsPerUserInstall(exe_path), channel_name);
122 bool ChromeCrashReporterClient::ShouldShowRestartDialog(base::string16* title,
123 base::string16* message,
124 bool* is_rtl_locale) {
125 scoped_ptr<base::Environment> env(base::Environment::Create());
126 if (!env->HasVar(env_vars::kShowRestart) ||
127 !env->HasVar(env_vars::kRestartInfo) ||
128 env->HasVar(env_vars::kMetroConnected)) {
129 return false;
132 std::string restart_info;
133 env->GetVar(env_vars::kRestartInfo, &restart_info);
135 // The CHROME_RESTART var contains the dialog strings separated by '|'.
136 // See ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment()
137 // for details.
138 std::vector<std::string> dlg_strings = base::SplitString(
139 restart_info, "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
141 if (dlg_strings.size() < 3)
142 return false;
144 *title = base::UTF8ToUTF16(dlg_strings[0]);
145 *message = base::UTF8ToUTF16(dlg_strings[1]);
146 *is_rtl_locale = dlg_strings[2] == env_vars::kRtlLocale;
147 return true;
150 bool ChromeCrashReporterClient::AboutToRestart() {
151 scoped_ptr<base::Environment> env(base::Environment::Create());
152 if (!env->HasVar(env_vars::kRestartInfo))
153 return false;
155 env->SetVar(env_vars::kShowRestart, "1");
156 return true;
159 bool ChromeCrashReporterClient::GetDeferredUploadsSupported(
160 bool is_per_user_install) {
161 Version update_version = GoogleUpdateSettings::GetGoogleUpdateVersion(
162 !is_per_user_install);
163 if (!update_version.IsValid() ||
164 update_version.IsOlderThan(std::string(kMinUpdateVersion)))
165 return false;
167 return true;
170 bool ChromeCrashReporterClient::GetIsPerUserInstall(
171 const base::FilePath& exe_path) {
172 return InstallUtil::IsPerUserInstall(exe_path);
175 bool ChromeCrashReporterClient::GetShouldDumpLargerDumps(
176 bool is_per_user_install) {
177 base::string16 channel_name =
178 GoogleUpdateSettings::GetChromeChannel(!is_per_user_install);
180 // Capture more detail in crash dumps for beta and dev channel builds.
181 return (channel_name == installer::kChromeChannelDev ||
182 channel_name == installer::kChromeChannelBeta ||
183 channel_name == GoogleChromeSxSDistribution::ChannelName());
186 int ChromeCrashReporterClient::GetResultCodeRespawnFailed() {
187 return chrome::RESULT_CODE_RESPAWN_FAILED;
190 void ChromeCrashReporterClient::InitBrowserCrashDumpsRegKey() {
191 #if !defined(NACL_WIN64)
192 if (GetCollectStatsConsent()){
193 crash_reporting_metrics_.reset(new browser_watcher::CrashReportingMetrics(
194 InstallUtil::IsChromeSxSProcess()
195 ? chrome::kBrowserCrashDumpAttemptsRegistryPathSxS
196 : chrome::kBrowserCrashDumpAttemptsRegistryPath));
198 #endif
201 void ChromeCrashReporterClient::RecordCrashDumpAttempt(bool is_real_crash) {
202 #if !defined(NACL_WIN64)
203 if (!crash_reporting_metrics_)
204 return;
206 if (is_real_crash)
207 crash_reporting_metrics_->RecordCrashDumpAttempt();
208 else
209 crash_reporting_metrics_->RecordDumpWithoutCrashAttempt();
210 #endif
213 void ChromeCrashReporterClient::RecordCrashDumpAttemptResult(bool is_real_crash,
214 bool succeeded) {
215 #if !defined(NACL_WIN64)
216 if (!crash_reporting_metrics_)
217 return;
219 if (is_real_crash)
220 crash_reporting_metrics_->RecordCrashDumpAttemptResult(succeeded);
221 else
222 crash_reporting_metrics_->RecordDumpWithoutCrashAttemptResult(succeeded);
223 #endif
226 bool ChromeCrashReporterClient::ReportingIsEnforcedByPolicy(
227 bool* breakpad_enabled) {
228 // Determine whether configuration management allows loading the crash reporter.
229 // Since the configuration management infrastructure is not initialized at this
230 // point, we read the corresponding registry key directly. The return status
231 // indicates whether policy data was successfully read. If it is true,
232 // |breakpad_enabled| contains the value set by policy.
233 base::string16 key_name =
234 base::UTF8ToUTF16(policy::key::kMetricsReportingEnabled);
235 DWORD value = 0;
236 base::win::RegKey hklm_policy_key(HKEY_LOCAL_MACHINE,
237 policy::kRegistryChromePolicyKey, KEY_READ);
238 if (hklm_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) {
239 *breakpad_enabled = value != 0;
240 return true;
243 base::win::RegKey hkcu_policy_key(HKEY_CURRENT_USER,
244 policy::kRegistryChromePolicyKey, KEY_READ);
245 if (hkcu_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) {
246 *breakpad_enabled = value != 0;
247 return true;
250 return false;
252 #endif // defined(OS_WIN)
254 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS)
255 void ChromeCrashReporterClient::GetProductNameAndVersion(
256 const char** product_name,
257 const char** version) {
258 DCHECK(product_name);
259 DCHECK(version);
260 #if defined(OS_ANDROID)
261 *product_name = "Chrome_Android";
262 #elif defined(OS_CHROMEOS)
263 *product_name = "Chrome_ChromeOS";
264 #else // OS_LINUX
265 #if !defined(ADDRESS_SANITIZER)
266 *product_name = "Chrome_Linux";
267 #else
268 *product_name = "Chrome_Linux_ASan";
269 #endif
270 #endif
272 *version = PRODUCT_VERSION;
275 base::FilePath ChromeCrashReporterClient::GetReporterLogFilename() {
276 return base::FilePath(CrashUploadList::kReporterLogFilename);
278 #endif
280 bool ChromeCrashReporterClient::GetCrashDumpLocation(
281 base::FilePath* crash_dir) {
282 // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate
283 // location to write breakpad crash dumps can be set.
284 scoped_ptr<base::Environment> env(base::Environment::Create());
285 std::string alternate_crash_dump_location;
286 if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_crash_dump_location)) {
287 base::FilePath crash_dumps_dir_path =
288 base::FilePath::FromUTF8Unsafe(alternate_crash_dump_location);
289 PathService::Override(chrome::DIR_CRASH_DUMPS, crash_dumps_dir_path);
292 return PathService::Get(chrome::DIR_CRASH_DUMPS, crash_dir);
295 size_t ChromeCrashReporterClient::RegisterCrashKeys() {
296 // Note: On Windows this only affects the EXE. A separate invocation from
297 // child_process_logging_win.cc registers crash keys for Chrome.dll.
298 #if defined(OS_WIN) && defined(COMPONENT_BUILD)
299 // On Windows, this is not called in a component build, as in that case a
300 // single copy of 'base' is shared by the EXE and the various DLLs, and that
301 // copy is configured by child_process_logging_win.cc.
302 NOTREACHED();
303 return 0;
304 #else
305 return crash_keys::RegisterChromeCrashKeys();
306 #endif
309 bool ChromeCrashReporterClient::IsRunningUnattended() {
310 scoped_ptr<base::Environment> env(base::Environment::Create());
311 return env->HasVar(env_vars::kHeadless);
314 bool ChromeCrashReporterClient::GetCollectStatsConsent() {
315 #if defined(GOOGLE_CHROME_BUILD)
316 bool is_official_chrome_build = true;
317 #else
318 bool is_official_chrome_build = false;
319 #endif
321 #if defined(OS_CHROMEOS)
322 bool is_guest_session = base::CommandLine::ForCurrentProcess()->HasSwitch(
323 chromeos::switches::kGuestSession);
324 bool is_stable_channel =
325 chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_STABLE;
327 if (is_guest_session && is_stable_channel)
328 return false;
329 #endif // defined(OS_CHROMEOS)
331 #if defined(OS_ANDROID)
332 // TODO(jcivelli): we should not initialize the crash-reporter when it was not
333 // enabled. Right now if it is disabled we still generate the minidumps but we
334 // do not upload them.
335 return is_official_chrome_build;
336 #else // !defined(OS_ANDROID)
337 return is_official_chrome_build &&
338 GoogleUpdateSettings::GetCollectStatsConsent();
339 #endif // defined(OS_ANDROID)
342 #if defined(OS_ANDROID)
343 int ChromeCrashReporterClient::GetAndroidMinidumpDescriptor() {
344 return kAndroidMinidumpDescriptor;
346 #endif
348 bool ChromeCrashReporterClient::EnableBreakpadForProcess(
349 const std::string& process_type) {
350 return process_type == switches::kRendererProcess ||
351 process_type == switches::kPluginProcess ||
352 process_type == switches::kPpapiPluginProcess ||
353 process_type == switches::kZygoteProcess ||
354 process_type == switches::kGpuProcess;
357 } // namespace chrome