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 |
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 |