summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser_list.cc7
-rw-r--r--chrome/browser/browser_list.h9
-rw-r--r--chrome/browser/browser_main.cc53
-rw-r--r--chrome/browser/browser_main_gtk.cc4
-rw-r--r--chrome/browser/browser_main_mac.mm4
-rw-r--r--chrome/browser/browser_main_win.cc12
-rw-r--r--chrome/browser/browser_main_win.h3
-rw-r--r--chrome/browser/browser_process.h13
-rw-r--r--chrome/browser/browser_process_impl.cc77
-rw-r--r--chrome/browser/browser_process_impl.h15
-rw-r--r--chrome/browser/first_run.h9
-rw-r--r--chrome/browser/first_run_win.cc20
-rw-r--r--chrome/installer/util/google_update_constants.cc5
-rw-r--r--chrome/installer/util/google_update_constants.h4
-rw-r--r--chrome/test/testing_browser_process.h5
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) {}