Add right-click user switching tutorial bubble.
This design is based on this mock: https://drive.google.com/a/chromium.org/file/d/0B-DVbqI3huZGZGhIcTFtRWRTSTA/view?usp=sharing
BUG=458664
TEST=
1. Launch chrome and make sure there is more than one available profile.
2. Left-click on the Avatar Button.
3. A tutorial bubble should be displayed informing the user they can
right-click the button to see other users.
4. Close the bubble without dismissing the tutorial, for example by
clicking in the content area.
5. Reopening the Avatar Menu should still display the tutorial until it
is explicitly dismissed (clicking the X or the "Ok, got it!" button)
or until the user right clicks the button.
6. Once dismissed, the tutorial should never be shown again.
Review URL: https://codereview.chromium.org/1120013003
Cr-Commit-Position: refs/heads/master@{#330565}
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index d644471a..90621be 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -12045,6 +12045,12 @@
<message name="IDS_PROFILES_GUEST_PROFILE_NAME" desc="Name of the guest profile.">
Guest
</message>
+ <message name="IDS_PROFILES_RIGHT_CLICK_TUTORIAL_CONTENT_TEXT" desc="Content of the tutorial bubble informing users about right-click user switching.">
+ Right click on the button above to view other people.
+ </message>
+ <message name="IDS_PROFILES_RIGHT_CLICK_TUTORIAL_TITLE" desc="Title of the tutorial bubble informing users about right-click user switching.">
+ Switch people faster
+ </message>
<message name="IDS_DEFAULT_PROFILE_NAME" desc="The default name given to a profile. Displayed in wrench menu and settings UI.">
First user
</message>
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index 73508b6..177bb3b 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -19,6 +19,7 @@
#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/signin_ui_util.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/ui/browser.h"
@@ -312,7 +313,7 @@
size_t min_profiles = profile->IsGuestSession() ? 1 : 2;
size_t number_of_profiles =
g_browser_process->profile_manager()->GetNumberOfProfiles();
- return number_of_profiles < min_profiles;
+ return number_of_profiles >= min_profiles;
}
void CreateAndSwitchToNewProfile(chrome::HostDesktopType desktop_type,
@@ -525,4 +526,26 @@
}
}
+bool ShouldShowWelcomeUpgradeTutorial(
+ Profile* profile, TutorialMode tutorial_mode) {
+ const int show_count = profile->GetPrefs()->GetInteger(
+ prefs::kProfileAvatarTutorialShown);
+ // Do not show the tutorial if user has dismissed it.
+ if (show_count > signin_ui_util::kUpgradeWelcomeTutorialShowMax)
+ return false;
+
+ return tutorial_mode == TUTORIAL_MODE_WELCOME_UPGRADE ||
+ show_count != signin_ui_util::kUpgradeWelcomeTutorialShowMax;
+}
+
+bool ShouldShowRightClickTutorial(Profile* profile) {
+ PrefService* local_state = g_browser_process->local_state();
+ const bool dismissed = local_state->GetBoolean(
+ prefs::kProfileAvatarRightClickTutorialDismissed);
+
+ // Don't show the tutorial if it's already been dismissed or if right-clicking
+ // wouldn't show any targets.
+ return !dismissed && HasProfileSwitchTargets(profile);
+}
+
} // namespace profiles
diff --git a/chrome/browser/profiles/profile_window.h b/chrome/browser/profiles/profile_window.h
index 4f030034..8f8a43a 100644
--- a/chrome/browser/profiles/profile_window.h
+++ b/chrome/browser/profiles/profile_window.h
@@ -123,6 +123,15 @@
BubbleViewMode* bubble_view_mode,
TutorialMode* tutorial_mode);
+// Returns true if the Welcome/Upgrade tutorial bubble should be shown to the
+// user, false otherwise.
+bool ShouldShowWelcomeUpgradeTutorial(
+ Profile* profile, TutorialMode tutorial_mode);
+
+// Returns true if the tutorial informing the user about right-click user
+// switching should be shown, false otherwise.
+bool ShouldShowRightClickTutorial(Profile* profile);
+
} // namespace profiles
#endif // CHROME_BROWSER_PROFILES_PROFILE_WINDOW_H_
diff --git a/chrome/browser/profiles/profiles_state.cc b/chrome/browser/profiles/profiles_state.cc
index f0b3ac3c..b819c3f 100644
--- a/chrome/browser/profiles/profiles_state.cc
+++ b/chrome/browser/profiles/profiles_state.cc
@@ -53,6 +53,9 @@
// Preferences about the user manager.
registry->RegisterBooleanPref(prefs::kBrowserGuestModeEnabled, true);
registry->RegisterBooleanPref(prefs::kBrowserAddPersonEnabled, true);
+
+ registry->RegisterBooleanPref(
+ prefs::kProfileAvatarRightClickTutorialDismissed, false);
}
base::string16 GetAvatarNameForProfile(const base::FilePath& profile_path) {
diff --git a/chrome/browser/profiles/profiles_state.h b/chrome/browser/profiles/profiles_state.h
index 322a29a0..3b25c2c4 100644
--- a/chrome/browser/profiles/profiles_state.h
+++ b/chrome/browser/profiles/profiles_state.h
@@ -92,6 +92,13 @@
// a BrowsingDataRemover to delete all the Profile's data.
void RemoveBrowsingDataForProfile(const base::FilePath& profile_path);
+// Marks the right-click user switching tutorial dismissed state as |dismissed|.
+void SetFastUserSwitchingTutorialDismissedState(bool dismissed);
+
+// Returns true if the right-click user switching tutorial was previously
+// dismissed by a user, false otherwise.
+bool GetFastUserSwitchingTutorialDismissedState();
+
} // namespace profiles
#endif // CHROME_BROWSER_PROFILES_PROFILES_STATE_H_
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
index a3a598bc..67c421c5 100644
--- a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
+++ b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
@@ -192,7 +192,7 @@
// It has to happen here to prevent the view system from creating an empty
// container.
if (viewMode == profiles::BUBBLE_VIEW_MODE_FAST_PROFILE_CHOOSER &&
- profiles::HasProfileSwitchTargets(browser_->profile())) {
+ !profiles::HasProfileSwitchTargets(browser_->profile())) {
return;
}
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h
index f6374afa..684d92e5 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h
+++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h
@@ -131,6 +131,7 @@
viewMode:(profiles::BubbleViewMode)viewMode
tutorialMode:(profiles::TutorialMode)tutorialMode
serviceType:(signin::GAIAServiceType)GAIAServiceType;
+- (IBAction)dismissTutorial:(id)sender;
@end
#endif // CHROME_BROWSER_UI_COCOA_PROFILES_PROFILE_CHOOSER_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
index 016224a..0754849 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
+++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -878,6 +878,8 @@
// Builds the profile chooser view.
- (NSView*)buildProfileChooserView;
+- (NSView*)buildTutorialViewIfNeededForItem:(const AvatarMenu::Item&)item;
+
// Builds a tutorial card with a title label using |titleMessage|, a content
// label using |contentMessage|, a link using |linkMessage|, and a button using
// |buttonMessage|. If |stackButton| is YES, places the button above the link.
@@ -897,7 +899,11 @@
// Builds a tutorial card to introduce an upgrade user to the new avatar menu if
// needed. |tutorial_shown| indicates if the tutorial has already been shown in
// the previous active view. |avatar_item| refers to the current profile.
-- (NSView*)buildWelcomeUpgradeTutorialViewIfNeeded;
+- (NSView*)buildWelcomeUpgradeTutorialView:(const AvatarMenu::Item&)item;
+
+// Builds a tutorial card to inform the user about right-click user switching if
+// needed.
+- (NSView*)buildRightClickTutorialView;
// Builds a tutorial card to have the user confirm the last Chrome signin,
// Chrome sync will be delayed until the user either dismisses the tutorial, or
@@ -1129,6 +1135,12 @@
signin_ui_util::kUpgradeWelcomeTutorialShowMax + 1);
}
+ if(tutorialMode_ == profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING) {
+ PrefService* localState = g_browser_process->local_state();
+ localState->SetBoolean(
+ prefs::kProfileAvatarRightClickTutorialDismissed, true);
+ }
+
tutorialMode_ = profiles::TUTORIAL_MODE_NONE;
[self initMenuContentsWithView:profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER];
}
@@ -1270,6 +1282,12 @@
bool displayLock = false;
bool isFastProfileChooser =
viewMode_ == profiles::BUBBLE_VIEW_MODE_FAST_PROFILE_CHOOSER;
+ if (isFastProfileChooser) {
+ // The user is using right-click switching, no need to tell them about it.
+ PrefService* localState = g_browser_process->local_state();
+ localState->SetBoolean(
+ prefs::kProfileAvatarRightClickTutorialDismissed, true);
+ }
// Loop over the profiles in reverse, so that they are sorted by their
// y-coordinate, and separate them into active and "other" profiles.
@@ -1277,18 +1295,7 @@
const AvatarMenu::Item& item = avatarMenu_->GetItemAt(i);
if (item.active) {
if (viewMode_ == profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER) {
- switch (tutorialMode_) {
- case profiles::TUTORIAL_MODE_NONE:
- case profiles::TUTORIAL_MODE_WELCOME_UPGRADE:
- tutorialView =
- [self buildWelcomeUpgradeTutorialViewIfNeeded];
- break;
- case profiles::TUTORIAL_MODE_CONFIRM_SIGNIN:
- tutorialView = [self buildSigninConfirmationView];
- break;
- case profiles::TUTORIAL_MODE_SHOW_ERROR:
- tutorialView = [self buildSigninErrorView];
- }
+ tutorialView = [self buildTutorialViewIfNeededForItem:item];
}
currentProfileView = [self createCurrentProfileView:item];
displayLock = item.signed_in &&
@@ -1425,24 +1432,7 @@
buttonAction:nil];
}
-- (NSView*)buildWelcomeUpgradeTutorialViewIfNeeded {
- Profile* profile = browser_->profile();
- const AvatarMenu::Item& avatarItem =
- avatarMenu_->GetItemAt(avatarMenu_->GetActiveProfileIndex());
-
- const int showCount = profile->GetPrefs()->GetInteger(
- prefs::kProfileAvatarTutorialShown);
- // Do not show the tutorial if user has dismissed it.
- if (showCount > signin_ui_util::kUpgradeWelcomeTutorialShowMax)
- return nil;
-
- if (tutorialMode_ != profiles::TUTORIAL_MODE_WELCOME_UPGRADE) {
- if (showCount == signin_ui_util::kUpgradeWelcomeTutorialShowMax)
- return nil;
- profile->GetPrefs()->SetInteger(
- prefs::kProfileAvatarTutorialShown, showCount + 1);
- }
-
+- (NSView*)buildWelcomeUpgradeTutorialView:(const AvatarMenu::Item&)item {
ProfileMetrics::LogProfileNewAvatarMenuUpgrade(
ProfileMetrics::PROFILE_AVATAR_MENU_UPGRADE_VIEW);
@@ -1451,9 +1441,9 @@
NSString* contentMessage = l10n_util::GetNSString(
IDS_PROFILES_WELCOME_UPGRADE_TUTORIAL_CONTENT_TEXT);
// For local profiles, the "Not you" link doesn't make sense.
- NSString* linkMessage = avatarItem.signed_in ?
+ NSString* linkMessage = item.signed_in ?
ElideMessage(
- l10n_util::GetStringFUTF16(IDS_PROFILES_NOT_YOU, avatarItem.name),
+ l10n_util::GetStringFUTF16(IDS_PROFILES_NOT_YOU, item.name),
kFixedMenuWidth - 2 * kHorizontalSpacing) :
nil;
NSString* buttonMessage = l10n_util::GetNSString(
@@ -1469,6 +1459,52 @@
buttonAction:@selector(seeWhatsNew:)];
}
+- (NSView*)buildRightClickTutorialView {
+ NSString* titleMessage = l10n_util::GetNSString(
+ IDS_PROFILES_RIGHT_CLICK_TUTORIAL_TITLE);
+ NSString* contentMessage = l10n_util::GetNSString(
+ IDS_PROFILES_RIGHT_CLICK_TUTORIAL_CONTENT_TEXT);
+ NSString* buttonMessage = l10n_util::GetNSString(
+ IDS_PROFILES_TUTORIAL_OK_BUTTON);
+
+ return
+ [self tutorialViewWithMode:profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING
+ titleMessage:titleMessage
+ contentMessage:contentMessage
+ linkMessage:nil
+ buttonMessage:buttonMessage
+ stackButton:NO
+ hasCloseButton:NO
+ linkAction:nil
+ buttonAction:@selector(dismissTutorial:)];
+}
+
+- (NSView*)buildTutorialViewIfNeededForItem:(const AvatarMenu::Item&)item {
+ if (tutorialMode_ == profiles::TUTORIAL_MODE_CONFIRM_SIGNIN)
+ return [self buildSigninConfirmationView];
+
+ if (tutorialMode_ == profiles::TUTORIAL_MODE_SHOW_ERROR)
+ return [self buildSigninErrorView];
+
+ if (profiles::ShouldShowWelcomeUpgradeTutorial(
+ browser_->profile(), tutorialMode_)) {
+ if (tutorialMode_ != profiles::TUTORIAL_MODE_WELCOME_UPGRADE) {
+ Profile* profile = browser_->profile();
+ const int showCount = profile->GetPrefs()->GetInteger(
+ prefs::kProfileAvatarTutorialShown);
+ profile->GetPrefs()->SetInteger(
+ prefs::kProfileAvatarTutorialShown, showCount + 1);
+ }
+
+ return [self buildWelcomeUpgradeTutorialView:item];
+ }
+
+ if (profiles::ShouldShowRightClickTutorial(browser_->profile()))
+ return [self buildRightClickTutorialView];
+
+ return nil;
+}
+
- (NSView*)tutorialViewWithMode:(profiles::TutorialMode)mode
titleMessage:(NSString*)titleMessage
contentMessage:(NSString*)contentMessage
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller_unittest.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller_unittest.mm
index 13515fb..66ecfd50 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller_unittest.mm
@@ -80,17 +80,49 @@
}
void StartProfileChooserController() {
+ StartProfileChooserControllerWithTutorialMode(profiles::TUTORIAL_MODE_NONE);
+ }
+
+ void StartProfileChooserControllerWithTutorialMode(
+ profiles::TutorialMode mode) {
NSRect frame = [test_window() frame];
NSPoint point = NSMakePoint(NSMidX(frame), NSMidY(frame));
controller_.reset([[ProfileChooserController alloc]
initWithBrowser:browser()
anchoredAt:point
viewMode:profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER
- tutorialMode:profiles::TUTORIAL_MODE_NONE
+ tutorialMode:mode
serviceType:signin::GAIA_SERVICE_TYPE_NONE]);
[controller_ showWindow:nil];
}
+ void AssertRightClickTutorialShown() {
+ NSArray* subviews = [[[controller() window] contentView] subviews];
+ ASSERT_EQ(2U, [subviews count]);
+ subviews = [[subviews objectAtIndex:0] subviews];
+
+ // There should be 4 views: the tutorial, the active profile card, a
+ // separator and the options view.
+ ASSERT_EQ(4U, [subviews count]);
+
+ // The tutorial is the topmost view, so the last in the array. It should
+ // contain 3 views: the title, the content text and the OK button.
+ NSArray* tutorialSubviews = [[subviews objectAtIndex:3] subviews];
+ ASSERT_EQ(3U, [tutorialSubviews count]);
+
+ NSTextField* tutorialTitle = base::mac::ObjCCastStrict<NSTextField>(
+ [tutorialSubviews objectAtIndex:2]);
+ EXPECT_GT([[tutorialTitle stringValue] length], 0U);
+
+ NSTextField* tutorialContent = base::mac::ObjCCastStrict<NSTextField>(
+ [tutorialSubviews objectAtIndex:1]);
+ EXPECT_GT([[tutorialContent stringValue] length], 0U);
+
+ NSButton* tutorialOKButton = base::mac::ObjCCastStrict<NSButton>(
+ [tutorialSubviews objectAtIndex:0]);
+ EXPECT_GT([[tutorialOKButton title] length], 0U);
+ }
+
void EnableFastUserSwitching() {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kFastUserSwitching);
@@ -175,6 +207,69 @@
EXPECT_GT([[promo stringValue] length], 0U);
}
+TEST_F(ProfileChooserControllerTest, RightClickTutorialShownAfterWelcome) {
+ switches::EnableNewAvatarMenuForTesting(
+ base::CommandLine::ForCurrentProcess());
+ // The welcome upgrade tutorial takes precedence so show it then dismiss it.
+ // The right click tutorial should be shown right away.
+ StartProfileChooserControllerWithTutorialMode(
+ profiles::TUTORIAL_MODE_WELCOME_UPGRADE);
+
+ [controller() dismissTutorial:nil];
+ AssertRightClickTutorialShown();
+}
+
+TEST_F(ProfileChooserControllerTest, RightClickTutorialShownAfterReopen) {
+ switches::EnableNewAvatarMenuForTesting(
+ base::CommandLine::ForCurrentProcess());
+ // The welcome upgrade tutorial takes precedence so show it then close the
+ // menu. Reopening the menu should show the tutorial.
+ StartProfileChooserController();
+
+ [controller() close];
+ StartProfileChooserController();
+ AssertRightClickTutorialShown();
+
+ // The tutorial must be manually dismissed so it should still be shown after
+ // closing and reopening the menu,
+ [controller() close];
+ StartProfileChooserController();
+ AssertRightClickTutorialShown();
+}
+
+TEST_F(ProfileChooserControllerTest, RightClickTutorialNotShownAfterDismiss) {
+ switches::EnableNewAvatarMenuForTesting(
+ base::CommandLine::ForCurrentProcess());
+ // The welcome upgrade tutorial takes precedence so show it then close the
+ // menu. Reopening the menu should show the tutorial.
+ StartProfileChooserController();
+
+ [controller() close];
+ StartProfileChooserControllerWithTutorialMode(
+ profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING);
+ AssertRightClickTutorialShown();
+
+ // Dismissing the tutorial should prevent it from being shown forever.
+ [controller() dismissTutorial:nil];
+ NSArray* subviews = [[[controller() window] contentView] subviews];
+ ASSERT_EQ(2U, [subviews count]);
+ subviews = [[subviews objectAtIndex:0] subviews];
+
+ // There should be 3 views since there's no tutorial
+ ASSERT_EQ(3U, [subviews count]);
+
+ // Closing and reopening the menu shouldn't show the tutorial.
+ [controller() close];
+ StartProfileChooserControllerWithTutorialMode(
+ profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING);
+ subviews = [[[controller() window] contentView] subviews];
+ ASSERT_EQ(2U, [subviews count]);
+ subviews = [[subviews objectAtIndex:0] subviews];
+
+ // There should be 3 views since there's no tutorial
+ ASSERT_EQ(3U, [subviews count]);
+}
+
TEST_F(ProfileChooserControllerTest, InitialLayoutWithFastUserSwitcher) {
switches::EnableNewAvatarMenuForTesting(
base::CommandLine::ForCurrentProcess());
diff --git a/chrome/browser/ui/profile_chooser_constants.h b/chrome/browser/ui/profile_chooser_constants.h
index 1301be9b..73fdbb09 100644
--- a/chrome/browser/ui/profile_chooser_constants.h
+++ b/chrome/browser/ui/profile_chooser_constants.h
@@ -37,6 +37,8 @@
TUTORIAL_MODE_WELCOME_UPGRADE,
// A tutorial card shown to display the signin errors.
TUTORIAL_MODE_SHOW_ERROR,
+ // A tutorial card shown to inform users about right-click user switching.
+ TUTORIAL_MODE_RIGHT_CLICK_SWITCHING,
};
}; // namespace profiles
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index 880cccd..3b414d2 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -491,7 +491,7 @@
// It has to happen here to prevent the view system from creating an empty
// container.
if (view_mode == profiles::BUBBLE_VIEW_MODE_FAST_PROFILE_CHOOSER &&
- profiles::HasProfileSwitchTargets(browser->profile())) {
+ !profiles::HasProfileSwitchTargets(browser->profile())) {
return;
}
@@ -913,20 +913,7 @@
item.signed_in && profiles::IsLockAvailable(browser_->profile()));
current_profile_view = CreateCurrentProfileView(item, false);
if (IsProfileChooser(view_mode_)) {
- switch (tutorial_mode_) {
- case profiles::TUTORIAL_MODE_NONE:
- case profiles::TUTORIAL_MODE_WELCOME_UPGRADE:
- tutorial_view = CreateWelcomeUpgradeTutorialViewIfNeeded(
- tutorial_mode_ == profiles::TUTORIAL_MODE_WELCOME_UPGRADE,
- item);
- break;
- case profiles::TUTORIAL_MODE_CONFIRM_SIGNIN:
- tutorial_view = CreateSigninConfirmationView();
- break;
- case profiles::TUTORIAL_MODE_SHOW_ERROR:
- tutorial_view = CreateSigninErrorView();
- break;
- }
+ tutorial_view = CreateTutorialViewIfNeeded(item);
} else {
current_profile_accounts = CreateCurrentProfileAccountsView(item);
}
@@ -1003,10 +990,15 @@
views::View* view = new views::View();
views::GridLayout* layout = CreateSingleColumnLayout(view, kFixedMenuWidth);
- if (view_mode_ == profiles::BUBBLE_VIEW_MODE_FAST_PROFILE_CHOOSER)
+ if (view_mode_ == profiles::BUBBLE_VIEW_MODE_FAST_PROFILE_CHOOSER) {
PopulateMinimalProfileChooserView(layout, avatar_menu);
- else
+ // The user is using right-click switching, no need to tell them about it.
+ PrefService* local_state = g_browser_process->local_state();
+ local_state->SetBoolean(
+ prefs::kProfileAvatarRightClickTutorialDismissed, true);
+ } else {
PopulateCompleteProfileChooserView(layout, avatar_menu);
+ }
return view;
}
@@ -1019,10 +1011,43 @@
signin_ui_util::kUpgradeWelcomeTutorialShowMax + 1);
}
+ if (tutorial_mode_ == profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING) {
+ PrefService* local_state = g_browser_process->local_state();
+ local_state->SetBoolean(
+ prefs::kProfileAvatarRightClickTutorialDismissed, true);
+ }
+
tutorial_mode_ = profiles::TUTORIAL_MODE_NONE;
ShowView(profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER, avatar_menu_.get());
}
+views::View* ProfileChooserView::CreateTutorialViewIfNeeded(
+ const AvatarMenu::Item& item) {
+ if (tutorial_mode_ == profiles::TUTORIAL_MODE_CONFIRM_SIGNIN)
+ return CreateSigninConfirmationView();
+
+ if (tutorial_mode_ == profiles::TUTORIAL_MODE_SHOW_ERROR)
+ return CreateSigninErrorView();
+
+ if (profiles::ShouldShowWelcomeUpgradeTutorial(
+ browser_->profile(), tutorial_mode_)) {
+ if (tutorial_mode_ != profiles::TUTORIAL_MODE_WELCOME_UPGRADE) {
+ Profile* profile = browser_->profile();
+ const int show_count = profile->GetPrefs()->GetInteger(
+ prefs::kProfileAvatarTutorialShown);
+ profile->GetPrefs()->SetInteger(
+ prefs::kProfileAvatarTutorialShown, show_count + 1);
+ }
+
+ return CreateWelcomeUpgradeTutorialView(item);
+ }
+
+ if (profiles::ShouldShowRightClickTutorial(browser_->profile()))
+ return CreateRightClickTutorialView();
+
+ return nullptr;
+}
+
views::View* ProfileChooserView::CreateTutorialView(
profiles::TutorialMode tutorial_mode,
const base::string16& title_text,
@@ -1572,22 +1597,8 @@
kFixedAccountRemovalViewWidth);
}
-views::View* ProfileChooserView::CreateWelcomeUpgradeTutorialViewIfNeeded(
- bool tutorial_shown, const AvatarMenu::Item& avatar_item) {
- Profile* profile = browser_->profile();
-
- const int show_count = profile->GetPrefs()->GetInteger(
- prefs::kProfileAvatarTutorialShown);
- // Do not show the tutorial if user has dismissed it.
- if (show_count > signin_ui_util::kUpgradeWelcomeTutorialShowMax)
- return NULL;
-
- if (!tutorial_shown) {
- if (show_count == signin_ui_util::kUpgradeWelcomeTutorialShowMax)
- return NULL;
- profile->GetPrefs()->SetInteger(
- prefs::kProfileAvatarTutorialShown, show_count + 1);
- }
+views::View* ProfileChooserView::CreateWelcomeUpgradeTutorialView(
+ const AvatarMenu::Item& avatar_item) {
ProfileMetrics::LogProfileNewAvatarMenuUpgrade(
ProfileMetrics::PROFILE_AVATAR_MENU_UPGRADE_VIEW);
@@ -1643,6 +1654,19 @@
&tutorial_close_button_);
}
+views::View* ProfileChooserView::CreateRightClickTutorialView() {
+ return CreateTutorialView(
+ profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING,
+ l10n_util::GetStringUTF16(IDS_PROFILES_RIGHT_CLICK_TUTORIAL_TITLE),
+ l10n_util::GetStringUTF16(IDS_PROFILES_RIGHT_CLICK_TUTORIAL_CONTENT_TEXT),
+ base::string16(),
+ l10n_util::GetStringUTF16(IDS_PROFILES_TUTORIAL_OK_BUTTON),
+ false,
+ nullptr,
+ &tutorial_sync_settings_ok_button_,
+ nullptr);
+}
+
views::View* ProfileChooserView::CreateSwitchUserView() {
views::View* view = new views::View();
views::GridLayout* layout = CreateSingleColumnLayout(
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.h b/chrome/browser/ui/views/profiles/profile_chooser_view.h
index d9b5981..e3121c9f 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.h
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.h
@@ -167,20 +167,23 @@
void DismissTutorial();
// Creates a tutorial card to introduce an upgrade user to the new avatar
- // menu if needed. |tutorial_shown| indicates if the tutorial has already been
- // shown in the previous active view. |avatar_item| refers to the current
- // profile.
- views::View* CreateWelcomeUpgradeTutorialViewIfNeeded(
- bool tutorial_shown, const AvatarMenu::Item& avatar_item);
+ // menu. |avatar_item| refers to the current profile.
+ views::View* CreateWelcomeUpgradeTutorialView(
+ const AvatarMenu::Item& avatar_item);
// Creates a tutorial card to have the user confirm the last Chrome signin,
// Chrome sync will be delayed until the user either dismisses the tutorial,
// or configures sync through the "Settings" link.
views::View* CreateSigninConfirmationView();
- // Creates a a tutorial card to show the errors in the last Chrome signin.
+ // Creates a tutorial card to show the errors in the last Chrome signin.
views::View* CreateSigninErrorView();
+ // Creates a tutorial card telling the user about right-click user switching.
+ views::View* CreateRightClickTutorialView();
+
+ views::View* CreateTutorialViewIfNeeded(const AvatarMenu::Item& item);
+
// Creates a tutorial card. If |stack_button| is true, places the button above
// the link otherwise places both on the same row with the link left aligned
// and button right aligned. The method sets |link| to point to the newly
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 9ff1673..15a8f9a1 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1106,6 +1106,11 @@
const char kProfileAvatarTutorialShown[] =
"profile.avatar_bubble_tutorial_shown";
+// Boolean that specifies if the user has already dismissed the right-click user
+// switching tutorial.
+const char kProfileAvatarRightClickTutorialDismissed[] =
+ "profile.avatar_bubble_right_click_tutorial_dismissed";
+
// Indicates if we've already shown a notification that high contrast
// mode is on, recommending high-contrast extensions and themes.
const char kInvertNotificationShown[] = "invert_notification_version_2_shown";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index c0347342..b88ad1e 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -378,6 +378,7 @@
extern const char kProfileGAIAInfoPictureURL[];
extern const char kProfileAvatarTutorialShown[];
+extern const char kProfileAvatarRightClickTutorialDismissed[];
extern const char kInvertNotificationShown[];