1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_CHOOSER_VIEW_H_ 6 #define CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_CHOOSER_VIEW_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "chrome/browser/profiles/avatar_menu.h" 12 #include "chrome/browser/profiles/avatar_menu_observer.h" 13 #include "chrome/browser/profiles/profile_metrics.h" 14 #include "chrome/browser/ui/browser_window.h" 15 #include "chrome/browser/ui/profile_chooser_constants.h" 16 #include "google_apis/gaia/oauth2_token_service.h" 17 #include "ui/views/bubble/bubble_delegate.h" 18 #include "ui/views/controls/button/button.h" 19 #include "ui/views/controls/link_listener.h" 20 #include "ui/views/controls/styled_label_listener.h" 21 #include "ui/views/controls/textfield/textfield_controller.h" 22 23 class EditableProfilePhoto; 24 class EditableProfileName; 25 26 namespace gfx { 27 class Image; 28 } 29 30 namespace views { 31 class GridLayout; 32 class ImageButton; 33 class Link; 34 class LabelButton; 35 } 36 37 class Browser; 38 39 // This bubble view is displayed when the user clicks on the avatar button. 40 // It displays a list of profiles and allows users to switch between profiles. 41 class ProfileChooserView : public views::BubbleDelegateView, 42 public views::ButtonListener, 43 public views::LinkListener, 44 public views::StyledLabelListener, 45 public views::TextfieldController, 46 public AvatarMenuObserver, 47 public OAuth2TokenService::Observer { 48 public: 49 // Shows the bubble if one is not already showing. This allows us to easily 50 // make a button toggle the bubble on and off when clicked: we unconditionally 51 // call this function when the button is clicked and if the bubble isn't 52 // showing it will appear while if it is showing, nothing will happen here and 53 // the existing bubble will auto-close due to focus loss. 54 static void ShowBubble( 55 profiles::BubbleViewMode view_mode, 56 profiles::TutorialMode tutorial_mode, 57 const signin::ManageAccountsParams& manage_accounts_params, 58 views::View* anchor_view, 59 views::BubbleBorder::Arrow arrow, 60 views::BubbleBorder::BubbleAlignment border_alignment, 61 Browser* browser); 62 static bool IsShowing(); 63 static void Hide(); 64 65 // We normally close the bubble any time it becomes inactive but this can lead 66 // to flaky tests where unexpected UI events are triggering this behavior. 67 // Tests should call this with "false" for more consistent operation. clear_close_on_deactivate_for_testing()68 static void clear_close_on_deactivate_for_testing() { 69 close_on_deactivate_for_testing_ = false; 70 } 71 72 private: 73 friend class NewAvatarMenuButtonTest; 74 FRIEND_TEST_ALL_PREFIXES(NewAvatarMenuButtonTest, SignOut); 75 76 typedef std::vector<size_t> Indexes; 77 typedef std::map<views::Button*, int> ButtonIndexes; 78 typedef std::map<views::Button*, std::string> AccountButtonIndexes; 79 80 ProfileChooserView(views::View* anchor_view, 81 views::BubbleBorder::Arrow arrow, 82 Browser* browser, 83 profiles::BubbleViewMode view_mode, 84 profiles::TutorialMode tutorial_mode, 85 signin::GAIAServiceType service_type); 86 virtual ~ProfileChooserView(); 87 88 // views::BubbleDelegateView: 89 virtual void Init() OVERRIDE; 90 virtual void WindowClosing() OVERRIDE; 91 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; 92 93 // views::ButtonListener: 94 virtual void ButtonPressed(views::Button* sender, 95 const ui::Event& event) OVERRIDE; 96 97 // views::LinkListener: 98 virtual void LinkClicked(views::Link* sender, int event_flags) OVERRIDE; 99 100 // views::StyledLabelListener: 101 virtual void StyledLabelLinkClicked( 102 const gfx::Range& range, int event_flags) OVERRIDE; 103 104 // views::TextfieldController: 105 virtual bool HandleKeyEvent(views::Textfield* sender, 106 const ui::KeyEvent& key_event) OVERRIDE; 107 108 // AvatarMenuObserver: 109 virtual void OnAvatarMenuChanged(AvatarMenu* avatar_menu) OVERRIDE; 110 111 // OAuth2TokenService::Observer overrides. 112 virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE; 113 virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE; 114 115 static ProfileChooserView* profile_bubble_; 116 static bool close_on_deactivate_for_testing_; 117 118 void ResetView(); 119 120 // Shows the bubble with the |view_to_display|. 121 void ShowView(profiles::BubbleViewMode view_to_display, 122 AvatarMenu* avatar_menu); 123 124 // Creates the profile chooser view. 125 views::View* CreateProfileChooserView(AvatarMenu* avatar_menu); 126 127 // Creates the main profile card for the profile |avatar_item|. |is_guest| 128 // is used to determine whether to show any Sign in/Sign out/Manage accounts 129 // links. 130 views::View* CreateCurrentProfileView( 131 const AvatarMenu::Item& avatar_item, 132 bool is_guest); 133 views::View* CreateGuestProfileView(); 134 views::View* CreateOtherProfilesView(const Indexes& avatars_to_show); 135 views::View* CreateOptionsView(bool display_lock); 136 views::View* CreateSupervisedUserDisclaimerView(); 137 138 // Account Management view for the profile |avatar_item|. 139 views::View* CreateCurrentProfileAccountsView( 140 const AvatarMenu::Item& avatar_item); 141 void CreateAccountButton(views::GridLayout* layout, 142 const std::string& account_id, 143 bool is_primary_account, 144 bool reauth_required, 145 int width); 146 147 // Creates a webview showing the gaia signin page. 148 views::View* CreateGaiaSigninView(); 149 150 // Creates a view to confirm account removal for |account_id_to_remove_|. 151 views::View* CreateAccountRemovalView(); 152 153 // Removes the currently selected account and attempts to restart Chrome. 154 void RemoveAccount(); 155 156 // Close the tutorial card. 157 void DismissTutorial(); 158 159 // Creates a tutorial card to introduce an upgrade user to the new avatar 160 // menu if needed. |tutorial_shown| indicates if the tutorial has already been 161 // shown in the previous active view. |avatar_item| refers to the current 162 // profile. 163 views::View* CreateWelcomeUpgradeTutorialViewIfNeeded( 164 bool tutorial_shown, const AvatarMenu::Item& avatar_item); 165 166 // Creates a tutorial card to have the user confirm the last Chrome signin, 167 // Chrome sync will be delayed until the user either dismisses the tutorial, 168 // or configures sync through the "Settings" link. 169 views::View* CreateSigninConfirmationView(); 170 171 // Creates a a tutorial card to show the errors in the last Chrome signin. 172 views::View* CreateSigninErrorView(); 173 174 // Creates a tutorial card. If |stack_button| is true, places the button above 175 // the link otherwise places both on the same row with the link left aligned 176 // and button right aligned. The method sets |link| to point to the newly 177 // create link, |button| to the newly created button, and |tutorial_mode_| to 178 // the given |tutorial_mode|. 179 views::View* CreateTutorialView( 180 profiles::TutorialMode tutorial_mode, 181 const base::string16& title_text, 182 const base::string16& content_text, 183 const base::string16& link_text, 184 const base::string16& button_text, 185 bool stack_button, 186 views::Link** link, 187 views::LabelButton** button, 188 views::ImageButton** close_button); 189 190 // Create a view that shows various options for an upgrade user who is not 191 // the same person as the currently signed in user. 192 views::View* CreateSwitchUserView(); 193 194 bool ShouldShowGoIncognito() const; 195 196 // Clean-up done after an action was performed in the ProfileChooser. 197 void PostActionPerformed(ProfileMetrics::ProfileDesktopMenu action_performed); 198 199 scoped_ptr<AvatarMenu> avatar_menu_; 200 Browser* browser_; 201 202 // Other profiles used in the "fast profile switcher" view. 203 ButtonIndexes open_other_profile_indexes_map_; 204 205 // Buttons associated with the current profile. 206 AccountButtonIndexes delete_account_button_map_; 207 AccountButtonIndexes reauth_account_button_map_; 208 209 // Links and buttons displayed in the tutorial card. 210 views::LabelButton* tutorial_sync_settings_ok_button_; 211 views::Link* tutorial_sync_settings_link_; 212 views::LabelButton* tutorial_see_whats_new_button_; 213 views::Link* tutorial_not_you_link_; 214 views::Link* tutorial_learn_more_link_; 215 views::ImageButton* tutorial_close_button_; 216 217 // Links and buttons displayed in the active profile card. 218 views::Link* manage_accounts_link_; 219 views::LabelButton* signin_current_profile_link_; 220 views::LabelButton* auth_error_email_button_; 221 222 // The profile name and photo in the active profile card. Owned by the 223 // views hierarchy. 224 EditableProfilePhoto* current_profile_photo_; 225 EditableProfileName* current_profile_name_; 226 227 // Action buttons. 228 views::LabelButton* users_button_; 229 views::LabelButton* go_incognito_button_; 230 views::LabelButton* lock_button_; 231 views::Link* add_account_link_; 232 233 // Buttons displayed in the gaia signin view. 234 views::ImageButton* gaia_signin_cancel_button_; 235 236 // Links and buttons displayed in the account removal view. 237 views::LabelButton* remove_account_button_; 238 views::ImageButton* account_removal_cancel_button_; 239 240 // Buttons in the switch user view. 241 views::LabelButton* add_person_button_; 242 views::LabelButton* disconnect_button_; 243 views::ImageButton* switch_user_cancel_button_; 244 245 // Records the account id to remove. 246 std::string account_id_to_remove_; 247 248 // Active view mode. 249 profiles::BubbleViewMode view_mode_; 250 251 // The current tutorial mode. 252 profiles::TutorialMode tutorial_mode_; 253 254 // The GAIA service type provided in the response header. 255 signin::GAIAServiceType gaia_service_type_; 256 257 DISALLOW_COPY_AND_ASSIGN(ProfileChooserView); 258 }; 259 260 #endif // CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_CHOOSER_VIEW_H_ 261