Skip to content

Commit

Permalink
Linux/GTK: implement update notification.
Browse files Browse the repository at this point in the history
BUG=45148
TEST=compile chrome with PRODUCT_VERSION manually set to something higher than the current version (e.g. 7.0.0.0), and manually set the upgrade detector time to something short (like 10 seconds). Launch chrome and wait a short time for the update notification to appear. The update notification should pulse every few seconds, and should stop pulsing when the user opens the wrench menu. The about menu item should launch a dialog that allows the user to restart chrome, restoring the current session.

Review URL: http://codereview.chromium.org/2365003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48795 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
estade@chromium.org committed Jun 3, 2010
1 parent 8622c0c commit 8fcec3c
Show file tree
Hide file tree
Showing 23 changed files with 398 additions and 92 deletions.
4 changes: 4 additions & 0 deletions app/throb_animation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "app/throb_animation.h"

#include <limits>

static const int kDefaultThrobDurationMS = 400;

ThrobAnimation::ThrobAnimation(AnimationDelegate* target)
Expand All @@ -15,6 +17,8 @@ ThrobAnimation::ThrobAnimation(AnimationDelegate* target)
}

void ThrobAnimation::StartThrobbing(int cycles_til_stop) {
cycles_til_stop = cycles_til_stop >= 0 ? cycles_til_stop :
std::numeric_limits<int>::max();
cycles_remaining_ = cycles_til_stop;
throbbing_ = true;
SlideAnimation::SetSlideDuration(throb_duration_);
Expand Down
2 changes: 1 addition & 1 deletion app/throb_animation.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ThrobAnimation : public SlideAnimation {
virtual ~ThrobAnimation() {}

// Starts throbbing. cycles_til_stop gives the number of cycles to do before
// stopping.
// stopping. A negative value means "throb indefinitely".
void StartThrobbing(int cycles_til_stop);

// Sets the duration of the slide animation when throbbing.
Expand Down
11 changes: 11 additions & 0 deletions chrome/app/chrome_dll_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/debug_util.h"
#include "base/file_version_info.h"
#include "base/i18n/icu_util.h"
#include "base/message_loop.h"
#include "base/path_service.h"
Expand All @@ -45,6 +46,7 @@
#include "base/stats_counters.h"
#include "base/stats_table.h"
#include "base/string_util.h"
#include "chrome/app/chrome_version_info.h"
#include "chrome/browser/diagnostics/diagnostics_main.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/common/chrome_constants.h"
Expand Down Expand Up @@ -475,6 +477,15 @@ int ChromeMain(int argc, char** argv) {
#endif

const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();

#if defined(OS_POSIX) && !defined(OS_MACOSX)
if (parsed_command_line.HasSwitch(switches::kProductVersion)) {
scoped_ptr<FileVersionInfo> version(chrome_app::GetChromeVersionInfo());
printf("%s\n", WideToASCII(version->product_version()).c_str());
return 0;
}
#endif

std::string process_type =
parsed_command_line.GetSwitchValueASCII(switches::kProcessType);

Expand Down
6 changes: 2 additions & 4 deletions chrome/browser/browser_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/task_manager.h"
#include "chrome/browser/translate/translate_prefs.h"
#include "chrome/browser/upgrade_detector.h"

#if defined(TOOLKIT_VIEWS) // TODO(port): whittle this down as we port
#include "chrome/browser/views/browser_actions_container.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/update_recommended_message_box.h"
#endif

#if defined(TOOLKIT_GTK)
Expand Down Expand Up @@ -81,9 +81,7 @@ void RegisterLocalState(PrefService* local_state) {
#if defined(TOOLKIT_VIEWS)
BrowserView::RegisterBrowserViewPrefs(local_state);
#endif
#if defined(OS_WIN)
UpdateRecommendedMessageBox::RegisterUpdateRecommendedPrefs(local_state);
#endif
UpgradeDetector::RegisterPrefs(local_state);
TaskManager::RegisterPrefs(local_state);
CookiePromptModalDialog::RegisterPrefs(local_state);
geolocation::RegisterPrefs(local_state);
Expand Down
11 changes: 5 additions & 6 deletions chrome/browser/browser_shutdown.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,21 +161,20 @@ void Shutdown() {
shutdown_type_ != browser_shutdown::END_SESSION) {
Upgrade::SwapNewChromeExeIfPresent();
}
#endif

if (restart_last_session) {
#if defined(OS_WIN) || defined(OS_LINUX)
// Make sure to relaunch the browser with the same command line and add
// Restore Last Session flag if session restore is not set.
CommandLine command_line = CommandLine::FromString(
CommandLine::ForCurrentProcess()->command_line_string());
CommandLine command_line(*CommandLine::ForCurrentProcess());
if (!command_line.HasSwitch(switches::kRestoreLastSession))
command_line.AppendSwitch(switches::kRestoreLastSession);
Upgrade::RelaunchChromeBrowser(command_line);
}
#endif
#if !defined(OS_WIN)
if (restart_last_session)
#else
NOTIMPLEMENTED();
#endif
}

if (shutdown_type_ > NOT_VALID && shutdown_num_processes_ > 0) {
// Measure total shutdown time as late in the process as possible
Expand Down
8 changes: 4 additions & 4 deletions chrome/browser/first_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,6 @@ class Upgrade {
// handle to the event.
static bool IsBrowserAlreadyRunning();

// Launches chrome again simulating a 'user' launch. If chrome could not
// be launched the return is false.
static bool RelaunchChromeBrowser(const CommandLine& command_line);

// If the new_chrome.exe exists (placed by the installer then is swapped
// to chrome.exe and the old chrome is renamed to old_chrome.exe. If there
// is no new_chrome.exe or the swap fails the return is false;
Expand All @@ -180,6 +176,10 @@ class Upgrade {
static TryResult ShowTryChromeDialog(size_t version);
#endif // OS_WIN

// Launches chrome again simulating a 'user' launch. If chrome could not
// be launched the return is false.
static bool RelaunchChromeBrowser(const CommandLine& command_line);

#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
static void SaveLastModifiedTimeOfExe();
#endif
Expand Down
6 changes: 6 additions & 0 deletions chrome/browser/first_run_gtk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "chrome/browser/gtk/first_run_dialog.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/shell_integration.h"
Expand Down Expand Up @@ -152,6 +153,11 @@ void Upgrade::SaveLastModifiedTimeOfExe() {
saved_last_modified_time_of_exe_ = Upgrade::GetLastModifiedTimeOfExe();
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
return base::LaunchApp(command_line, false, false, NULL);
}

// static
void Upgrade::RelaunchChromeBrowserWithNewCommandLineIfNeeded() {
if (new_command_line_) {
Expand Down
80 changes: 79 additions & 1 deletion chrome/browser/gtk/browser_toolbar_gtk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/upgrade_detector.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "gfx/canvas_paint.h"
#include "gfx/gtk_util.h"
#include "gfx/skbitmap_operations.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
Expand All @@ -68,6 +71,13 @@ const int kToolbarWidgetSpacing = 2;
// Amount of rounding on top corners of toolbar. Only used in Gtk theme mode.
const int kToolbarCornerSize = 3;

// The offset in pixels of the upgrade dot on the app menu.
const int kUpgradeDotOffset = 11;

// The duration of the upgrade notification animation (actually the duration
// of a half-throb).
const int kThrobDuration = 1000;

} // namespace

// BrowserToolbarGtk, public ---------------------------------------------------
Expand All @@ -82,7 +92,8 @@ BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window)
window_(window),
profile_(NULL),
sync_service_(NULL),
menu_bar_helper_(this) {
menu_bar_helper_(this),
upgrade_reminder_animation_(this) {
browser_->command_updater()->AddCommandObserver(IDC_BACK, this);
browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this);
browser_->command_updater()->AddCommandObserver(IDC_RELOAD, this);
Expand All @@ -92,6 +103,14 @@ BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window)
registrar_.Add(this,
NotificationType::BROWSER_THEME_CHANGED,
NotificationService::AllSources());
registrar_.Add(this,
NotificationType::UPGRADE_RECOMMENDED,
NotificationService::AllSources());

upgrade_reminder_animation_.SetThrobDuration(kThrobDuration);

if (Singleton<UpgradeDetector>::get()->notify_upgrade())
ShowUpgradeReminder();
}

BrowserToolbarGtk::~BrowserToolbarGtk() {
Expand Down Expand Up @@ -213,11 +232,15 @@ void BrowserToolbarGtk::Init(Profile* profile,
app_menu_image_ = gtk_image_new_from_pixbuf(
theme_provider_->GetRTLEnabledPixbufNamed(IDR_MENU_CHROME));
gtk_container_add(GTK_CONTAINER(chrome_menu), app_menu_image_);
g_signal_connect_after(app_menu_image_, "expose-event",
G_CALLBACK(OnAppMenuImageExposeThunk), this);

app_menu_.reset(new MenuGtk(this, &app_menu_model_));
gtk_box_pack_start(GTK_BOX(menus_hbox), chrome_menu, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(toolbar_right_), menus_hbox, FALSE, FALSE,
kToolbarWidgetSpacing);
g_signal_connect(app_menu_->widget(), "show",
G_CALLBACK(OnAppMenuShowThunk), this);

gtk_box_pack_start(GTK_BOX(toolbar_), toolbar_right_, FALSE, FALSE, 0);

Expand Down Expand Up @@ -425,6 +448,8 @@ void BrowserToolbarGtk::Observe(NotificationType type,
gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_), use_gtk);

UpdateRoundedness();
} else if (type == NotificationType::UPGRADE_RECOMMENDED) {
ShowUpgradeReminder();
} else {
NOTREACHED();
}
Expand Down Expand Up @@ -750,6 +775,10 @@ void BrowserToolbarGtk::NotifyPrefChanged(const std::wstring* pref) {
!home_page_is_new_tab_page_.IsManaged());
}

void BrowserToolbarGtk::ShowUpgradeReminder() {
upgrade_reminder_animation_.StartThrobbing(-1);
}

bool BrowserToolbarGtk::ShouldOnlyShowLocation() const {
// If we're a popup window, only show the location bar (omnibox).
return browser_->type() != Browser::TYPE_NORMAL;
Expand All @@ -763,6 +792,7 @@ void BrowserToolbarGtk::PopupForButton(GtkWidget* button) {
GTK_STATE_ACTIVE);
MenuGtk* menu = button == page_menu_button_.get() ?
page_menu_.get() : app_menu_.get();

menu->PopupAsFromKeyEvent(button);
menu_bar_helper_.MenuStartedShowing(button, menu->widget());
}
Expand All @@ -773,3 +803,51 @@ void BrowserToolbarGtk::PopupForButtonNextTo(GtkWidget* button,
app_menu_button_.get() : page_menu_button_.get();
PopupForButton(other_button);
}

void BrowserToolbarGtk::AnimationEnded(const Animation* animation) {
AnimationProgressed(animation);
}

void BrowserToolbarGtk::AnimationProgressed(const Animation* animation) {
DCHECK_EQ(animation, &upgrade_reminder_animation_);
gtk_widget_queue_draw(app_menu_image_);
}

void BrowserToolbarGtk::AnimationCanceled(const Animation* animation) {
AnimationProgressed(animation);
}

void BrowserToolbarGtk::OnAppMenuShow(GtkWidget* sender) {
upgrade_reminder_animation_.Reset();
}

gboolean BrowserToolbarGtk::OnAppMenuImageExpose(GtkWidget* sender,
GdkEventExpose* expose) {
if (!Singleton<UpgradeDetector>::get()->notify_upgrade())
return FALSE;

SkBitmap badge;
if (upgrade_reminder_animation_.cycles_remaining() > 0 &&
// This funky looking math makes the badge throb for 2 seconds once
// every 8 seconds.
((upgrade_reminder_animation_.cycles_remaining() - 1) / 2) % 4 == 0) {
badge = SkBitmapOperations::CreateBlendedBitmap(
*theme_provider_->GetBitmapNamed(IDR_UPGRADE_DOT_ACTIVE),
*theme_provider_->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE),
upgrade_reminder_animation_.GetCurrentValue());
} else {
badge = *theme_provider_->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE);
}

// Draw the chrome app menu icon onto the canvas.
gfx::CanvasPaint canvas(expose, false);
int x_offset = base::i18n::IsRTL() ?
sender->allocation.width - kUpgradeDotOffset - badge.width() :
kUpgradeDotOffset;
canvas.DrawBitmapInt(
badge,
sender->allocation.x + x_offset,
sender->allocation.y + sender->allocation.height - badge.height());

return FALSE;
}
21 changes: 20 additions & 1 deletion chrome/browser/gtk/browser_toolbar_gtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "app/gtk_signal.h"
#include "app/menus/simple_menu_model.h"
#include "app/throb_animation.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/app_menu_model.h"
#include "chrome/browser/command_updater.h"
Expand Down Expand Up @@ -43,7 +44,8 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
public menus::SimpleMenuModel::Delegate,
public MenuGtk::Delegate,
public NotificationObserver,
public MenuBarHelper::Delegate {
public MenuBarHelper::Delegate,
public AnimationDelegate {
public:
explicit BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window);
virtual ~BrowserToolbarGtk();
Expand Down Expand Up @@ -116,6 +118,11 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
virtual void PopupForButtonNextTo(GtkWidget* button,
GtkMenuDirectionType dir);

// AnimationDelegate implementation ------------------------------------------
virtual void AnimationEnded(const Animation* animation);
virtual void AnimationProgressed(const Animation* animation);
virtual void AnimationCanceled(const Animation* animation);

private:
// Builds a toolbar button with all the properties set.
// |spacing| is the width of padding (in pixels) on the left and right of the
Expand Down Expand Up @@ -165,12 +172,22 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
GdkDragContext*, gint, gint, GtkSelectionData*,
guint, guint);

// Used to stop the upgrade notification animation.
CHROMEGTK_CALLBACK_0(BrowserToolbarGtk, void, OnAppMenuShow);

// Used to draw the upgrade notification badge.
CHROMEGTK_CALLBACK_1(BrowserToolbarGtk, gboolean, OnAppMenuImageExpose,
GdkEventExpose*);

// ProfileSyncServiceObserver method.
virtual void OnStateChanged();

// Updates preference-dependent state.
void NotifyPrefChanged(const std::wstring* pref);

// Start the upgrade notification animation.
void ShowUpgradeReminder();

static void SetSyncMenuLabel(GtkWidget* widget, gpointer userdata);

// Sometimes we only want to show the location w/o the toolbar buttons (e.g.,
Expand Down Expand Up @@ -252,6 +269,8 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Manages the home button drop signal handler.
scoped_ptr<GtkSignalRegistrar> drop_handler_;

ThrobAnimation upgrade_reminder_animation_;

DISALLOW_COPY_AND_ASSIGN(BrowserToolbarGtk);
};

Expand Down
3 changes: 2 additions & 1 deletion chrome/browser/gtk/browser_window_gtk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include "chrome/browser/gtk/tabs/tab_strip_gtk.h"
#include "chrome/browser/gtk/task_manager_gtk.h"
#include "chrome/browser/gtk/theme_install_bubble_view_gtk.h"
#include "chrome/browser/gtk/update_recommended_dialog.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/page_info_window.h"
#include "chrome/browser/pref_service.h"
Expand Down Expand Up @@ -884,7 +885,7 @@ views::Window* BrowserWindowGtk::ShowAboutChromeDialog() {
}

void BrowserWindowGtk::ShowUpdateChromeDialog() {
NOTIMPLEMENTED();
UpdateRecommendedDialog::Show(window_);
}

void BrowserWindowGtk::ShowTaskManager() {
Expand Down
Loading

0 comments on commit 8fcec3c

Please sign in to comment.