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