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/browser/chrome_browser_main.h" | 5 #include "chrome/browser/chrome_browser_main.h" |
6 | 6 |
7 #if defined(TOOLKIT_GTK) | 7 #if defined(TOOLKIT_GTK) |
8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
9 #endif | 9 #endif |
10 | 10 |
| 11 #include <limits.h> |
11 #include <string> | 12 #include <string> |
12 #include <vector> | 13 #include <vector> |
13 | 14 |
14 #include "base/at_exit.h" | 15 #include "base/at_exit.h" |
15 #include "base/bind.h" | 16 #include "base/bind.h" |
16 #include "base/command_line.h" | 17 #include "base/command_line.h" |
17 #include "base/debug/trace_event.h" | 18 #include "base/debug/trace_event.h" |
18 #include "base/file_util.h" | 19 #include "base/file_util.h" |
19 #include "base/files/file_path.h" | 20 #include "base/files/file_path.h" |
| 21 #include "base/memory/ref_counted.h" |
20 #include "base/metrics/field_trial.h" | 22 #include "base/metrics/field_trial.h" |
21 #include "base/metrics/histogram.h" | 23 #include "base/metrics/histogram.h" |
22 #include "base/path_service.h" | 24 #include "base/path_service.h" |
23 #include "base/prefs/json_pref_store.h" | 25 #include "base/prefs/json_pref_store.h" |
24 #include "base/prefs/pref_registry_simple.h" | 26 #include "base/prefs/pref_registry_simple.h" |
25 #include "base/prefs/pref_service.h" | 27 #include "base/prefs/pref_service.h" |
26 #include "base/prefs/pref_value_store.h" | 28 #include "base/prefs/pref_value_store.h" |
27 #include "base/process_info.h" | 29 #include "base/process_info.h" |
28 #include "base/process_util.h" | 30 #include "base/process_util.h" |
29 #include "base/run_loop.h" | 31 #include "base/run_loop.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 #include "chrome/browser/metrics/metrics_log.h" | 66 #include "chrome/browser/metrics/metrics_log.h" |
65 #include "chrome/browser/metrics/metrics_service.h" | 67 #include "chrome/browser/metrics/metrics_service.h" |
66 #include "chrome/browser/metrics/thread_watcher.h" | 68 #include "chrome/browser/metrics/thread_watcher.h" |
67 #include "chrome/browser/metrics/tracking_synchronizer.h" | 69 #include "chrome/browser/metrics/tracking_synchronizer.h" |
68 #include "chrome/browser/metrics/variations/variations_service.h" | 70 #include "chrome/browser/metrics/variations/variations_service.h" |
69 #include "chrome/browser/nacl_host/nacl_process_host.h" | 71 #include "chrome/browser/nacl_host/nacl_process_host.h" |
70 #include "chrome/browser/net/chrome_net_log.h" | 72 #include "chrome/browser/net/chrome_net_log.h" |
71 #include "chrome/browser/net/crl_set_fetcher.h" | 73 #include "chrome/browser/net/crl_set_fetcher.h" |
72 #include "chrome/browser/notifications/desktop_notification_service.h" | 74 #include "chrome/browser/notifications/desktop_notification_service.h" |
73 #include "chrome/browser/notifications/desktop_notification_service_factory.h" | 75 #include "chrome/browser/notifications/desktop_notification_service_factory.h" |
| 76 #include "chrome/browser/operation_output.h" |
74 #include "chrome/browser/page_cycler/page_cycler.h" | 77 #include "chrome/browser/page_cycler/page_cycler.h" |
75 #include "chrome/browser/performance_monitor/performance_monitor.h" | 78 #include "chrome/browser/performance_monitor/performance_monitor.h" |
76 #include "chrome/browser/performance_monitor/startup_timer.h" | 79 #include "chrome/browser/performance_monitor/startup_timer.h" |
77 #include "chrome/browser/plugins/plugin_prefs.h" | 80 #include "chrome/browser/plugins/plugin_prefs.h" |
78 #include "chrome/browser/policy/policy_service.h" | 81 #include "chrome/browser/policy/policy_service.h" |
79 #include "chrome/browser/prefs/chrome_pref_service_factory.h" | 82 #include "chrome/browser/prefs/chrome_pref_service_factory.h" |
80 #include "chrome/browser/prefs/command_line_pref_store.h" | 83 #include "chrome/browser/prefs/command_line_pref_store.h" |
81 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 84 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
82 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" | 85 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" |
83 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.
h" | 86 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.
h" |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 if (!command_line.HasSwitch(switches::kDisableCRLSets)) | 411 if (!command_line.HasSwitch(switches::kDisableCRLSets)) |
409 g_browser_process->crl_set_fetcher()->StartInitialLoad(cus); | 412 g_browser_process->crl_set_fetcher()->StartInitialLoad(cus); |
410 #endif | 413 #endif |
411 | 414 |
412 g_browser_process->pnacl_component_installer()->RegisterPnaclComponent( | 415 g_browser_process->pnacl_component_installer()->RegisterPnaclComponent( |
413 cus, command_line); | 416 cus, command_line); |
414 | 417 |
415 cus->Start(); | 418 cus->Start(); |
416 } | 419 } |
417 | 420 |
418 bool ProcessSingletonNotificationCallback( | 421 bool ProcessSingletonOperationCallback( |
419 const CommandLine& command_line, | 422 const CommandLine& command_line, |
420 const base::FilePath& current_directory) { | 423 const base::FilePath& current_directory, |
| 424 scoped_ptr<OperationOutput> operation_output) { |
421 // Drop the request if the browser process is already in shutdown path. | 425 // Drop the request if the browser process is already in shutdown path. |
422 if (!g_browser_process || g_browser_process->IsShuttingDown()) | 426 if (!g_browser_process || g_browser_process->IsShuttingDown()) |
423 return false; | 427 return false; |
424 | 428 |
425 g_browser_process->PlatformSpecificCommandLineProcessing(command_line); | 429 g_browser_process->PlatformSpecificCommandLineProcessing(command_line); |
426 | 430 |
427 // TODO(erikwright): Consider removing this - AFAIK it is no longer used. | 431 // TODO(erikwright): Consider removing this - AFAIK it is no longer used. |
428 // Handle the --uninstall-extension startup action. This needs to done here in | 432 // Handle the --uninstall-extension startup action. This needs to done here in |
429 // the process that is running with the target profile, otherwise the | 433 // the process that is running with the target profile, otherwise the |
430 // uninstall will fail to unload and remove all components. | 434 // uninstall will fail to unload and remove all components. |
(...skipping 13 matching lines...) Expand all Loading... |
444 extension_startup_helper.UninstallExtension(command_line, profile); | 448 extension_startup_helper.UninstallExtension(command_line, profile); |
445 return true; | 449 return true; |
446 } | 450 } |
447 | 451 |
448 base::FilePath user_data_dir = | 452 base::FilePath user_data_dir = |
449 g_browser_process->profile_manager()->user_data_dir(); | 453 g_browser_process->profile_manager()->user_data_dir(); |
450 base::FilePath startup_profile_dir = | 454 base::FilePath startup_profile_dir = |
451 GetStartupProfilePath(user_data_dir, command_line); | 455 GetStartupProfilePath(user_data_dir, command_line); |
452 | 456 |
453 StartupBrowserCreator::ProcessCommandLineAlreadyRunning( | 457 StartupBrowserCreator::ProcessCommandLineAlreadyRunning( |
454 command_line, current_directory, startup_profile_dir); | 458 command_line, |
| 459 current_directory, |
| 460 startup_profile_dir, |
| 461 operation_output.Pass()); |
455 return true; | 462 return true; |
456 } | 463 } |
457 | 464 |
458 void LaunchDevToolsHandlerIfNeeded(Profile* profile, | 465 void LaunchDevToolsHandlerIfNeeded(Profile* profile, |
459 const CommandLine& command_line) { | 466 const CommandLine& command_line) { |
460 if (command_line.HasSwitch(::switches::kRemoteDebuggingPort)) { | 467 if (command_line.HasSwitch(::switches::kRemoteDebuggingPort)) { |
461 std::string port_str = | 468 std::string port_str = |
462 command_line.GetSwitchValueASCII(::switches::kRemoteDebuggingPort); | 469 command_line.GetSwitchValueASCII(::switches::kRemoteDebuggingPort); |
463 int port; | 470 int port; |
464 if (base::StringToInt(port_str, &port) && port > 0 && port < 65535) { | 471 if (base::StringToInt(port_str, &port) && port > 0 && port < 65535) { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 run_message_loop_ = false; | 749 run_message_loop_ = false; |
743 user_data_dir_ = chrome::GetUserDataDir(parameters()); | 750 user_data_dir_ = chrome::GetUserDataDir(parameters()); |
744 | 751 |
745 // Whether this is First Run. |do_first_run_tasks_| should be prefered to this | 752 // Whether this is First Run. |do_first_run_tasks_| should be prefered to this |
746 // unless the desire is actually to know whether this is really First Run | 753 // unless the desire is actually to know whether this is really First Run |
747 // (i.e., even if --no-first-run is passed). | 754 // (i.e., even if --no-first-run is passed). |
748 bool is_first_run = false; | 755 bool is_first_run = false; |
749 // Android's first run is done in Java instead of native. | 756 // Android's first run is done in Java instead of native. |
750 #if !defined(OS_ANDROID) | 757 #if !defined(OS_ANDROID) |
751 process_singleton_.reset(new ChromeProcessSingleton( | 758 process_singleton_.reset(new ChromeProcessSingleton( |
752 user_data_dir_, base::Bind(&ProcessSingletonNotificationCallback))); | 759 user_data_dir_, base::Bind(&ProcessSingletonOperationCallback))); |
753 | 760 |
754 bool force_first_run = | 761 bool force_first_run = |
755 parsed_command_line().HasSwitch(switches::kForceFirstRun); | 762 parsed_command_line().HasSwitch(switches::kForceFirstRun); |
756 bool force_skip_first_run_tasks = | 763 bool force_skip_first_run_tasks = |
757 (!force_first_run && | 764 (!force_first_run && |
758 parsed_command_line().HasSwitch(switches::kNoFirstRun)); | 765 parsed_command_line().HasSwitch(switches::kNoFirstRun)); |
759 | 766 |
760 is_first_run = | 767 is_first_run = |
761 (force_first_run || first_run::IsChromeFirstRun()) && | 768 (force_first_run || first_run::IsChromeFirstRun()) && |
762 !ProfileManager::IsImportProcess(parsed_command_line()); | 769 !ProfileManager::IsImportProcess(parsed_command_line()); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 #endif | 1003 #endif |
997 | 1004 |
998 for (size_t i = 0; i < chrome_extra_parts_.size(); ++i) | 1005 for (size_t i = 0; i < chrome_extra_parts_.size(); ++i) |
999 chrome_extra_parts_[i]->PostBrowserStart(); | 1006 chrome_extra_parts_[i]->PostBrowserStart(); |
1000 #if !defined(OS_ANDROID) | 1007 #if !defined(OS_ANDROID) |
1001 // Allow ProcessSingleton to process messages. | 1008 // Allow ProcessSingleton to process messages. |
1002 process_singleton_->Unlock(); | 1009 process_singleton_->Unlock(); |
1003 #endif | 1010 #endif |
1004 } | 1011 } |
1005 | 1012 |
| 1013 class CaptureOperationOutput { |
| 1014 public: |
| 1015 CaptureOperationOutput() |
| 1016 : exit_code_(new base::RefCountedData<int>(INT_MAX)) {} |
| 1017 |
| 1018 int exit_code() { return exit_code_->data; } |
| 1019 |
| 1020 scoped_ptr<OperationOutput> Wrap(scoped_ptr<OperationOutput> wrapped) { |
| 1021 return scoped_ptr<OperationOutput>(new Wrapper(wrapped.Pass(), exit_code_)); |
| 1022 } |
| 1023 |
| 1024 private: |
| 1025 class Wrapper : public OperationOutput { |
| 1026 public: |
| 1027 Wrapper(scoped_ptr<OperationOutput> wrapped, |
| 1028 const scoped_refptr<base::RefCountedData<int> >& exit_code) |
| 1029 : wrapped_(wrapped.Pass()), |
| 1030 exit_code_(exit_code) { |
| 1031 } |
| 1032 |
| 1033 // OperationOutput implementation. |
| 1034 virtual bool Write(const char* data, unsigned int length) OVERRIDE { |
| 1035 if (wrapped_) |
| 1036 return wrapped_->Write(data, length); |
| 1037 return true; |
| 1038 } |
| 1039 |
| 1040 private: |
| 1041 virtual bool SetExitCode(unsigned int exit_code) OVERRIDE { |
| 1042 bool success = true; |
| 1043 if (wrapped_) |
| 1044 success = OperationOutput::Complete(wrapped_.Pass(), exit_code); |
| 1045 if (success) |
| 1046 exit_code_->data = exit_code; |
| 1047 return success; |
| 1048 } |
| 1049 scoped_ptr<OperationOutput> wrapped_; |
| 1050 scoped_refptr<base::RefCountedData<int> > exit_code_; |
| 1051 |
| 1052 DISALLOW_COPY_AND_ASSIGN(Wrapper); |
| 1053 }; |
| 1054 |
| 1055 scoped_refptr<base::RefCountedData<int> > exit_code_; |
| 1056 |
| 1057 DISALLOW_COPY_AND_ASSIGN(CaptureOperationOutput); |
| 1058 }; |
| 1059 |
1006 #if !defined(OS_ANDROID) | 1060 #if !defined(OS_ANDROID) |
1007 void ChromeBrowserMainParts::RunPageCycler() { | 1061 void ChromeBrowserMainParts::RunPageCycler() { |
1008 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 1062 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
1009 // We assume a native desktop for tests, but we will need to find a way to | 1063 // We assume a native desktop for tests, but we will need to find a way to |
1010 // get the proper host desktop type once we start running these tests in ASH. | 1064 // get the proper host desktop type once we start running these tests in ASH. |
1011 Browser* browser = chrome::FindBrowserWithProfile( | 1065 Browser* browser = chrome::FindBrowserWithProfile( |
1012 profile_, chrome::HOST_DESKTOP_TYPE_NATIVE); | 1066 profile_, chrome::HOST_DESKTOP_TYPE_NATIVE); |
1013 DCHECK(browser); | 1067 DCHECK(browser); |
1014 PageCycler* page_cycler = NULL; | 1068 PageCycler* page_cycler = NULL; |
1015 base::FilePath input_file = | 1069 base::FilePath input_file = |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 #endif | 1500 #endif |
1447 | 1501 |
1448 PreBrowserStart(); | 1502 PreBrowserStart(); |
1449 | 1503 |
1450 // Instantiate the notification UI manager, as this triggers a perf timer | 1504 // Instantiate the notification UI manager, as this triggers a perf timer |
1451 // used to measure startup time. TODO(stevenjb): Figure out what is actually | 1505 // used to measure startup time. TODO(stevenjb): Figure out what is actually |
1452 // triggering the timer and call that explicitly in the approprate place. | 1506 // triggering the timer and call that explicitly in the approprate place. |
1453 // http://crbug.com/105065. | 1507 // http://crbug.com/105065. |
1454 browser_process_->notification_ui_manager(); | 1508 browser_process_->notification_ui_manager(); |
1455 | 1509 |
| 1510 CaptureOperationOutput capture_output; |
| 1511 |
1456 #if !defined(OS_ANDROID) | 1512 #if !defined(OS_ANDROID) |
1457 // Most general initialization is behind us, but opening a | 1513 // Most general initialization is behind us, but opening a |
1458 // tab and/or session restore and such is still to be done. | 1514 // tab and/or session restore and such is still to be done. |
1459 base::TimeTicks browser_open_start = base::TimeTicks::Now(); | 1515 base::TimeTicks browser_open_start = base::TimeTicks::Now(); |
1460 | 1516 |
1461 // We are in regular browser boot sequence. Open initial tabs and enter the | 1517 // We are in regular browser boot sequence. Open initial tabs and enter the |
1462 // main message loop. | 1518 // main message loop. |
1463 int result_code; | 1519 |
1464 #if defined(OS_CHROMEOS) | 1520 #if defined(OS_CHROMEOS) |
1465 // On ChromeOS multiple profiles doesn't apply, and will break if we load | 1521 // On ChromeOS multiple profiles doesn't apply, and will break if we load |
1466 // them this early as the cryptohome hasn't yet been mounted (which happens | 1522 // them this early as the cryptohome hasn't yet been mounted (which happens |
1467 // only once we log in. | 1523 // only once we log in. |
1468 std::vector<Profile*> last_opened_profiles; | 1524 std::vector<Profile*> last_opened_profiles; |
1469 #else | 1525 #else |
1470 std::vector<Profile*> last_opened_profiles = | 1526 std::vector<Profile*> last_opened_profiles = |
1471 g_browser_process->profile_manager()->GetLastOpenedProfiles(); | 1527 g_browser_process->profile_manager()->GetLastOpenedProfiles(); |
1472 #endif | 1528 #endif |
1473 | 1529 |
1474 if (!parsed_command_line().HasSwitch(switches::kDisableComponentUpdate)) | 1530 if (!parsed_command_line().HasSwitch(switches::kDisableComponentUpdate)) |
1475 RegisterComponentsForUpdate(parsed_command_line()); | 1531 RegisterComponentsForUpdate(parsed_command_line()); |
1476 | 1532 |
1477 if (browser_creator_->Start(parsed_command_line(), base::FilePath(), | 1533 if (browser_creator_->Start( |
1478 profile_, last_opened_profiles, &result_code)) { | 1534 parsed_command_line(), base::FilePath(), |
| 1535 profile_, last_opened_profiles, |
| 1536 capture_output.Wrap( |
| 1537 OperationOutput::Create(parsed_command_line())))) { |
1479 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) | 1538 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) |
1480 // Initialize autoupdate timer. Timer callback costs basically nothing | 1539 // Initialize autoupdate timer. Timer callback costs basically nothing |
1481 // when browser is not in persistent mode, so it's OK to let it ride on | 1540 // when browser is not in persistent mode, so it's OK to let it ride on |
1482 // the main thread. This needs to be done here because we don't want | 1541 // the main thread. This needs to be done here because we don't want |
1483 // to start the timer when Chrome is run inside a test harness. | 1542 // to start the timer when Chrome is run inside a test harness. |
1484 browser_process_->StartAutoupdateTimer(); | 1543 browser_process_->StartAutoupdateTimer(); |
1485 #endif | 1544 #endif |
1486 | 1545 |
1487 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 1546 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
1488 // On Linux, the running exe will be updated if an upgrade becomes | 1547 // On Linux, the running exe will be updated if an upgrade becomes |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 if (parameters().ui_task) { | 1601 if (parameters().ui_task) { |
1543 // We end the startup timer here if we have parameters to run, because we | 1602 // We end the startup timer here if we have parameters to run, because we |
1544 // never start to run the main loop (where we normally stop the timer). | 1603 // never start to run the main loop (where we normally stop the timer). |
1545 startup_timer_->SignalStartupComplete( | 1604 startup_timer_->SignalStartupComplete( |
1546 performance_monitor::StartupTimer::STARTUP_TEST); | 1605 performance_monitor::StartupTimer::STARTUP_TEST); |
1547 parameters().ui_task->Run(); | 1606 parameters().ui_task->Run(); |
1548 delete parameters().ui_task; | 1607 delete parameters().ui_task; |
1549 run_message_loop_ = false; | 1608 run_message_loop_ = false; |
1550 } | 1609 } |
1551 | 1610 |
1552 return result_code_; | 1611 return capture_output.exit_code(); |
1553 } | 1612 } |
1554 | 1613 |
1555 bool ChromeBrowserMainParts::MainMessageLoopRun(int* result_code) { | 1614 bool ChromeBrowserMainParts::MainMessageLoopRun(int* result_code) { |
1556 #if defined(OS_ANDROID) | 1615 #if defined(OS_ANDROID) |
1557 // Chrome on Android does not use default MessageLoop. It has its own | 1616 // Chrome on Android does not use default MessageLoop. It has its own |
1558 // Android specific MessageLoop | 1617 // Android specific MessageLoop |
1559 NOTREACHED(); | 1618 NOTREACHED(); |
1560 return true; | 1619 return true; |
1561 #else | 1620 #else |
1562 // Set the result code set in PreMainMessageLoopRun or set above. | 1621 // Set the result code set in PreMainMessageLoopRun or set above. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1732 if (base::win::GetVersion() <= base::win::VERSION_XP) | 1791 if (base::win::GetVersion() <= base::win::VERSION_XP) |
1733 uma_name += "_XP"; | 1792 uma_name += "_XP"; |
1734 | 1793 |
1735 uma_name += "_PreRead_"; | 1794 uma_name += "_PreRead_"; |
1736 uma_name += pre_read_percentage; | 1795 uma_name += pre_read_percentage; |
1737 AddPreReadHistogramTime(uma_name.c_str(), time); | 1796 AddPreReadHistogramTime(uma_name.c_str(), time); |
1738 } | 1797 } |
1739 #endif | 1798 #endif |
1740 #endif | 1799 #endif |
1741 } | 1800 } |
OLD | NEW |