1 // Copyright 2019 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_LOGIN_UI_PIN_REQUEST_VIEW_H_ 6 #define ASH_LOGIN_UI_PIN_REQUEST_VIEW_H_ 7 8 #include <string> 9 10 #include "ash/ash_export.h" 11 #include "ash/login/ui/access_code_input.h" 12 #include "ash/public/cpp/login_types.h" 13 #include "ash/public/cpp/tablet_mode_observer.h" 14 #include "ash/wm/tablet_mode/tablet_mode_controller.h" 15 #include "ui/views/window/dialog_delegate.h" 16 17 namespace views { 18 class Label; 19 class LabelButton; 20 class Textfield; 21 } // namespace views 22 23 namespace ash { 24 class ArrowButtonView; 25 class LoginButton; 26 class LoginPinView; 27 28 // State of the PinRequestView. 29 enum class PinRequestViewState { 30 kNormal, 31 kError, 32 }; 33 34 struct ASH_EXPORT PinRequest { 35 PinRequest(); 36 PinRequest(PinRequest&&); 37 PinRequest& operator=(PinRequest&&); 38 ~PinRequest(); 39 40 // Callback for PIN validations. It is called when the validation has finished 41 // and the view is closing. 42 // |success| indicates whether the validation was successful. 43 using OnPinRequestDone = base::OnceCallback<void(bool success)>; 44 OnPinRequestDone on_pin_request_done = base::NullCallback(); 45 46 // Whether the help button is displayed. 47 bool help_button_enabled = false; 48 49 base::Optional<int> pin_length; 50 51 // When |pin_keyboard_always_enabled| is set, the PIN keyboard is displayed at 52 // all times. Otherwise, it is only displayed when the device is in tablet 53 // mode. 54 bool pin_keyboard_always_enabled = false; 55 56 // The pin widget is a modal and already contains a dimmer, however 57 // when another modal is the parent of the widget, the dimmer will be placed 58 // behind the two windows. |extra_dimmer| will create an extra dimmer between 59 // the two. 60 bool extra_dimmer = false; 61 62 // Whether the entered PIN should be displayed clearly or only as bullets. 63 bool obscure_pin = true; 64 65 // Strings for UI. 66 base::string16 title; 67 base::string16 description; 68 base::string16 accessible_title; 69 }; 70 71 // The view that allows for input of pins to authorize certain actions. 72 class ASH_EXPORT PinRequestView : public views::DialogDelegateView, 73 public TabletModeObserver { 74 public: 75 enum class SubmissionResult { 76 // Closes the UI and calls |on_pin_request_done_|. 77 kPinAccepted, 78 // PIN rejected - keeps the UI in its current state. 79 kPinError, 80 // Async waiting for result - keeps the UI in its current state. 81 kSubmitPending, 82 }; 83 84 class Delegate { 85 public: 86 virtual SubmissionResult OnPinSubmitted(const std::string& pin) = 0; 87 virtual void OnBack() = 0; 88 virtual void OnHelp(gfx::NativeWindow parent_window) = 0; 89 90 protected: 91 virtual ~Delegate() = default; 92 }; 93 94 class ASH_EXPORT TestApi { 95 public: 96 explicit TestApi(PinRequestView* view); 97 ~TestApi(); 98 99 LoginButton* back_button(); 100 views::Label* title_label(); 101 views::Label* description_label(); 102 views::View* access_code_view(); 103 views::LabelButton* help_button(); 104 ArrowButtonView* submit_button(); 105 LoginPinView* pin_keyboard_view(); 106 107 views::Textfield* GetInputTextField(int index); 108 PinRequestViewState state() const; 109 110 private: 111 PinRequestView* const view_; 112 }; 113 114 // Returns color used for dialog and UI elements specific for child user. 115 // |using_blur| should be true if the UI element is using background blur 116 // (color transparency depends on it). 117 static SkColor GetChildUserDialogColor(bool using_blur); 118 119 // Creates pin request view that will enable the user to enter a pin. 120 // |request| is used to configure callbacks and UI details. 121 PinRequestView(PinRequest request, Delegate* delegate); 122 ~PinRequestView() override; 123 124 // views::View: 125 void OnPaint(gfx::Canvas* canvas) override; 126 void RequestFocus() override; 127 gfx::Size CalculatePreferredSize() const override; 128 void GetAccessibleNodeData(ui::AXNodeData* node_data) override; 129 130 // views::DialogDelegateView: 131 views::View* GetInitiallyFocusedView() override; 132 base::string16 GetAccessibleWindowTitle() const override; 133 134 // TabletModeObserver: 135 void OnTabletModeStarted() override; 136 void OnTabletModeEnded() override; 137 void OnTabletControllerDestroyed() override; 138 139 // Sets whether the user can enter a PIN. Other buttons (back, submit etc.) 140 // are unaffected. 141 void SetInputEnabled(bool input_enabled); 142 143 // Clears previously entered PIN from the PIN input field(s). 144 void ClearInput(); 145 146 // Updates state of the view. 147 void UpdateState(PinRequestViewState state, 148 const base::string16& title, 149 const base::string16& description); 150 151 private: 152 class FocusableLabelButton; 153 154 // Submits access code for validation. 155 void SubmitCode(); 156 157 // Closes the view. 158 void OnBack(); 159 160 // Updates view's preferred size. 161 void UpdatePreferredSize(); 162 163 // Moves focus to |submit_button_|. 164 void FocusSubmitButton(); 165 166 // Called when access code input changes. |complete| brings information 167 // whether current input code is complete. |last_field_active| contains 168 // information whether last input field is currently active. 169 void OnInputChange(bool last_field_active, bool complete); 170 171 // Returns if the pin keyboard should be visible. 172 bool PinKeyboardVisible() const; 173 174 // Size that depends on the pin keyboards visibility. 175 gfx::Size GetPinRequestViewSize() const; 176 177 PinRequestViewState state_ = PinRequestViewState::kNormal; 178 179 // Unowned pointer to the delegate. The delegate should outlive this instance. 180 Delegate* delegate_; 181 182 // Callback to close the UI. 183 PinRequest::OnPinRequestDone on_pin_request_done_; 184 185 // Auto submit code when the last input has been inserted. 186 bool auto_submit_enabled_ = true; 187 188 // If false, |pin_keyboard_view| is only displayed in tablet mode. 189 bool pin_keyboard_always_enabled_ = true; 190 191 // Strings as on view construction to enable restoring the original state. 192 base::string16 default_title_; 193 base::string16 default_description_; 194 base::string16 default_accessible_title_; 195 196 views::Label* title_label_ = nullptr; 197 views::Label* description_label_ = nullptr; 198 AccessCodeInput* access_code_view_ = nullptr; 199 LoginPinView* pin_keyboard_view_ = nullptr; 200 LoginButton* back_button_ = nullptr; 201 FocusableLabelButton* help_button_ = nullptr; 202 ArrowButtonView* submit_button_ = nullptr; 203 204 ScopedObserver<TabletModeController, TabletModeObserver> 205 tablet_mode_observer_{this}; 206 207 base::WeakPtrFactory<PinRequestView> weak_ptr_factory_{this}; 208 209 DISALLOW_COPY_AND_ASSIGN(PinRequestView); 210 }; 211 212 } // namespace ash 213 214 #endif // ASH_LOGIN_UI_PIN_REQUEST_VIEW_H_ 215