diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser_list.cc | 7 | ||||
-rw-r--r-- | chrome/browser/browser_list.h | 9 | ||||
-rw-r--r-- | chrome/browser/browser_main.cc | 53 | ||||
-rw-r--r-- | chrome/browser/browser_main_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/browser_main_mac.mm | 4 | ||||
-rw-r--r-- | chrome/browser/browser_main_win.cc | 12 | ||||
-rw-r--r-- | chrome/browser/browser_main_win.h | 3 | ||||
-rw-r--r-- | chrome/browser/browser_process.h | 13 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 77 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.h | 15 | ||||
-rw-r--r-- | chrome/browser/first_run.h | 9 | ||||
-rw-r--r-- | chrome/browser/first_run_win.cc | 20 | ||||
-rw-r--r-- | chrome/installer/util/google_update_constants.cc | 5 | ||||
-rw-r--r-- | chrome/installer/util/google_update_constants.h | 4 | ||||
-rw-r--r-- | chrome/test/testing_browser_process.h | 5 |
15 files changed, 196 insertions, 44 deletions
diff --git a/chrome/browser/browser_list.cc b/chrome/browser/browser_list.cc index ec7865d1..93af98b 100644 --- a/chrome/browser/browser_list.cc +++ b/chrome/browser/browser_list.cc @@ -310,6 +310,13 @@ bool BrowserList::HasBrowserWithProfile(Profile* profile) { } // static +bool BrowserList::IsInPersistentMode() { + // TODO(atwilson): check the boolean state variable that you will set for + // persisent instances. + return false; +} + +// static BrowserList::list_type BrowserList::last_active_browsers_; // static diff --git a/chrome/browser/browser_list.h b/chrome/browser/browser_list.h index 9ab6e22..a5f40a9 100644 --- a/chrome/browser/browser_list.h +++ b/chrome/browser/browser_list.h @@ -80,6 +80,12 @@ class BrowserList { // browser currently exists. static Browser* FindBrowserWithID(SessionID::id_type desired_id); + // Checks if the browser can be automatically restarted to install upgrades + // The browser can be automatically restarted when: + // 1. It's in the background mode (no visible windows). + // 2. An update exe is present in the install folder. + static bool CanRestartForUpdate(); + // Closes all browsers. If use_post is true the windows are closed by way of // posting a WM_CLOSE message, otherwise the windows are closed directly. In // almost all cases you'll want to use true, the one exception is ending @@ -98,6 +104,9 @@ class BrowserList { // Returns true if there is at least one Browser with the specified profile. static bool HasBrowserWithProfile(Profile* profile); + // Returns true if browser is in persistent mode and false otherwise. + static bool IsInPersistentMode(); + static const_iterator begin() { return browsers_.begin(); } diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index a993769..25df1a8 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -910,6 +910,29 @@ int BrowserMain(const MainFunctionParams& parameters) { } #endif + // When another process is running, use that process instead of starting a + // new one. NotifyOtherProcess will currently give the other process up to + // 20 seconds to respond. Note that this needs to be done before we attempt + // to read the profile. + switch (process_singleton.NotifyOtherProcess()) { + case ProcessSingleton::PROCESS_NONE: + // No process already running, fall through to starting a new one. + break; + + case ProcessSingleton::PROCESS_NOTIFIED: +#if defined(OS_POSIX) && !defined(OS_MACOSX) + printf("%s\n", base::SysWideToNativeMB( + l10n_util::GetString(IDS_USED_EXISTING_BROWSER)).c_str()); +#endif + return ResultCodes::NORMAL_EXIT; + + case ProcessSingleton::PROFILE_IN_USE: + return ResultCodes::PROFILE_IN_USE; + + default: + NOTREACHED(); + } + // Profile creation ---------------------------------------------------------- Profile* profile = CreateProfile(parameters, user_data_dir); @@ -937,29 +960,9 @@ int BrowserMain(const MainFunctionParams& parameters) { } #endif - // When another process is running, use it instead of starting us. - switch (process_singleton.NotifyOtherProcess()) { - case ProcessSingleton::PROCESS_NONE: - // No process already running, fall through to starting a new one. - break; - - case ProcessSingleton::PROCESS_NOTIFIED: -#if defined(OS_POSIX) && !defined(OS_MACOSX) - printf("%s\n", base::SysWideToNativeMB( - l10n_util::GetString(IDS_USED_EXISTING_BROWSER)).c_str()); -#endif - return ResultCodes::NORMAL_EXIT; - - case ProcessSingleton::PROFILE_IN_USE: - return ResultCodes::PROFILE_IN_USE; - - default: - NOTREACHED(); - } - #if defined(OS_WIN) // Do the tasks if chrome has been upgraded while it was last running. - if (!already_running && DoUpgradeTasks(parsed_command_line)) + if (!already_running && Upgrade::DoUpgradeTasks(parsed_command_line)) return ResultCodes::NORMAL_EXIT; #endif @@ -1133,6 +1136,14 @@ int BrowserMain(const MainFunctionParams& parameters) { // the main message loop. if (browser_init.Start(parsed_command_line, std::wstring(), profile, &result_code)) { +#if defined(OS_WIN) + // Initialize autoupdate timer. Timer callback costs basically nothing + // when browser is not in persistent mode, so it's OK to let it ride on + // the main thread. This needs to be done here because we don't want + // to start the timer when Chrome is run inside a test harness. + g_browser_process->StartAutoupdateTimer(); +#endif + // Record now as the last succesful chrome start. GoogleUpdateSettings::SetLastRunTime(); // Call Recycle() here as late as possible, before going into the loop diff --git a/chrome/browser/browser_main_gtk.cc b/chrome/browser/browser_main_gtk.cc index 1b7006a..c64d573 100644 --- a/chrome/browser/browser_main_gtk.cc +++ b/chrome/browser/browser_main_gtk.cc @@ -39,10 +39,6 @@ int DoUninstallTasks(bool chrome_still_running) { return ResultCodes::NORMAL_EXIT; } -bool DoUpgradeTasks(const CommandLine& command_line) { - return ResultCodes::NORMAL_EXIT; -} - int HandleIconsCommands(const CommandLine &parsed_command_line) { return 0; } diff --git a/chrome/browser/browser_main_mac.mm b/chrome/browser/browser_main_mac.mm index 266ae24..c1e0aca 100644 --- a/chrome/browser/browser_main_mac.mm +++ b/chrome/browser/browser_main_mac.mm @@ -80,10 +80,6 @@ int DoUninstallTasks(bool chrome_still_running) { return ResultCodes::NORMAL_EXIT; } -bool DoUpgradeTasks(const CommandLine& command_line) { - return false; -} - int HandleIconsCommands(const CommandLine& parsed_command_line) { return 0; } diff --git a/chrome/browser/browser_main_win.cc b/chrome/browser/browser_main_win.cc index 7b681e5..b10236d 100644 --- a/chrome/browser/browser_main_win.cc +++ b/chrome/browser/browser_main_win.cc @@ -17,6 +17,7 @@ #include "base/i18n/rtl.h" #include "base/path_service.h" #include "base/win_util.h" +#include "chrome/browser/browser_list.h" #include "chrome/browser/first_run.h" #include "chrome/browser/metrics/metrics_service.h" #include "chrome/browser/views/uninstall_view.h" @@ -200,14 +201,3 @@ bool CheckMachineLevelInstall() { } return false; } - -bool DoUpgradeTasks(const CommandLine& command_line) { - if (!Upgrade::SwapNewChromeExeIfPresent()) - return false; - // At this point the chrome.exe has been swapped with the new one. - if (!Upgrade::RelaunchChromeBrowser(command_line)) { - // The re-launch fails. Feel free to panic now. - NOTREACHED(); - } - return true; -} diff --git a/chrome/browser/browser_main_win.h b/chrome/browser/browser_main_win.h index 45bfbf63..66fbc26 100644 --- a/chrome/browser/browser_main_win.h +++ b/chrome/browser/browser_main_win.h @@ -33,7 +33,4 @@ int HandleIconsCommands(const CommandLine &parsed_command_line); // user level Chrome. bool CheckMachineLevelInstall(); -// Handle upgrades if Chromium was upgraded while it was last running. -bool DoUpgradeTasks(const CommandLine& command_line); - #endif // CHROME_BROWSER_BROWSER_MAIN_WIN_H_ diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index 136d3be..e6f6eb3 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -139,6 +139,19 @@ class BrowserProcess { // disk. virtual void CheckForInspectorFiles() = 0; +#if defined(OS_WIN) + + // This will start a timer that, if Chrome is in persistent mode, will check + // whether an update is available, and if that's the case, restart the + // browser. Note that restart code will strip some of the command line keys + // and all loose values from the cl this instance of Chrome was launched with, + // and add the command line key that will force Chrome to start in the + // background mode. For the full list of "blacklisted" keys, refer to + // |kSwitchesToRemoveOnAutorestart| array in browser_process_impl.cc. + virtual void StartAutoupdateTimer() = 0; + +#endif // OS_WIN + // Return true iff we found the inspector files on disk. It's possible to // call this function before we have a definite answer from the disk. In that // case, we default to returning true. diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index afaf666..be8b601 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -12,6 +12,7 @@ #include "base/thread.h" #include "base/waitable_event.h" #include "chrome/browser/appcache/chrome_appcache_service.h" +#include "chrome/browser/browser_list.h" #include "chrome/browser/browser_main.h" #include "chrome/browser/browser_process_sub_thread.h" #include "chrome/browser/browser_trial.h" @@ -21,6 +22,7 @@ #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/download/download_file.h" #include "chrome/browser/download/save_file_manager.h" +#include "chrome/browser/first_run.h" #include "chrome/browser/google_url_tracker.h" #include "chrome/browser/icon_manager.h" #include "chrome/browser/in_process_webkit/dom_storage_context.h" @@ -47,6 +49,7 @@ #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" +#include "chrome/installer/util/google_update_constants.h" #include "ipc/ipc_logging.h" #include "webkit/database/database_tracker.h" @@ -444,6 +447,15 @@ void BrowserProcessImpl::CheckForInspectorFiles() { NewRunnableMethod(this, &BrowserProcessImpl::DoInspectorFilesCheck)); } +#if defined(OS_WIN) +void BrowserProcessImpl::StartAutoupdateTimer() { + autoupdate_timer_.Start( + TimeDelta::FromHours(google_update::kUpdateCheckInvervalHours), + this, + &BrowserProcessImpl::OnAutoupdateTimer); +} +#endif // OS_WIN + #if defined(IPC_MESSAGE_LOG_ENABLED) void BrowserProcessImpl::SetIPCLoggingEnabled(bool enable) { @@ -494,3 +506,68 @@ void BrowserProcessImpl::DoInspectorFilesCheck() { have_inspector_files_ = result; } + +#if defined(OS_WIN) // Linux doesn't do rename on restart, and Mac is currently + // not supported. + +bool BrowserProcessImpl::CanAutorestartForUpdate() const { + // Check if browser is in the background and if it needs to be restarted to + // apply a pending update. + return BrowserList::IsInPersistentMode() && Upgrade::IsUpdatePendingRestart(); +} + +// Switches enumerated here will be removed when a background instance of +// Chrome restarts itself. If your key is designed to only be used once, +// or if it does not make sense when restarting a background instance to +// pick up an automatic update, be sure to add it to this list. +const char* const kSwitchesToRemoveOnAutorestart[] = { + switches::kApp, + switches::kFirstRun, + switches::kImport, + switches::kImportFromFile, + switches::kMakeDefaultBrowser +}; + +void BrowserProcessImpl::RestartPersistentInstance() { + CommandLine* old_cl = CommandLine::ForCurrentProcess(); + CommandLine new_cl(old_cl->GetProgram()); + + std::map<std::string, CommandLine::StringType> switches = + old_cl->GetSwitches(); + + // Remove the keys that we shouldn't pass through during restart. + for (int i = 0; i < arraysize(kSwitchesToRemoveOnAutorestart); i++) { + switches.erase(kSwitchesToRemoveOnAutorestart[i]); + } + + // Append the rest of the switches (along with their values, if any) + // to the new command line + for (std::map<std::string, CommandLine::StringType>::const_iterator i = + switches.begin(); i != switches.end(); ++i) { + CommandLine::StringType switch_value = i->second; + if (switch_value.length() > 0) { + new_cl.AppendSwitchWithValue(i->first, i->second); + } else { + new_cl.AppendSwitch(i->first); + } + } + + // TODO(atwilson): Uncomment the following two lines to add the "persistence" + // switch when the corresponding CL is committed. + // if (!new_cl.HasSwitch(switches::kLongLivedExtensions)) + // new_cl.AppendSwitch(switches::kLongLivedExtensions); + + if (Upgrade::RelaunchChromeBrowser(new_cl)) { + BrowserList::CloseAllBrowsersAndExit(); + } else { + DLOG(ERROR) << "Could not restart browser for autoupdate."; + } +} + +void BrowserProcessImpl::OnAutoupdateTimer() { + if (CanAutorestartForUpdate()) { + RestartPersistentInstance(); + } +} + +#endif diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index d6d870b..93e6ab3 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -15,6 +15,7 @@ #include "base/basictypes.h" #include "base/message_loop.h" #include "base/non_thread_safe.h" +#include "base/timer.h" #include "base/scoped_ptr.h" #include "chrome/browser/automation/automation_provider_list.h" #include "chrome/browser/browser_process.h" @@ -194,6 +195,10 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { virtual void CheckForInspectorFiles(); +#if defined(OS_WIN) + void StartAutoupdateTimer(); +#endif // OS_WIN + virtual bool have_inspector_files() const { return have_inspector_files_; } @@ -309,6 +314,16 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { // Our best estimate about the existence of the inspector directory. bool have_inspector_files_; +#if defined(OS_WIN) + base::RepeatingTimer<BrowserProcessImpl> autoupdate_timer_; + + // Gets called by autoupdate timer to see if browser needs restart and can be + // restarted, and if that's the case, restarts the browser. + void OnAutoupdateTimer(); + bool CanAutorestartForUpdate() const; + void RestartPersistentInstance(); +#endif // OS_WIN + DISALLOW_COPY_AND_ASSIGN(BrowserProcessImpl); }; diff --git a/chrome/browser/first_run.h b/chrome/browser/first_run.h index 2fe71ce..8a9fb7a 100644 --- a/chrome/browser/first_run.h +++ b/chrome/browser/first_run.h @@ -151,6 +151,15 @@ class Upgrade { // is no new_chrome.exe or the swap fails the return is false; static bool SwapNewChromeExeIfPresent(); + // Combines the two methods above to perform the rename and relaunch of + // the browser. Note that relaunch does NOT exit the existing browser process. + // If this is called before message loop is executed, simply exit the main + // function. If browser is already running, you will need to exit it. + static bool DoUpgradeTasks(const CommandLine& command_line); + + // Checks if chrome_new.exe is present in the current instance's install. + static bool IsUpdatePendingRestart(); + // Shows a modal dialog asking the user to give chrome another try. See // above for the possible outcomes of the function. This is an experimental, // non-localized dialog. diff --git a/chrome/browser/first_run_win.cc b/chrome/browser/first_run_win.cc index 0620baa..932bbc5 100644 --- a/chrome/browser/first_run_win.cc +++ b/chrome/browser/first_run_win.cc @@ -444,6 +444,26 @@ bool Upgrade::SwapNewChromeExeIfPresent() { return false; } +// static +bool Upgrade::DoUpgradeTasks(const CommandLine& command_line) { + if (!Upgrade::SwapNewChromeExeIfPresent()) + return false; + // At this point the chrome.exe has been swapped with the new one. + if (!Upgrade::RelaunchChromeBrowser(command_line)) { + // The re-launch fails. Feel free to panic now. + NOTREACHED(); + } + return true; +} + +// static +bool Upgrade::IsUpdatePendingRestart() { + std::wstring new_chrome_exe; + if (!GetNewerChromeFile(&new_chrome_exe)) + return false; + return file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe)); +} + bool OpenFirstRunDialog(Profile* profile, bool homepage_defined, int import_items, diff --git a/chrome/installer/util/google_update_constants.cc b/chrome/installer/util/google_update_constants.cc index 5455aff..496c530 100644 --- a/chrome/installer/util/google_update_constants.cc +++ b/chrome/installer/util/google_update_constants.cc @@ -31,4 +31,7 @@ const wchar_t kRegReferralField[] = L"referral"; const wchar_t kRegEULAAceptedField[] = L"eulaaccepted"; const wchar_t kEnvProductVersionKey[] = L"CHROME_VERSION"; const wchar_t kRegLastRunTimeField[] = L"lastrun"; -} // namespace installer + +const int kUpdateCheckInvervalHours = 6; + +} // namespace google_update diff --git a/chrome/installer/util/google_update_constants.h b/chrome/installer/util/google_update_constants.h index 45d3996..4479d66 100644 --- a/chrome/installer/util/google_update_constants.h +++ b/chrome/installer/util/google_update_constants.h @@ -45,6 +45,10 @@ extern const wchar_t kEnvProductVersionKey[]; // last time that chrome ran in the Time internal format. extern const wchar_t kRegLastRunTimeField[]; +// How often to check if the persistent instance of Chrome needs to restart +// to install an update. +extern const int kUpdateCheckInvervalHours; + } // namespace google_update #endif // CHROME_INSTALLER_UTIL_GOOGLE_UPDATE_CONSTANTS_H_ diff --git a/chrome/test/testing_browser_process.h b/chrome/test/testing_browser_process.h index 0a22151..b95b3a8 100644 --- a/chrome/test/testing_browser_process.h +++ b/chrome/test/testing_browser_process.h @@ -148,6 +148,11 @@ class TestingBrowserProcess : public BrowserProcess { } virtual void CheckForInspectorFiles() {} + +#if defined(OS_WIN) + virtual void StartAutoupdateTimer() {} +#endif // OS_WIN + virtual bool have_inspector_files() const { return true; } #if defined(IPC_MESSAGE_LOG_ENABLED) virtual void SetIPCLoggingEnabled(bool enable) {} |