1 // Copyright 2017 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 ASH_SHELF_LOGIN_SHELF_VIEW_H_ 6 #define ASH_SHELF_LOGIN_SHELF_VIEW_H_ 7 8 #include <memory> 9 #include <string> 10 #include <vector> 11 12 #include "ash/ash_export.h" 13 #include "ash/lock_screen_action/lock_screen_action_background_controller.h" 14 #include "ash/lock_screen_action/lock_screen_action_background_observer.h" 15 #include "ash/login/ui/login_data_dispatcher.h" 16 #include "ash/public/cpp/kiosk_app_menu.h" 17 #include "ash/public/cpp/login_types.h" 18 #include "ash/public/cpp/scoped_guest_button_blocker.h" 19 #include "ash/shutdown_controller_impl.h" 20 #include "ash/tray_action/tray_action.h" 21 #include "ash/tray_action/tray_action_observer.h" 22 #include "base/memory/weak_ptr.h" 23 #include "base/scoped_observer.h" 24 #include "ui/views/controls/button/button.h" 25 #include "ui/views/view.h" 26 27 namespace gfx { 28 class ImageSkia; 29 } 30 31 namespace session_manager { 32 enum class SessionState; 33 } 34 35 namespace ash { 36 37 enum class LockScreenActionBackgroundState; 38 39 class KioskAppsButton; 40 41 // LoginShelfView contains the shelf buttons visible outside of an active user 42 // session. ShelfView and LoginShelfView should never be shown together. 43 class ASH_EXPORT LoginShelfView : public views::View, 44 public TrayActionObserver, 45 public LockScreenActionBackgroundObserver, 46 public ShutdownControllerImpl::Observer, 47 public LoginDataDispatcher::Observer { 48 public: 49 enum ButtonId { 50 kShutdown = 1, // Shut down the device. 51 kRestart, // Restart the device. 52 kSignOut, // Sign out the active user session. 53 kCloseNote, // Close the lock screen note. 54 kCancel, // Cancel multiple user sign-in. 55 kBrowseAsGuest, // Use in guest mode. 56 kAddUser, // Add a new user. 57 kApps, // Show list of available kiosk apps. 58 kParentAccess, // Unlock child device with Parent Access Code. 59 kEnterpriseEnrollment, // Start enterprise enrollment flow. 60 }; 61 62 // Stores and notifies UiUpdate test callbacks. 63 class TestUiUpdateDelegate { 64 public: 65 virtual ~TestUiUpdateDelegate(); 66 virtual void OnUiUpdate() = 0; 67 }; 68 69 public: 70 explicit LoginShelfView( 71 LockScreenActionBackgroundController* lock_screen_action_background); 72 ~LoginShelfView() override; 73 74 // ShelfWidget observes SessionController for higher-level UI changes and 75 // then notifies LoginShelfView to update its own UI. 76 void UpdateAfterSessionChange(); 77 78 // Sets the contents of the kiosk app menu, as well as the callback used when 79 // a menu item is selected. 80 void SetKioskApps( 81 const std::vector<KioskAppMenuEntry>& kiosk_apps, 82 const base::RepeatingCallback<void(const KioskAppMenuEntry&)>& launch_app, 83 const base::RepeatingClosure& on_show_menu); 84 85 // Sets the state of the login dialog. 86 void SetLoginDialogState(OobeDialogState state); 87 88 // Sets if the guest button on the login shelf can be shown. Even if set to 89 // true the button may still not be visible. 90 void SetAllowLoginAsGuest(bool allow_guest); 91 92 // Sets whether parent access button can be shown on the login shelf. 93 void ShowParentAccessButton(bool show); 94 95 // Sets if the guest button and apps button on the login shelf can be 96 // shown during gaia signin screen. 97 void SetIsFirstSigninStep(bool is_first); 98 99 // Sets whether users can be added from the login screen. 100 void SetAddUserButtonEnabled(bool enable_add_user); 101 102 // Sets whether shutdown button is enabled in the login screen. 103 void SetShutdownButtonEnabled(bool enable_shutdown_button); 104 105 // Sets and animates the opacity of login shelf buttons. 106 void SetButtonOpacity(float target_opacity); 107 108 // views::View: 109 const char* GetClassName() const override; 110 void OnFocus() override; 111 void AboutToRequestFocusFromTabTraversal(bool reverse) override; 112 void GetAccessibleNodeData(ui::AXNodeData* node_data) override; 113 void Layout() override; 114 get_button_union_bounds()115 gfx::Rect get_button_union_bounds() const { return button_union_bounds_; } 116 117 // Test API. Returns true if request was successful (i.e. button was 118 // clickable). 119 bool LaunchAppForTesting(const std::string& app_id); 120 121 // Adds test delegate. Delegate will become owned by LoginShelfView. 122 void InstallTestUiUpdateDelegate( 123 std::unique_ptr<TestUiUpdateDelegate> delegate); 124 test_ui_update_delegate()125 TestUiUpdateDelegate* test_ui_update_delegate() { 126 return test_ui_update_delegate_.get(); 127 } 128 129 // Returns scoped object to temporarily block Browse as Guest login button. 130 std::unique_ptr<ScopedGuestButtonBlocker> GetScopedGuestButtonBlocker(); 131 132 // TrayActionObserver: 133 void OnLockScreenNoteStateChanged(mojom::TrayActionState state) override; 134 135 // LockScreenActionBackgroundObserver: 136 void OnLockScreenActionBackgroundStateChanged( 137 LockScreenActionBackgroundState state) override; 138 139 // ShutdownControllerImpl::Observer: 140 void OnShutdownPolicyChanged(bool reboot_on_shutdown) override; 141 142 // LoginDataDispatcher::Observer: 143 void OnUsersChanged(const std::vector<LoginUserInfo>& users) override; 144 void OnOobeDialogStateChanged(OobeDialogState state) override; 145 146 // Called when a locale change is detected. Updates the login shelf button 147 // strings. 148 void HandleLocaleChange(); 149 150 private: 151 class ScopedGuestButtonBlockerImpl; 152 153 bool LockScreenActionBackgroundAnimating() const; 154 155 // Updates the visibility of buttons based on state changes, e.g. shutdown 156 // policy updates, session state changes etc. 157 void UpdateUi(); 158 159 // Updates the color of all buttons. Uses dark colors if |use_dark_colors| is 160 // true, light colors otherwise. 161 void UpdateButtonColors(bool use_dark_colors); 162 163 // Updates the total bounds of all buttons. 164 void UpdateButtonUnionBounds(); 165 166 bool ShouldShowGuestButton() const; 167 168 bool ShouldShowEnterpriseEnrollmentButton() const; 169 170 bool ShouldShowAppsButton() const; 171 172 bool ShouldShowGuestAndAppsButtons() const; 173 174 OobeDialogState dialog_state_ = OobeDialogState::HIDDEN; 175 bool allow_guest_ = true; 176 bool is_first_signin_step_ = false; 177 bool show_parent_access_ = false; 178 // When the Gaia screen is active during Login, the guest-login button should 179 // appear if there are no user views. 180 bool login_screen_has_users_ = false; 181 182 LockScreenActionBackgroundController* lock_screen_action_background_; 183 184 ScopedObserver<TrayAction, TrayActionObserver> tray_action_observer_{this}; 185 186 ScopedObserver<LockScreenActionBackgroundController, 187 LockScreenActionBackgroundObserver> 188 lock_screen_action_background_observer_{this}; 189 190 ScopedObserver<ShutdownControllerImpl, ShutdownControllerImpl::Observer> 191 shutdown_controller_observer_{this}; 192 193 ScopedObserver<LoginDataDispatcher, LoginDataDispatcher::Observer> 194 login_data_dispatcher_observer_{this}; 195 196 // The kiosk app button will only be created for the primary display's login 197 // shelf. 198 KioskAppsButton* kiosk_apps_button_ = nullptr; 199 200 // This is used in tests to wait until UI is updated. 201 std::unique_ptr<TestUiUpdateDelegate> test_ui_update_delegate_; 202 203 // The bounds of all the buttons that this view is showing. Useful for 204 // letting events that target the "empty space" pass through. These 205 // coordinates are local to the view. 206 gfx::Rect button_union_bounds_; 207 208 // Number of active scoped Guest button blockers. 209 int scoped_guest_button_blockers_ = 0; 210 211 base::WeakPtrFactory<LoginShelfView> weak_ptr_factory_{this}; 212 213 DISALLOW_COPY_AND_ASSIGN(LoginShelfView); 214 }; 215 216 } // namespace ash 217 218 #endif // ASH_SHELF_LOGIN_SHELF_VIEW_H_ 219