diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/browser_main.cc | 23 | ||||
-rw-r--r-- | chrome/browser/browser_process.h | 6 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 43 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.h | 8 | ||||
-rw-r--r-- | chrome/browser/first_run.h | 39 | ||||
-rw-r--r-- | chrome/browser/first_run_gtk.cc | 45 | ||||
-rw-r--r-- | chrome/browser/first_run_win.cc | 15 |
7 files changed, 146 insertions, 33 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 790502f..179201d 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -618,6 +618,19 @@ OSStatus KeychainCallback(SecKeychainEvent keychain_event, } // namespace +#if defined(OS_WIN) +#define DLLEXPORT __declspec(dllexport) + +// We use extern C for the prototype DLLEXPORT to avoid C++ name mangling. +extern "C" { +DLLEXPORT void __cdecl RelaunchChromeBrowserWithNewCommandLineIfNeeded(); +} + +DLLEXPORT void __cdecl RelaunchChromeBrowserWithNewCommandLineIfNeeded() { + Upgrade::RelaunchChromeBrowserWithNewCommandLineIfNeeded(); +} +#endif + // Main routine for running as the Browser process. int BrowserMain(const MainFunctionParams& parameters) { const CommandLine& parsed_command_line = parameters.command_line_; @@ -1177,7 +1190,7 @@ 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) +#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) // 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 @@ -1185,6 +1198,14 @@ int BrowserMain(const MainFunctionParams& parameters) { g_browser_process->StartAutoupdateTimer(); #endif +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) + // On Linux, the running exe will be updated if an upgrade becomes + // available while the browser is running. We need to save the last + // modified time of the exe, so we can compare to determine if there is + // an upgrade while the browser is kept alive by a persistent extension. + Upgrade::SaveLastModifiedTimeOfExe(); +#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_process.h b/chrome/browser/browser_process.h index e6f6eb3..91614b6 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -139,8 +139,7 @@ class BrowserProcess { // disk. virtual void CheckForInspectorFiles() = 0; -#if defined(OS_WIN) - +#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) // 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 @@ -149,8 +148,7 @@ class BrowserProcess { // 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 +#endif // 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 diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index ac623a5..05ea69f 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -4,6 +4,8 @@ #include "chrome/browser/browser_process_impl.h" +#include <map> + #include "app/clipboard/clipboard.h" #include "app/l10n_util.h" #include "base/command_line.h" @@ -63,6 +65,12 @@ #include "chrome/common/render_messages.h" #endif +#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) +// How often to check if the persistent instance of Chrome needs to restart +// to install an update. +static const int kUpdateCheckIntervalHours = 6; +#endif + BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line) : created_resource_dispatcher_host_(false), created_metrics_service_(false), @@ -448,14 +456,14 @@ void BrowserProcessImpl::CheckForInspectorFiles() { NewRunnableMethod(this, &BrowserProcessImpl::DoInspectorFilesCheck)); } -#if defined(OS_WIN) +#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) void BrowserProcessImpl::StartAutoupdateTimer() { autoupdate_timer_.Start( - TimeDelta::FromHours(google_update::kUpdateCheckInvervalHours), + TimeDelta::FromHours(kUpdateCheckIntervalHours), this, &BrowserProcessImpl::OnAutoupdateTimer); } -#endif // OS_WIN +#endif #if defined(IPC_MESSAGE_LOG_ENABLED) @@ -508,8 +516,8 @@ void BrowserProcessImpl::DoInspectorFilesCheck() { have_inspector_files_ = result; } -#if defined(OS_WIN) // Linux doesn't do rename on restart, and Mac is currently - // not supported. +// Mac is currently not supported. +#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) bool BrowserProcessImpl::CanAutorestartForUpdate() const { // Check if browser is in the background and if it needs to be restarted to @@ -531,13 +539,13 @@ const char* const kSwitchesToRemoveOnAutorestart[] = { void BrowserProcessImpl::RestartPersistentInstance() { CommandLine* old_cl = CommandLine::ForCurrentProcess(); - CommandLine new_cl(old_cl->GetProgram()); + scoped_ptr<CommandLine> new_cl(new CommandLine(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++) { + for (size_t i = 0; i < arraysize(kSwitchesToRemoveOnAutorestart); i++) { switches.erase(kSwitchesToRemoveOnAutorestart[i]); } @@ -547,28 +555,29 @@ void BrowserProcessImpl::RestartPersistentInstance() { switches.begin(); i != switches.end(); ++i) { CommandLine::StringType switch_value = i->second; if (switch_value.length() > 0) { - new_cl.AppendSwitchWithValue(i->first, i->second); + new_cl->AppendSwitchWithValue(i->first, i->second); } else { - new_cl.AppendSwitch(i->first); + 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 (!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."; - } + DLOG(WARNING) << "Shutting down current instance of the browser."; + BrowserList::CloseAllBrowsersAndExit(); + + // Transfer ownership to Upgrade. + Upgrade::SetNewCommandLine(new_cl.release()); } void BrowserProcessImpl::OnAutoupdateTimer() { if (CanAutorestartForUpdate()) { + DLOG(WARNING) << "Detected update. Restarting browser."; RestartPersistentInstance(); } } -#endif +#endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 93e6ab3..d476b58 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -195,9 +195,9 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { virtual void CheckForInspectorFiles(); -#if defined(OS_WIN) +#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) void StartAutoupdateTimer(); -#endif // OS_WIN +#endif virtual bool have_inspector_files() const { return have_inspector_files_; @@ -314,7 +314,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { // Our best estimate about the existence of the inspector directory. bool have_inspector_files_; -#if defined(OS_WIN) +#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) base::RepeatingTimer<BrowserProcessImpl> autoupdate_timer_; // Gets called by autoupdate timer to see if browser needs restart and can be @@ -322,7 +322,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { void OnAutoupdateTimer(); bool CanAutorestartForUpdate() const; void RestartPersistentInstance(); -#endif // OS_WIN +#endif // defined(OS_WIN) || defined(OS_LINUX) DISALLOW_COPY_AND_ASSIGN(BrowserProcessImpl); }; diff --git a/chrome/browser/first_run.h b/chrome/browser/first_run.h index a3310ed..0ac3da5 100644 --- a/chrome/browser/first_run.h +++ b/chrome/browser/first_run.h @@ -137,12 +137,13 @@ class FirstRun { DISALLOW_IMPLICIT_CONSTRUCTORS(FirstRun); }; -#if defined(OS_WIN) +#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) // This class contains the actions that need to be performed when an upgrade // is required. This involves mainly swapping the chrome exe and relaunching // the new browser. class Upgrade { public: +#if defined(OS_WIN) // Possible results of ShowTryChromeDialog(). enum TryResult { TD_TRY_CHROME, // Launch chrome right now. @@ -168,22 +169,48 @@ 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 + // Combines the two methods, RelaunchChromeBrowser and + // SwapNewChromeExeIfPresent, 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. // |version| can be 0, 1 or 2 and selects what strings to present. static TryResult ShowTryChromeDialog(size_t version); -}; +#endif // OS_WIN + +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) + static void SaveLastModifiedTimeOfExe(); +#endif + + static void SetNewCommandLine(CommandLine* new_command_line) { + // Takes ownership of the pointer. + new_command_line_ = new_command_line; + } + + // Launches a new instance of the browser if the current instance in + // persistent mode an upgrade is detected. + static void RelaunchChromeBrowserWithNewCommandLineIfNeeded(); + + // Windows: + // Checks if chrome_new.exe is present in the current instance's install. + // Linux: + // Checks if the last modified time of chrome is newer than that of the + // current running instance. + static bool IsUpdatePendingRestart(); + +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) + private: + static double GetLastModifiedTimeOfExe(); + static double saved_last_modified_time_of_exe_; #endif + static CommandLine* new_command_line_; +}; +#endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) // A subclass of BrowserProcessImpl that does not have a GoogleURLTracker or // IntranetRedirectDetector so we don't do any URL fetches (as we have no IO diff --git a/chrome/browser/first_run_gtk.cc b/chrome/browser/first_run_gtk.cc index a424d60..2b48d3b 100644 --- a/chrome/browser/first_run_gtk.cc +++ b/chrome/browser/first_run_gtk.cc @@ -139,3 +139,48 @@ bool FirstRun::ImportBookmarks(const std::wstring& import_bookmarks_path) { // for the process to return. return base::LaunchApp(import_cmd, true, false, NULL); } + +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +CommandLine* Upgrade::new_command_line_ = NULL; +double Upgrade::saved_last_modified_time_of_exe_ = 0; + +// static +bool Upgrade::IsUpdatePendingRestart() { + return saved_last_modified_time_of_exe_ != + Upgrade::GetLastModifiedTimeOfExe(); +} + +// static +void Upgrade::SaveLastModifiedTimeOfExe() { + saved_last_modified_time_of_exe_ = Upgrade::GetLastModifiedTimeOfExe(); +} + +// static +void Upgrade::RelaunchChromeBrowserWithNewCommandLineIfNeeded() { + if (new_command_line_) { + if (!base::LaunchApp(*new_command_line_, false, false, NULL)) { + DLOG(ERROR) << "Launching a new instance of the browser failed."; + } else { + DLOG(WARNING) << "Launched a new instance of the browser."; + } + delete new_command_line_; + new_command_line_ = NULL; + } +} + +// static +double Upgrade::GetLastModifiedTimeOfExe() { + FilePath exe_file_path; + if (!PathService::Get(base::FILE_EXE, &exe_file_path)) { + LOG(WARNING) << "Failed to get FilePath object for FILE_EXE."; + return saved_last_modified_time_of_exe_; + } + file_util::FileInfo exe_file_info; + if (!file_util::GetFileInfo(exe_file_path, &exe_file_info)) { + LOG(WARNING) << "Failed to get FileInfo object for FILE_EXE - " + << exe_file_path.value(); + return saved_last_modified_time_of_exe_; + } + return exe_file_info.last_modified.ToDoubleT(); +} +#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) diff --git a/chrome/browser/first_run_win.cc b/chrome/browser/first_run_win.cc index cc34dc1..86a79e5 100644 --- a/chrome/browser/first_run_win.cc +++ b/chrome/browser/first_run_win.cc @@ -205,6 +205,8 @@ class FirsRunDelayedTasks : public NotificationObserver { } // namespace +CommandLine* Upgrade::new_command_line_ = NULL; + bool FirstRun::CreateChromeDesktopShortcut() { std::wstring chrome_exe; if (!PathService::Get(base::FILE_EXE, &chrome_exe)) @@ -410,6 +412,18 @@ bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) { false, false, NULL); } +void Upgrade::RelaunchChromeBrowserWithNewCommandLineIfNeeded() { + if (new_command_line_) { + if (RelaunchChromeBrowser(*new_command_line_)) { + DLOG(ERROR) << "Launching a new instance of the browser failed."; + } else { + DLOG(WARNING) << "Launched a new instance of the browser."; + } + delete new_command_line_; + new_command_line_ = NULL; + } +} + bool Upgrade::SwapNewChromeExeIfPresent() { std::wstring new_chrome_exe; if (!GetNewerChromeFile(&new_chrome_exe)) @@ -1020,4 +1034,3 @@ Upgrade::TryResult Upgrade::ShowTryChromeDialog(size_t version) { TryChromeDialog td; return td.ShowModal(); } - |