diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-27 18:27:14 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-27 18:27:14 +0000 |
commit | 623294c447e00b7485092cdf68d50874a9f0646e (patch) | |
tree | 53135e482180a848d3ab9b0a3643407f63c5b9cc | |
parent | 61b4efcd2a24ed3862775093626247ebddc3f5f0 (diff) | |
download | chromium_src-623294c447e00b7485092cdf68d50874a9f0646e.zip chromium_src-623294c447e00b7485092cdf68d50874a9f0646e.tar.gz chromium_src-623294c447e00b7485092cdf68d50874a9f0646e.tar.bz2 |
Add a button to exit managed mode in place of the profile avatar.
BUG=116060
TEST=none
Review URL: http://codereview.chromium.org/9500003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134308 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 217 insertions, 184 deletions
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 4a2d398..a091b4a 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -355,6 +355,12 @@ <include name="IDR_CONTROLLED_SETTING_RECOMMENDED_GRAY" file="controlled_setting_recommended_gray.png" type="BINDATA" /> <include name="IDR_CONTROLLED_SETTING_RECOMMENDED" file="controlled_setting_recommended.png" type="BINDATA" /> <include name="IDR_CONTROLLED_SETTING_RECOMMENDED_LARGE" file="controlled_setting_recommended_large.png" type="BINDATA" /> + <if expr="not is_macosx"> + <include name="IDR_MANAGED_MODE_AVATAR" file="managed_mode_avatar.png" type="BINDATA" /> + </if> + <if expr="is_macosx"> + <include name="IDR_MANAGED_MODE_AVATAR" file="managed_mode_avatar_mac.png" type="BINDATA" /> + </if> <if expr="pp_ifdef('_google_chrome')"> <include name="IDR_WEBSTORE_ICON" file="google_chrome/webstore_icon.png" type="BINDATA" /> <include name="IDR_WEBSTORE_ICON_16" file="google_chrome/webstore_icon_16.png" type="BINDATA" /> diff --git a/chrome/browser/managed_mode.cc b/chrome/browser/managed_mode.cc index 15706a8..fa4f303 100644 --- a/chrome/browser/managed_mode.cc +++ b/chrome/browser/managed_mode.cc @@ -41,6 +41,9 @@ bool ManagedMode::IsInManagedModeImpl() { // |g_browser_process| can be NULL during startup. if (!g_browser_process) return false; + // Local State can be NULL during unit tests. + if (!g_browser_process->local_state()) + return false; return g_browser_process->local_state()->GetBoolean(prefs::kInManagedMode); } diff --git a/chrome/browser/managed_mode.h b/chrome/browser/managed_mode.h index b3edef0..1925b16 100644 --- a/chrome/browser/managed_mode.h +++ b/chrome/browser/managed_mode.h @@ -22,6 +22,10 @@ struct DefaultSingletonTraits; class PrefService; class Profile; +// Managed mode allows one person to manage the Chrome experience for another +// person by pre-configuring and then locking a managed User profile. +// The ManagedMode class provides methods to check whether the browser is in +// managed mode, and to attempt to enter or leave managed mode. class ManagedMode : public BrowserList::Observer, public content::NotificationObserver { public: diff --git a/chrome/browser/profiles/avatar_menu_model.cc b/chrome/browser/profiles/avatar_menu_model.cc index fb943ee..11c0076 100644 --- a/chrome/browser/profiles/avatar_menu_model.cc +++ b/chrome/browser/profiles/avatar_menu_model.cc @@ -51,7 +51,6 @@ AvatarMenuModel::AvatarMenuModel(ProfileInfoInterface* profile_cache, observer_(observer), browser_(browser) { DCHECK(profile_info_); - DCHECK(observer_); // Don't DCHECK(browser_) so that unit tests can reuse this ctor. // Register this as an observer of the info cache. @@ -76,6 +75,8 @@ AvatarMenuModel::Item::~Item() { } void AvatarMenuModel::SwitchToProfile(size_t index, bool always_create) { + DCHECK(ProfileManager::IsMultipleProfilesEnabled() || + index == GetActiveProfileIndex()); const Item& item = GetItemAt(index); FilePath path = profile_info_->GetPathOfProfileAtIndex(item.model_index); g_browser_process->profile_manager()->CreateProfileAsync( @@ -135,7 +136,8 @@ void AvatarMenuModel::Observe(int type, const content::NotificationDetails& details) { DCHECK_EQ(chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, type); RebuildMenu(); - observer_->OnAvatarMenuModelChanged(this); + if (observer_) + observer_->OnAvatarMenuModelChanged(this); } // static diff --git a/chrome/browser/profiles/avatar_menu_model.h b/chrome/browser/profiles/avatar_menu_model.h index 3e5cf25..d76f876 100644 --- a/chrome/browser/profiles/avatar_menu_model.h +++ b/chrome/browser/profiles/avatar_menu_model.h @@ -49,8 +49,8 @@ class AvatarMenuModel : public content::NotificationObserver { size_t model_index; }; - // Constructor. No parameters can be NULL in practice. |browser| can be NULL - // and a new one will be created if an action requires it. + // Constructor. |observer| can be NULL. |browser| can be NULL and a new one + // will be created if an action requires it. AvatarMenuModel(ProfileInfoInterface* profile_cache, AvatarMenuModelObserver* observer, Browser* browser); diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 1dee07f..abc4049 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -425,6 +425,7 @@ Browser::Browser(Type type, Profile* profile) local_pref_registrar_.Add(prefs::kPrintingEnabled, this); local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this); local_pref_registrar_.Add(prefs::kMetricsReportingEnabled, this); + local_pref_registrar_.Add(prefs::kInManagedMode, this); } profile_pref_registrar_.Init(profile_->GetPrefs()); @@ -4266,6 +4267,8 @@ void Browser::Observe(int type, } else if (pref_name == prefs::kAllowFileSelectionDialogs) { UpdateSaveAsState(GetContentRestrictionsForSelectedTab()); UpdateOpenFileState(); + } else if (pref_name == prefs::kInManagedMode) { + UpdateCommandsForMultipleProfiles(); } else { NOTREACHED(); } @@ -4688,13 +4691,20 @@ void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) { command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui); command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui); command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui); - command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU, - show_main_ui && !profile()->IsOffTheRecord()); #if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC) command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui); #endif UpdateCommandsForBookmarkBar(); + UpdateCommandsForMultipleProfiles(); +} + +void Browser::UpdateCommandsForMultipleProfiles() { + bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen()); + command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU, + show_main_ui && + !profile()->IsOffTheRecord() && + ProfileManager::IsMultipleProfilesEnabled()); } void Browser::UpdatePrintingState(int content_restrictions) { diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 4759f1e..43dad16 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -1146,6 +1146,10 @@ class Browser : public TabHandlerDelegate, // mode. void UpdateCommandsForFullscreenMode(bool is_fullscreen); + // Update commands whose state depends on whether multiple profiles are + // allowed. + void UpdateCommandsForMultipleProfiles(); + // Updates the printing command state. void UpdatePrintingState(int content_restrictions); diff --git a/chrome/browser/ui/cocoa/browser/avatar_button_controller.mm b/chrome/browser/ui/cocoa/browser/avatar_button_controller.mm index 18ff3f1..a03c02b 100644 --- a/chrome/browser/ui/cocoa/browser/avatar_button_controller.mm +++ b/chrome/browser/ui/cocoa/browser/avatar_button_controller.mm @@ -1,11 +1,14 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #import "chrome/browser/ui/cocoa/browser/avatar_button_controller.h" #include "base/sys_string_conversions.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/command_updater.h" +#include "chrome/browser/managed_mode.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/profiles/profile_info_util.h" @@ -28,7 +31,7 @@ #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" @interface AvatarButtonController (Private) -- (void)setOpenMenuOnClick:(BOOL)flag; +- (void)setButtonEnabled:(BOOL)flag; - (IBAction)buttonClicked:(id)sender; - (void)bubbleWillClose:(NSNotification*)notif; - (NSImage*)compositeImageWithShadow:(NSImage*)image; @@ -46,9 +49,9 @@ class Observer : public content::NotificationObserver { } // NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) OVERRIDE { + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE { switch (type) { case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: [button_ updateAvatar]; @@ -125,10 +128,10 @@ const CGFloat kMenuYOffsetAdjust = 1.0; if (browser_->profile()->IsOffTheRecord()) { [self setImage:[self compositeImageWithShadow: gfx::GetCachedImageWithName(@"otr_icon.pdf")]]; - [self setOpenMenuOnClick:NO]; + [self setButtonEnabled:NO]; } else { + [self setButtonEnabled:YES]; observer_.reset(new AvatarButtonControllerInternal::Observer(self)); - [self setOpenMenuOnClick:YES]; [self updateAvatar]; } } @@ -155,6 +158,8 @@ const CGFloat kMenuYOffsetAdjust = 1.0; if (menuController_) return; + DCHECK(browser_->command_updater()->IsCommandEnabled(IDC_SHOW_AVATAR_MENU)); + NSWindowController* wc = [browser_->window()->GetNativeHandle() windowController]; if ([wc isKindOfClass:[BrowserWindowController class]]) { @@ -183,13 +188,17 @@ const CGFloat kMenuYOffsetAdjust = 1.0; // Private ///////////////////////////////////////////////////////////////////// -- (void)setOpenMenuOnClick:(BOOL)flag { +- (void)setButtonEnabled:(BOOL)flag { [self.buttonView setEnabled:flag]; } - (IBAction)buttonClicked:(id)sender { DCHECK_EQ(self.buttonView, sender); - [self showAvatarBubble]; + if (ManagedMode::IsInManagedMode()) { + ManagedMode::LeaveManagedMode(); + } else { + [self showAvatarBubble]; + } } - (void)bubbleWillClose:(NSNotification*)notif { @@ -234,26 +243,33 @@ const CGFloat kMenuYOffsetAdjust = 1.0; // Updates the avatar information from the profile cache. - (void)updateAvatar { + if (ManagedMode::IsInManagedMode()) { + gfx::Image icon = + ResourceBundle::GetSharedInstance().GetNativeImageNamed( + IDR_MANAGED_MODE_AVATAR); + [self setImage:icon.ToNSImage()]; + return; + } ProfileInfoCache& cache = g_browser_process->profile_manager()->GetProfileInfoCache(); size_t index = cache.GetIndexOfProfileWithPath(browser_->profile()->GetPath()); - if (index != std::string::npos) { - BOOL is_gaia_picture = - cache.IsUsingGAIAPictureOfProfileAtIndex(index) && - cache.GetGAIAPictureOfProfileAtIndex(index); - gfx::Image icon = profiles::GetAvatarIconForTitleBar( - cache.GetAvatarIconOfProfileAtIndex(index), is_gaia_picture, - profiles::kAvatarIconWidth, profiles::kAvatarIconHeight); - [self setImage:icon.ToNSImage()]; - - const string16& name = cache.GetNameOfProfileAtIndex(index); - NSString* nsName = base::SysUTF16ToNSString(name); - [self.view setToolTip:nsName]; - [[self.buttonView cell] - accessibilitySetOverrideValue:nsName - forAttribute:NSAccessibilityValueAttribute]; - } + if (index == std::string::npos) + return; + BOOL is_gaia_picture = + cache.IsUsingGAIAPictureOfProfileAtIndex(index) && + cache.GetGAIAPictureOfProfileAtIndex(index); + gfx::Image icon = profiles::GetAvatarIconForTitleBar( + cache.GetAvatarIconOfProfileAtIndex(index), is_gaia_picture, + profiles::kAvatarIconWidth, profiles::kAvatarIconHeight); + [self setImage:icon.ToNSImage()]; + + const string16& name = cache.GetNameOfProfileAtIndex(index); + NSString* nsName = base::SysUTF16ToNSString(name); + [self.view setToolTip:nsName]; + [[self.buttonView cell] + accessibilitySetOverrideValue:nsName + forAttribute:NSAccessibilityValueAttribute]; } // If the second-to-last profile was removed or a second profile was added, diff --git a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h index a76a498..fea1889 100644 --- a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h +++ b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -14,7 +14,6 @@ #import "chrome/browser/ui/cocoa/tracking_area.h" class AvatarMenuModel; -class AvatarMenuModelObserver; class Browser; @class HoverImageButton; @@ -25,9 +24,6 @@ class Browser; // The model that contains the data from the backend. scoped_ptr<AvatarMenuModel> model_; - // Observer for changes to the model. - scoped_ptr<AvatarMenuModelObserver> bridge_; - // Array of the below view controllers. scoped_nsobject<NSMutableArray> items_; } @@ -127,7 +123,6 @@ class Browser; @interface AvatarMenuBubbleController (ExposedForTesting) - (id)initWithModel:(AvatarMenuModel*)model - bridge:(AvatarMenuModelObserver*)bridge parentWindow:(NSWindow*)parent anchoredAt:(NSPoint)point; - (void)performLayout; diff --git a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.mm b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.mm index 07efbd3..71bfe0c 100644 --- a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.mm @@ -9,7 +9,6 @@ #include "base/sys_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/avatar_menu_model.h" -#include "chrome/browser/profiles/avatar_menu_model_observer.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/ui/browser.h" @@ -37,26 +36,6 @@ - (void)highlightItem:(AvatarMenuItemController*)newItem; @end -namespace AvatarMenuInternal { - -class Bridge : public AvatarMenuModelObserver { - public: - Bridge(AvatarMenuBubbleController* controller) : controller_(controller) {} - - // AvatarMenuModelObserver: - void OnAvatarMenuModelChanged(AvatarMenuModel* model) { - // Do nothing. Rebuilding while the bubble is open will cause it to be - // positioned incorrectly. Since the bubble will be dismissed on losing key - // status, it's impossible for the user to edit the information in a - // meaningful way such that it would need to be redrawn. - } - - private: - AvatarMenuBubbleController* controller_; -}; - -} // namespace AvatarMenuInternal - namespace { // Constants taken from the Windows/Views implementation at: @@ -76,13 +55,15 @@ const CGFloat kLabelInset = 49.0; - (id)initWithBrowser:(Browser*)parentBrowser anchoredAt:(NSPoint)point { - AvatarMenuInternal::Bridge* bridge = new AvatarMenuInternal::Bridge(self); + // Pass in a NULL observer. Rebuilding while the bubble is open will cause it + // to be positioned incorrectly. Since the bubble will be dismissed on losing + // key status, it's impossible for the user to edit the information in a + // meaningful way such that it would need to be redrawn. AvatarMenuModel* model = new AvatarMenuModel( - &g_browser_process->profile_manager()->GetProfileInfoCache(), - bridge, parentBrowser); + &g_browser_process->profile_manager()->GetProfileInfoCache(), + NULL, parentBrowser); if ((self = [self initWithModel:model - bridge:bridge parentWindow:parentBrowser->window()->GetNativeHandle() anchoredAt:point])) { } @@ -107,7 +88,6 @@ const CGFloat kLabelInset = 49.0; // Private ///////////////////////////////////////////////////////////////////// - (id)initWithModel:(AvatarMenuModel*)model - bridge:(AvatarMenuModelObserver*)bridge parentWindow:(NSWindow*)parent anchoredAt:(NSPoint)point { // Use an arbitrary height because it will reflect the size of the content. @@ -121,7 +101,6 @@ const CGFloat kLabelInset = 49.0; if ((self = [super initWithWindow:window parentWindow:parent anchoredAt:point])) { - bridge_.reset(bridge); model_.reset(model); [window accessibilitySetOverrideValue: diff --git a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm index cd8ffd9..9abbaa1 100644 --- a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -17,11 +17,6 @@ #include "testing/gtest_mac.h" #include "ui/base/test/cocoa_test_event_utils.h" -class FakeBridge : public AvatarMenuModelObserver { - public: - void OnAvatarMenuModelChanged(AvatarMenuModel* model) OVERRIDE {} -}; - class AvatarMenuBubbleControllerTest : public CocoaTest { public: AvatarMenuBubbleControllerTest() @@ -35,14 +30,12 @@ class AvatarMenuBubbleControllerTest : public CocoaTest { manager_.CreateTestingProfile("test1", ASCIIToUTF16("Test 1"), 1); manager_.CreateTestingProfile("test2", ASCIIToUTF16("Test 2"), 0); - bridge_ = new FakeBridge; - model_ = new AvatarMenuModel(manager_.profile_info_cache(), bridge(), NULL); + model_ = new AvatarMenuModel(manager_.profile_info_cache(), NULL, NULL); NSRect frame = [test_window() frame]; NSPoint point = NSMakePoint(NSMidX(frame), NSMidY(frame)); controller_ = [[AvatarMenuBubbleController alloc] initWithModel:model() - bridge:bridge() parentWindow:test_window() anchoredAt:point]; } @@ -50,7 +43,6 @@ class AvatarMenuBubbleControllerTest : public CocoaTest { TestingProfileManager* manager() { return &manager_; } AvatarMenuBubbleController* controller() { return controller_; } AvatarMenuModel* model() { return model_; } - FakeBridge* bridge() { return bridge_; } AvatarMenuItemController* GetHighlightedItem() { for (AvatarMenuItemController* item in [controller() items]) { @@ -68,7 +60,6 @@ class AvatarMenuBubbleControllerTest : public CocoaTest { // Weak; owned by |controller_|. AvatarMenuModel* model_; - FakeBridge* bridge_; }; TEST_F(AvatarMenuBubbleControllerTest, InitialLayout) { diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index ec6fd54..5bf6214 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm @@ -16,6 +16,7 @@ #include "chrome/browser/bookmarks/bookmark_editor.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/instant/instant_controller.h" +#include "chrome/browser/managed_mode.h" #include "chrome/browser/profiles/avatar_menu_model.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_info_cache.h" @@ -1404,8 +1405,10 @@ enum { - (BOOL)shouldShowAvatar { if (![self hasTabStrip]) return NO; - if (browser_->profile()->IsOffTheRecord()) + if (browser_->profile()->IsOffTheRecord() || + ManagedMode::IsInManagedMode()) { return YES; + } ProfileInfoCache& cache = g_browser_process->profile_manager()->GetProfileInfoCache(); diff --git a/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc b/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc index 411f721..c8560c4 100644 --- a/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc +++ b/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc @@ -1,12 +1,16 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/gtk/avatar_menu_button_gtk.h" #include "base/i18n/rtl.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/command_updater.h" +#include "chrome/browser/managed_mode.h" #include "chrome/browser/profiles/profile_metrics.h" #include "chrome/browser/profiles/profile_info_util.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/gtk/avatar_menu_bubble_gtk.h" #include "chrome/browser/ui/gtk/bubble/bubble_gtk.h" #include "ui/gfx/gtk_util.h" @@ -46,6 +50,11 @@ gboolean AvatarMenuButtonGtk::OnButtonPressed(GtkWidget* widget, if (event->button != 1) return FALSE; + if (ManagedMode::IsInManagedMode()) { + ManagedMode::LeaveManagedMode(); + return TRUE; + } + ShowAvatarBubble(); ProfileMetrics::LogProfileOpenMethod(ProfileMetrics::ICON_AVATAR_BUBBLE); return TRUE; @@ -58,6 +67,7 @@ void AvatarMenuButtonGtk::OnSizeAllocate(GtkWidget* widget, } void AvatarMenuButtonGtk::ShowAvatarBubble() { + DCHECK(browser_->command_updater()->IsCommandEnabled(IDC_SHOW_AVATAR_MENU)); // Only show the avatar bubble if the avatar button is in the title bar. if (gtk_widget_get_parent_window(widget_.get())) new AvatarMenuBubbleGtk(browser_, widget_.get(), arrow_location_, NULL); diff --git a/chrome/browser/ui/gtk/browser_titlebar.cc b/chrome/browser/ui/gtk/browser_titlebar.cc index 559045f..e646d30 100644 --- a/chrome/browser/ui/gtk/browser_titlebar.cc +++ b/chrome/browser/ui/gtk/browser_titlebar.cc @@ -18,7 +18,9 @@ #include "base/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/managed_mode.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/profiles/avatar_menu_model.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/profiles/profile_manager.h" @@ -112,16 +114,6 @@ gboolean OnMouseMoveEvent(GtkWidget* widget, GdkEventMotion* event, return TRUE; } -GdkPixbuf* GetOTRAvatar() { - static GdkPixbuf* otr_avatar = NULL; - if (!otr_avatar) { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - otr_avatar = rb.GetNativeImageNamed( - IDR_OTR_ICON, ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf(); - } - return otr_avatar; -} - // Converts a GdkColor to a color_utils::HSL. color_utils::HSL GdkColorToHSL(const GdkColor* color) { color_utils::HSL hsl; @@ -150,15 +142,6 @@ GdkColor PickLuminosityContrastingColor(const GdkColor* base, return *one; } -// Returns true if there are multiple profiles created. This is used to -// determine whether to display the avatar image. -bool HasMultipleProfiles() { - ProfileInfoCache& cache = - g_browser_process->profile_manager()->GetProfileInfoCache(); - return ProfileManager::IsMultipleProfilesEnabled() && - cache.GetNumberOfProfiles() > 1; -} - } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -803,11 +786,14 @@ void BrowserTitlebar::UpdateAvatar() { if (!avatar_) { if (IsOffTheRecord()) { - avatar_ = gtk_image_new_from_pixbuf(GetOTRAvatar()); + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + gfx::Image avatar_image = + rb.GetNativeImageNamed(IDR_OTR_ICON, ui::ResourceBundle::RTL_ENABLED); + avatar_ = gtk_image_new_from_pixbuf(avatar_image.ToGdkPixbuf()); gtk_misc_set_alignment(GTK_MISC(avatar_), 0.0, 1.0); gtk_widget_set_size_request(avatar_, -1, 0); } else { - // Is using multi-profile avatar. + // Use a clickable avatar. avatar_ = avatar_button_->widget(); } } @@ -827,23 +813,32 @@ void BrowserTitlebar::UpdateAvatar() { if (IsOffTheRecord()) return; - ProfileInfoCache& cache = - g_browser_process->profile_manager()->GetProfileInfoCache(); - Profile* profile = browser_window_->browser()->profile(); - size_t index = cache.GetIndexOfProfileWithPath(profile->GetPath()); - if (index != std::string::npos) { - bool is_gaia_picture = + bool is_gaia_picture = false; + gfx::Image avatar; + if (ManagedMode::IsInManagedMode()) { + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + avatar = rb.GetNativeImageNamed(IDR_MANAGED_MODE_AVATAR, + ui::ResourceBundle::RTL_ENABLED); + } else { + ProfileInfoCache& cache = + g_browser_process->profile_manager()->GetProfileInfoCache(); + Profile* profile = browser_window_->browser()->profile(); + size_t index = cache.GetIndexOfProfileWithPath(profile->GetPath()); + if (index == std::string::npos) + return; + + is_gaia_picture = cache.IsUsingGAIAPictureOfProfileAtIndex(index) && cache.GetGAIAPictureOfProfileAtIndex(index); - avatar_button_->SetIcon( - cache.GetAvatarIconOfProfileAtIndex(index), is_gaia_picture); - - BubbleGtk::ArrowLocationGtk arrow_location = - display_avatar_on_left_ ^ base::i18n::IsRTL() ? - BubbleGtk::ARROW_LOCATION_TOP_LEFT : - BubbleGtk::ARROW_LOCATION_TOP_RIGHT; - avatar_button_->set_menu_arrow_location(arrow_location); + avatar = cache.GetAvatarIconOfProfileAtIndex(index); } + avatar_button_->SetIcon(avatar, is_gaia_picture); + + BubbleGtk::ArrowLocationGtk arrow_location = + display_avatar_on_left_ ^ base::i18n::IsRTL() ? + BubbleGtk::ARROW_LOCATION_TOP_LEFT : + BubbleGtk::ARROW_LOCATION_TOP_RIGHT; + avatar_button_->set_menu_arrow_location(arrow_location); } void BrowserTitlebar::ShowFaviconMenu(GdkEventButton* event) { @@ -1093,8 +1088,13 @@ void BrowserTitlebar::ActiveWindowChanged(GdkWindow* active_window) { } bool BrowserTitlebar::ShouldDisplayAvatar() { - return (IsOffTheRecord() || HasMultipleProfiles()) && - browser_window_->browser()->is_type_tabbed(); + if (IsOffTheRecord() || ManagedMode::IsInManagedMode()) + return true; + + if (!browser_window_->browser()->is_type_tabbed()) + return false; + + return AvatarMenuModel::ShouldShowAvatarMenu(); } bool BrowserTitlebar::IsOffTheRecord() { diff --git a/chrome/browser/ui/views/avatar_menu_button.cc b/chrome/browser/ui/views/avatar_menu_button.cc index 6ef2401..532f795 100644 --- a/chrome/browser/ui/views/avatar_menu_button.cc +++ b/chrome/browser/ui/views/avatar_menu_button.cc @@ -4,12 +4,20 @@ #include "chrome/browser/ui/views/avatar_menu_button.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/command_updater.h" +#include "chrome/browser/managed_mode.h" +#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/avatar_menu_model.h" #include "chrome/browser/profiles/profile_info_util.h" #include "chrome/browser/profiles/profile_metrics.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/views/avatar_menu_bubble_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/pref_names.h" +#include "content/public/browser/notification_service.h" #include "ui/gfx/canvas.h" #include "ui/views/widget/widget.h" @@ -36,10 +44,7 @@ void DrawTaskBarDecoration(gfx::NativeWindow window, const gfx::Image* image) { #if defined(OS_WIN) && !defined(USE_AURA) if (base::win::GetVersion() < base::win::VERSION_WIN7) return; - // Don't badge the task bar in the single profile case to match the behavior - // of the title bar. - if (!AvatarMenuModel::ShouldShowAvatarMenu()) - return; + // SetOverlayIcon does nothing if the window is not visible so testing // here avoids all the wasted effort of the image resizing. if (!::IsWindowVisible(window)) @@ -83,10 +88,10 @@ void DrawTaskBarDecoration(gfx::NativeWindow window, const gfx::Image* image) { #endif } -AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu) +AvatarMenuButton::AvatarMenuButton(Browser* browser, bool incognito) : MenuButton(NULL, string16(), this, false), browser_(browser), - has_menu_(has_menu), + incognito_(incognito), is_gaia_picture_(false), old_height_(0) { // In RTL mode, the avatar icon should be looking the opposite direction. @@ -128,7 +133,7 @@ void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) { } bool AvatarMenuButton::HitTest(const gfx::Point& point) const { - if (!has_menu_) + if (incognito_) return false; return views::MenuButton::HitTest(point); } @@ -144,12 +149,17 @@ void AvatarMenuButton::SetAvatarIcon(const gfx::Image& icon, // views::MenuButtonListener implementation void AvatarMenuButton::OnMenuButtonClicked(views::View* source, const gfx::Point& point) { - ShowAvatarBubble(); + if (incognito_) + return; + + if (ManagedMode::IsInManagedMode()) + ManagedMode::LeaveManagedMode(); + else + ShowAvatarBubble(); } void AvatarMenuButton::ShowAvatarBubble() { - if (!has_menu_) - return; + DCHECK(browser_->command_updater()->IsCommandEnabled(IDC_SHOW_AVATAR_MENU)); gfx::Point origin; views::View::ConvertPointToScreen(this, &origin); diff --git a/chrome/browser/ui/views/avatar_menu_button.h b/chrome/browser/ui/views/avatar_menu_button.h index 6edc79a..dbd8ffe 100644 --- a/chrome/browser/ui/views/avatar_menu_button.h +++ b/chrome/browser/ui/views/avatar_menu_button.h @@ -32,9 +32,9 @@ void DrawTaskBarDecoration(gfx::NativeWindow window, const gfx::Image* image); class AvatarMenuButton : public views::MenuButton, public views::MenuButtonListener { public: - // Creates a new button. If |has_menu| is true then clicking on the button - // will cause the profile menu to be displayed. - AvatarMenuButton(Browser* browser, bool has_menu); + // Creates a new button. If |incognito| is true and we're not in managed mode, + // clicking on the button will cause the profile menu to be displayed. + AvatarMenuButton(Browser* browser, bool incognito); virtual ~AvatarMenuButton(); @@ -52,8 +52,10 @@ class AvatarMenuButton : public views::MenuButton, virtual void OnMenuButtonClicked(views::View* source, const gfx::Point& point) OVERRIDE; + void ButtonClicked(); + Browser* browser_; - bool has_menu_; + bool incognito_; scoped_ptr<ui::MenuModel> menu_model_; // Use a scoped ptr because gfx::Image doesn't have a default constructor. diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc index bc52d45..2942426 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc @@ -1,15 +1,19 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/managed_mode.h" +#include "chrome/browser/profiles/avatar_menu_model.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/views/avatar_menu_button.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "grit/theme_resources.h" +#include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image.h" BrowserNonClientFrameView::BrowserNonClientFrameView(BrowserFrame* frame, @@ -24,8 +28,9 @@ BrowserNonClientFrameView::~BrowserNonClientFrameView() { void BrowserNonClientFrameView::UpdateAvatarInfo() { if (browser_view_->ShouldShowAvatar()) { if (!avatar_button_.get()) { - avatar_button_.reset(new AvatarMenuButton( - browser_view_->browser(), !browser_view_->IsOffTheRecord())); + avatar_button_.reset( + new AvatarMenuButton(browser_view_->browser(), + browser_view_->IsOffTheRecord())); AddChildView(avatar_button_.get()); frame_->GetRootView()->Layout(); } @@ -35,39 +40,46 @@ void BrowserNonClientFrameView::UpdateAvatarInfo() { frame_->GetRootView()->Layout(); } - // For popups and panels which don't have the avatar button, we still - // need to draw the taskbar decoration. - if (browser_view_->IsBrowserTypeNormal()) { - if (!avatar_button_.get()) - return; - } - + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + gfx::Image avatar; + string16 text; + bool is_gaia_picture = false; if (browser_view_->IsGuestSession()) { - const gfx::Image avatar(new SkBitmap(browser_view_->GetGuestAvatarIcon())); - if (avatar_button_.get()) - avatar_button_->SetAvatarIcon(avatar, false); - DrawTaskBarDecoration(frame_->GetNativeWindow(), &avatar); +#if defined(OS_CHROMEOS) + avatar = rb.GetImageNamed(IDR_GUEST_ICON); +#else + NOTREACHED(); +#endif } else if (browser_view_->IsOffTheRecord()) { - const gfx::Image avatar(new SkBitmap(browser_view_->GetOTRAvatarIcon())); - if (avatar_button_.get()) - avatar_button_->SetAvatarIcon(avatar, false); - DrawTaskBarDecoration(frame_->GetNativeWindow(), &avatar); - } else { + avatar = rb.GetImageNamed(IDR_OTR_ICON); + } else if (ManagedMode::IsInManagedMode()) { + avatar = rb.GetImageNamed(IDR_MANAGED_MODE_AVATAR); + } else if (AvatarMenuModel::ShouldShowAvatarMenu()) { ProfileInfoCache& cache = g_browser_process->profile_manager()->GetProfileInfoCache(); Profile* profile = browser_view_->browser()->profile(); size_t index = cache.GetIndexOfProfileWithPath(profile->GetPath()); - if (index != std::string::npos) { - bool is_gaia_picture = - cache.IsUsingGAIAPictureOfProfileAtIndex(index) && - cache.GetGAIAPictureOfProfileAtIndex(index); - const gfx::Image& avatar = cache.GetAvatarIconOfProfileAtIndex(index); - if (avatar_button_.get()) { - avatar_button_->SetAvatarIcon(avatar, is_gaia_picture); - avatar_button_->SetText(cache.GetNameOfProfileAtIndex(index)); - } - DrawTaskBarDecoration(frame_->GetNativeWindow(), &avatar); - } + if (index == std::string::npos) + return; + is_gaia_picture = + cache.IsUsingGAIAPictureOfProfileAtIndex(index) && + cache.GetGAIAPictureOfProfileAtIndex(index); + avatar = cache.GetAvatarIconOfProfileAtIndex(index); + text = cache.GetNameOfProfileAtIndex(index); + } + if (avatar_button_.get()) { + avatar_button_->SetAvatarIcon(avatar, is_gaia_picture); + if (!text.empty()) + avatar_button_->SetText(text); + } + + // For popups and panels which don't have the avatar button, we still + // need to draw the taskbar decoration. + if (AvatarMenuModel::ShouldShowAvatarMenu() || + ManagedMode::IsInManagedMode()) { + DrawTaskBarDecoration(frame_->GetNativeWindow(), &avatar); + } else { + DrawTaskBarDecoration(frame_->GetNativeWindow(), NULL); } } diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 16cda18..5bbca22 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -24,6 +24,7 @@ #include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/native_window_notification_source.h" #include "chrome/browser/ntp_background_util.h" +#include "chrome/browser/managed_mode.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/avatar_menu_model.h" #include "chrome/browser/profiles/profile.h" @@ -467,6 +468,8 @@ bool BrowserView::ShouldShowAvatar() const { return false; if (IsOffTheRecord()) return true; + if (ManagedMode::IsInManagedMode()) + return true; ProfileInfoCache& cache = g_browser_process->profile_manager()->GetProfileInfoCache(); @@ -549,28 +552,10 @@ TabContentsWrapper* BrowserView::GetSelectedTabContentsWrapper() const { } SkBitmap BrowserView::GetOTRAvatarIcon() const { - static SkBitmap* otr_avatar_ = new SkBitmap(); - - if (otr_avatar_->isNull()) { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - *otr_avatar_ = *rb.GetBitmapNamed(IDR_OTR_ICON); - } - return *otr_avatar_; -} - -SkBitmap BrowserView::GetGuestAvatarIcon() const { -#if defined(OS_CHROMEOS) - static SkBitmap* guest_avatar_ = new SkBitmap(); - - if (guest_avatar_->isNull()) { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - *guest_avatar_ = *rb.GetBitmapNamed(IDR_GUEST_ICON); - } - return *guest_avatar_; -#else - NOTREACHED(); - return SkBitmap(); -#endif + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + const SkBitmap* otr_avatar = + rb.GetNativeImageNamed(IDR_OTR_ICON).ToSkBitmap(); + return *otr_avatar; } // static diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index a8b574a..e634c89 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -182,9 +182,6 @@ class BrowserView : public BrowserWindow, // Retrieves the icon to use in the frame to indicate an OTR window. SkBitmap GetOTRAvatarIcon() const; - // Retrieves the icon to use in the frame to indicate guest session. - SkBitmap GetGuestAvatarIcon() const; - // Returns true if the Browser object associated with this BrowserView is a // tabbed-type window (i.e. a browser window, not an app or popup). bool IsBrowserTypeNormal() const { diff --git a/chrome/browser/ui/webui/ntp/ntp_login_handler.cc b/chrome/browser/ui/webui/ntp/ntp_login_handler.cc index ec17dc2b..9c51c9d 100644 --- a/chrome/browser/ui/webui/ntp/ntp_login_handler.cc +++ b/chrome/browser/ui/webui/ntp/ntp_login_handler.cc @@ -11,7 +11,9 @@ #include "base/metrics/histogram.h" #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/managed_mode.h" #include "chrome/browser/prefs/pref_notifier.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" @@ -137,7 +139,9 @@ void NTPLoginHandler::HandleShowSyncLoginUI(const ListValue* args) { RecordInHistogram(NTP_SIGN_IN_PROMO_CLICKED); } #endif - } else if (args->GetSize() == 4) { + } else if (args->GetSize() == 4 && + browser->command_updater()->IsCommandEnabled( + IDC_SHOW_AVATAR_MENU)) { // The user is signed in, show the profiles menu. double x = 0; double y = 0; |