Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/app/chrome_main_delegate.h" | 5 #include "chrome/app/chrome_main_delegate.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/base_paths.h" | 10 #include "base/base_paths.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/cpu.h" | 12 #include "base/cpu.h" |
| 13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 14 #include "base/i18n/rtl.h" | 14 #include "base/i18n/rtl.h" |
| 15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 16 #include "base/macros.h" | 16 #include "base/macros.h" |
| 17 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
| 18 #include "base/metrics/statistics_recorder.h" | 18 #include "base/metrics/statistics_recorder.h" |
| 19 #include "base/path_service.h" | 19 #include "base/path_service.h" |
| 20 #include "base/process/memory.h" | 20 #include "base/process/memory.h" |
| 21 #include "base/process/process_handle.h" | 21 #include "base/process/process_handle.h" |
| 22 #include "base/process/process_info.h" | 22 #include "base/process/process_info.h" |
| 23 #include "base/strings/string_util.h" | 23 #include "base/strings/string_util.h" |
| 24 #include "base/time/time.h" | 24 #include "base/time/time.h" |
| 25 #include "base/trace_event/trace_event_impl.h" | 25 #include "base/trace_event/trace_event_impl.h" |
| 26 #include "build/build_config.h" | 26 #include "build/build_config.h" |
| 27 #include "chrome/browser/chrome_content_browser_client.h" | 27 #include "chrome/browser/chrome_content_browser_client.h" |
| 28 #include "chrome/browser/defaults.h" | 28 #include "chrome/browser/defaults.h" |
| 29 #include "chrome/browser/ui/startup/bad_flags_prompt.h" | |
| 29 #include "chrome/common/channel_info.h" | 30 #include "chrome/common/channel_info.h" |
| 30 #include "chrome/common/chrome_constants.h" | 31 #include "chrome/common/chrome_constants.h" |
| 31 #include "chrome/common/chrome_content_client.h" | 32 #include "chrome/common/chrome_content_client.h" |
| 32 #include "chrome/common/chrome_paths.h" | 33 #include "chrome/common/chrome_paths.h" |
| 33 #include "chrome/common/chrome_paths_internal.h" | 34 #include "chrome/common/chrome_paths_internal.h" |
| 34 #include "chrome/common/chrome_result_codes.h" | 35 #include "chrome/common/chrome_result_codes.h" |
| 35 #include "chrome/common/chrome_switches.h" | 36 #include "chrome/common/chrome_switches.h" |
| 36 #include "chrome/common/crash_keys.h" | 37 #include "chrome/common/crash_keys.h" |
| 37 #include "chrome/common/features.h" | 38 #include "chrome/common/features.h" |
| 38 #include "chrome/common/logging_chrome.h" | 39 #include "chrome/common/logging_chrome.h" |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 } | 352 } |
| 352 #endif // !defined(OS_MACOSX) && !defined(OS_ANDROID) | 353 #endif // !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 353 | 354 |
| 354 #endif // OS_POSIX | 355 #endif // OS_POSIX |
| 355 | 356 |
| 356 struct MainFunction { | 357 struct MainFunction { |
| 357 const char* name; | 358 const char* name; |
| 358 int (*function)(const content::MainFunctionParams&); | 359 int (*function)(const content::MainFunctionParams&); |
| 359 }; | 360 }; |
| 360 | 361 |
| 362 #if !defined(OS_ANDROID) | |
| 363 void InitLogging(const std::string& process_type) { | |
| 364 logging::OldFileDeletionState file_state = | |
| 365 logging::APPEND_TO_OLD_LOG_FILE; | |
| 366 if (process_type.empty()) { | |
| 367 file_state = logging::DELETE_OLD_LOG_FILE; | |
| 368 } | |
| 369 const base::CommandLine& command_line = | |
| 370 *base::CommandLine::ForCurrentProcess(); | |
| 371 logging::InitChromeLogging(command_line, file_state); | |
| 372 } | |
| 373 #endif | |
| 374 | |
| 375 #if !defined(CHROME_MULTIPLE_DLL_CHILD) | |
| 376 void RecordMainStartupMetrics(base::TimeTicks exe_entry_point_ticks) { | |
| 377 if (!exe_entry_point_ticks.is_null()) | |
| 378 startup_metric_utils::RecordExeMainEntryPointTicks(exe_entry_point_ticks); | |
| 379 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) | |
| 380 // Record the startup process creation time on supported platforms. | |
| 381 startup_metric_utils::RecordStartupProcessCreationTime( | |
| 382 base::CurrentProcessInfo::CreationTime()); | |
| 383 #endif | |
| 384 | |
| 385 // On Android the main entry point time is the time when the Java code starts. | |
| 386 // This happens before the shared library containing this code is even loaded. | |
| 387 // The Java startup code has recorded that time, but the C++ code can't fetch it | |
| 388 // from the Java side until it has initialized the JNI. See | |
| 389 // ChromeMainDelegateAndroid. | |
| 390 #if !defined(OS_ANDROID) | |
| 391 startup_metric_utils::RecordMainEntryPointTime(base::Time::Now()); | |
| 392 #endif | |
| 393 } | |
| 394 #endif // !defined(CHROME_MULTIPLE_DLL_CHILD) | |
| 395 | |
| 396 } // namespace | |
| 397 | |
| 361 // Initializes the user data dir. Must be called before InitializeLocalState(). | 398 // Initializes the user data dir. Must be called before InitializeLocalState(). |
| 362 void InitializeUserDataDir() { | 399 // WARNING! It is important that this code match behavior with |
|
grt (UTC plus 2)
2016/11/16 13:24:52
is it necessary to do the work in both places? i i
scottmg
2016/11/16 21:01:18
Possibly... (it's not quite an install detail", bu
grt (UTC plus 2)
2016/11/17 09:20:25
Maybe for Windows this code can get the value from
| |
| 363 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 400 // GetUserDataDirectory() in chrome_elf. The two functions must be updated in |
| 401 // sync. | |
| 402 void InitializeUserDataDir(base::CommandLine* command_line) { | |
| 364 base::FilePath user_data_dir = | 403 base::FilePath user_data_dir = |
| 365 command_line->GetSwitchValuePath(switches::kUserDataDir); | 404 command_line->GetSwitchValuePath(switches::kUserDataDir); |
| 366 std::string process_type = | 405 std::string process_type = |
| 367 command_line->GetSwitchValueASCII(switches::kProcessType); | 406 command_line->GetSwitchValueASCII(switches::kProcessType); |
| 368 | |
| 369 #if defined(OS_LINUX) | 407 #if defined(OS_LINUX) |
| 370 // On Linux, Chrome does not support running multiple copies under different | 408 // On Linux, Chrome does not support running multiple copies under different |
| 371 // DISPLAYs, so the profile directory can be specified in the environment to | 409 // DISPLAYs, so the profile directory can be specified in the environment to |
| 372 // support the virtual desktop use-case. | 410 // support the virtual desktop use-case. |
| 373 if (user_data_dir.empty()) { | 411 if (user_data_dir.empty()) { |
| 374 std::string user_data_dir_string; | 412 std::string user_data_dir_string; |
| 375 std::unique_ptr<base::Environment> environment(base::Environment::Create()); | 413 std::unique_ptr<base::Environment> environment(base::Environment::Create()); |
| 376 if (environment->GetVar("CHROME_USER_DATA_DIR", &user_data_dir_string) && | 414 if (environment->GetVar("CHROME_USER_DATA_DIR", &user_data_dir_string) && |
| 377 base::IsStringUTF8(user_data_dir_string)) { | 415 base::IsStringUTF8(user_data_dir_string)) { |
| 378 user_data_dir = base::FilePath::FromUTF8Unsafe(user_data_dir_string); | 416 user_data_dir = base::FilePath::FromUTF8Unsafe(user_data_dir_string); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 390 | 428 |
| 391 const bool specified_directory_was_invalid = !user_data_dir.empty() && | 429 const bool specified_directory_was_invalid = !user_data_dir.empty() && |
| 392 !PathService::OverrideAndCreateIfNeeded(chrome::DIR_USER_DATA, | 430 !PathService::OverrideAndCreateIfNeeded(chrome::DIR_USER_DATA, |
| 393 user_data_dir, false, true); | 431 user_data_dir, false, true); |
| 394 // Save inaccessible or invalid paths so the user may be prompted later. | 432 // Save inaccessible or invalid paths so the user may be prompted later. |
| 395 if (specified_directory_was_invalid) | 433 if (specified_directory_was_invalid) |
| 396 chrome::SetInvalidSpecifiedUserDataDir(user_data_dir); | 434 chrome::SetInvalidSpecifiedUserDataDir(user_data_dir); |
| 397 | 435 |
| 398 // Warn and fail early if the process fails to get a user data directory. | 436 // Warn and fail early if the process fails to get a user data directory. |
| 399 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { | 437 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { |
| 400 // If an invalid command-line or policy override was specified, the user | 438 chrome::MaybeShowInvalidUserDataDirWarningDialog(); |
| 401 // will be given an error with that value. Otherwise, use the directory | 439 LOG(FATAL) << "Unable to get the user data directory " |
| 402 // returned by PathService (or the fallback default directory) in the error. | 440 << "for process type: " << process_type; |
| 403 if (!specified_directory_was_invalid) { | |
| 404 // PathService::Get() returns false and yields an empty path if it fails | |
| 405 // to create DIR_USER_DATA. Retrieve the default value manually to display | |
| 406 // a more meaningful error to the user in that case. | |
| 407 if (user_data_dir.empty()) | |
| 408 chrome::GetDefaultUserDataDirectory(&user_data_dir); | |
| 409 chrome::SetInvalidSpecifiedUserDataDir(user_data_dir); | |
| 410 } | |
| 411 | |
| 412 // The browser process (which is identified by an empty |process_type|) will | |
| 413 // handle the error later; other processes that need the dir crash here. | |
| 414 CHECK(process_type.empty()) << "Unable to get the user data directory " | |
| 415 << "for process type: " << process_type; | |
| 416 } | 441 } |
| 417 | 442 |
| 418 // Append the fallback user data directory to the commandline. Otherwise, | 443 // Append the fallback user data directory to the commandline. Otherwise, |
| 419 // child or service processes will attempt to use the invalid directory. | 444 // child or service processes will attempt to use the invalid directory. |
| 420 if (specified_directory_was_invalid) | 445 if (specified_directory_was_invalid) |
| 421 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir); | 446 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir); |
| 422 } | 447 } |
| 423 | 448 |
| 424 #if !defined(OS_ANDROID) | |
| 425 void InitLogging(const std::string& process_type) { | |
| 426 logging::OldFileDeletionState file_state = | |
| 427 logging::APPEND_TO_OLD_LOG_FILE; | |
| 428 if (process_type.empty()) { | |
| 429 file_state = logging::DELETE_OLD_LOG_FILE; | |
| 430 } | |
| 431 const base::CommandLine& command_line = | |
| 432 *base::CommandLine::ForCurrentProcess(); | |
| 433 logging::InitChromeLogging(command_line, file_state); | |
| 434 } | |
| 435 #endif | |
| 436 | |
| 437 #if !defined(CHROME_MULTIPLE_DLL_CHILD) | |
| 438 void RecordMainStartupMetrics(base::TimeTicks exe_entry_point_ticks) { | |
| 439 if (!exe_entry_point_ticks.is_null()) | |
| 440 startup_metric_utils::RecordExeMainEntryPointTicks(exe_entry_point_ticks); | |
| 441 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) | |
| 442 // Record the startup process creation time on supported platforms. | |
| 443 startup_metric_utils::RecordStartupProcessCreationTime( | |
| 444 base::CurrentProcessInfo::CreationTime()); | |
| 445 #endif | |
| 446 | |
| 447 // On Android the main entry point time is the time when the Java code starts. | |
| 448 // This happens before the shared library containing this code is even loaded. | |
| 449 // The Java startup code has recorded that time, but the C++ code can't fetch it | |
| 450 // from the Java side until it has initialized the JNI. See | |
| 451 // ChromeMainDelegateAndroid. | |
| 452 #if !defined(OS_ANDROID) | |
| 453 startup_metric_utils::RecordMainEntryPointTime(base::Time::Now()); | |
| 454 #endif | |
| 455 } | |
| 456 #endif // !defined(CHROME_MULTIPLE_DLL_CHILD) | |
| 457 | |
| 458 } // namespace | |
| 459 | 449 |
| 460 ChromeMainDelegate::ChromeMainDelegate() | 450 ChromeMainDelegate::ChromeMainDelegate() |
| 461 : ChromeMainDelegate(base::TimeTicks()) {} | 451 : ChromeMainDelegate(base::TimeTicks()) {} |
| 462 | 452 |
| 463 ChromeMainDelegate::ChromeMainDelegate(base::TimeTicks exe_entry_point_ticks) { | 453 ChromeMainDelegate::ChromeMainDelegate(base::TimeTicks exe_entry_point_ticks) { |
| 464 #if !defined(CHROME_MULTIPLE_DLL_CHILD) | 454 #if !defined(CHROME_MULTIPLE_DLL_CHILD) |
| 465 // Record startup metrics in the browser process. For component builds, there | 455 // Record startup metrics in the browser process. For component builds, there |
| 466 // is no way to know the type of process (process command line is not yet | 456 // is no way to know the type of process (process command line is not yet |
| 467 // initialized), so the function below will also be called in renderers. | 457 // initialized), so the function below will also be called in renderers. |
| 468 // This doesn't matter as it simply sets global variables. | 458 // This doesn't matter as it simply sets global variables. |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 741 child_process_logging::Init(); | 731 child_process_logging::Init(); |
| 742 #endif | 732 #endif |
| 743 #if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) | 733 #if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) |
| 744 // Create an instance of the CPU class to parse /proc/cpuinfo and cache | 734 // Create an instance of the CPU class to parse /proc/cpuinfo and cache |
| 745 // cpu_brand info. | 735 // cpu_brand info. |
| 746 base::CPU cpu_info; | 736 base::CPU cpu_info; |
| 747 #endif | 737 #endif |
| 748 | 738 |
| 749 // Initialize the user data dir for any process type that needs it. | 739 // Initialize the user data dir for any process type that needs it. |
| 750 if (chrome::ProcessNeedsProfileDir(process_type)) { | 740 if (chrome::ProcessNeedsProfileDir(process_type)) { |
| 751 InitializeUserDataDir(); | 741 InitializeUserDataDir(base::CommandLine::ForCurrentProcess()); |
| 752 #if defined(OS_WIN) && !defined(CHROME_MULTIPLE_DLL_CHILD) | 742 #if defined(OS_WIN) && !defined(CHROME_MULTIPLE_DLL_CHILD) |
| 753 if (downgrade::IsMSIInstall()) { | 743 if (downgrade::IsMSIInstall()) { |
| 754 downgrade::MoveUserDataForFirstRunAfterDowngrade(); | 744 downgrade::MoveUserDataForFirstRunAfterDowngrade(); |
| 755 base::FilePath user_data_dir; | 745 base::FilePath user_data_dir; |
| 756 if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) | 746 if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) |
| 757 downgrade::UpdateLastVersion(user_data_dir); | 747 downgrade::UpdateLastVersion(user_data_dir); |
| 758 } | 748 } |
| 759 #endif | 749 #endif |
| 760 } | 750 } |
| 761 | 751 |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1054 case version_info::Channel::CANARY: | 1044 case version_info::Channel::CANARY: |
| 1055 return true; | 1045 return true; |
| 1056 case version_info::Channel::DEV: | 1046 case version_info::Channel::DEV: |
| 1057 case version_info::Channel::BETA: | 1047 case version_info::Channel::BETA: |
| 1058 case version_info::Channel::STABLE: | 1048 case version_info::Channel::STABLE: |
| 1059 default: | 1049 default: |
| 1060 // Don't enable instrumentation. | 1050 // Don't enable instrumentation. |
| 1061 return false; | 1051 return false; |
| 1062 } | 1052 } |
| 1063 } | 1053 } |
| OLD | NEW |