1 // Copyright 2018 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 #include "ash/keyboard/keyboard_controller_impl.h"
6 
7 #include <utility>
8 
9 #include "ash/keyboard/ui/keyboard_ui_controller.h"
10 #include "ash/keyboard/ui/keyboard_ui_factory.h"
11 #include "ash/keyboard/virtual_keyboard_controller.h"
12 #include "ash/public/cpp/ash_constants.h"
13 #include "ash/public/cpp/ash_pref_names.h"
14 #include "ash/public/cpp/keyboard/keyboard_switches.h"
15 #include "ash/public/cpp/shell_window_ids.h"
16 #include "ash/root_window_controller.h"
17 #include "ash/session/session_controller_impl.h"
18 #include "ash/shelf/shelf.h"
19 #include "ash/shell.h"
20 #include "ash/shell_delegate.h"
21 #include "ash/wm/window_util.h"
22 #include "base/command_line.h"
23 #include "base/optional.h"
24 #include "components/pref_registry/pref_registry_syncable.h"
25 #include "components/prefs/pref_change_registrar.h"
26 #include "components/prefs/pref_service.h"
27 #include "ui/aura/env.h"
28 #include "ui/aura/window_delegate.h"
29 #include "ui/base/ui_base_features.h"
30 #include "ui/events/base_event_utils.h"
31 #include "ui/events/gestures/gesture_recognizer.h"
32 #include "ui/gfx/geometry/rect.h"
33 #include "ui/wm/core/coordinate_conversion.h"
34 
35 using keyboard::KeyboardConfig;
36 using keyboard::KeyboardEnableFlag;
37 
38 namespace ash {
39 
40 namespace {
41 
42 // Boolean controlling whether auto-complete for virtual keyboard is
43 // enabled.
44 const char kAutoCompleteEnabledKey[] = "auto_complete_enabled";
45 // Boolean controlling whether auto-correct for virtual keyboard is
46 // enabled.
47 const char kAutoCorrectEnabledKey[] = "auto_correct_enabled";
48 // Boolean controlling whether handwriting for virtual keyboard is
49 // enabled.
50 const char kHandwritingEnabledKey[] = "handwriting_enabled";
51 // Boolean controlling whether spell check for virtual keyboard is
52 // enabled.
53 const char kSpellCheckEnabledKey[] = "spell_check_enabled";
54 // Boolean controlling whether voice input for virtual keyboard is
55 // enabled.
56 const char kVoiceInputEnabledKey[] = "voice_input_enabled";
57 
GetFirstTouchDisplay()58 base::Optional<display::Display> GetFirstTouchDisplay() {
59   for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
60     if (display.touch_support() == display::Display::TouchSupport::AVAILABLE)
61       return display;
62   }
63   return base::nullopt;
64 }
65 
GetVirtualKeyboardFeatureValue(PrefService * prefs,const std::string & feature_path)66 bool GetVirtualKeyboardFeatureValue(PrefService* prefs,
67                                     const std::string& feature_path) {
68   DCHECK(prefs);
69   const base::DictionaryValue* features =
70       prefs->GetDictionary(prefs::kAccessibilityVirtualKeyboardFeatures);
71 
72   if (!features)
73     return false;
74 
75   bool feature_value = false;
76   return features->GetBoolean(feature_path, &feature_value) && feature_value;
77 }
78 
79 }  // namespace
80 
KeyboardControllerImpl(SessionControllerImpl * session_controller)81 KeyboardControllerImpl::KeyboardControllerImpl(
82     SessionControllerImpl* session_controller)
83     : session_controller_(session_controller),
84       keyboard_ui_controller_(
85           std::make_unique<keyboard::KeyboardUIController>()) {
86   if (session_controller_)  // May be null in tests.
87     session_controller_->AddObserver(this);
88   keyboard_ui_controller_->AddObserver(this);
89 }
90 
~KeyboardControllerImpl()91 KeyboardControllerImpl::~KeyboardControllerImpl() {
92   keyboard_ui_controller_->RemoveObserver(this);
93   if (session_controller_)  // May be null in tests.
94     session_controller_->RemoveObserver(this);
95 }
96 
97 // static
RegisterProfilePrefs(PrefRegistrySimple * registry)98 void KeyboardControllerImpl::RegisterProfilePrefs(
99     PrefRegistrySimple* registry) {
100   registry->RegisterBooleanPref(
101       ash::prefs::kXkbAutoRepeatEnabled, ash::kDefaultKeyAutoRepeatEnabled,
102       user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
103   registry->RegisterIntegerPref(
104       ash::prefs::kXkbAutoRepeatDelay,
105       ash::kDefaultKeyAutoRepeatDelay.InMilliseconds(),
106       user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
107   registry->RegisterIntegerPref(
108       ash::prefs::kXkbAutoRepeatInterval,
109       ash::kDefaultKeyAutoRepeatInterval.InMilliseconds(),
110       user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
111   registry->RegisterDictionaryPref(
112       prefs::kAccessibilityVirtualKeyboardFeatures);
113 }
114 
CreateVirtualKeyboard(std::unique_ptr<keyboard::KeyboardUIFactory> keyboard_ui_factory)115 void KeyboardControllerImpl::CreateVirtualKeyboard(
116     std::unique_ptr<keyboard::KeyboardUIFactory> keyboard_ui_factory) {
117   DCHECK(keyboard_ui_factory);
118   virtual_keyboard_controller_ = std::make_unique<VirtualKeyboardController>();
119   keyboard_ui_controller_->Initialize(std::move(keyboard_ui_factory), this);
120 
121   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
122           keyboard::switches::kEnableVirtualKeyboard)) {
123     keyboard_ui_controller_->SetEnableFlag(
124         KeyboardEnableFlag::kCommandLineEnabled);
125   }
126 }
127 
DestroyVirtualKeyboard()128 void KeyboardControllerImpl::DestroyVirtualKeyboard() {
129   virtual_keyboard_controller_.reset();
130   keyboard_ui_controller_->Shutdown();
131 }
132 
SendOnKeyboardVisibleBoundsChanged(const gfx::Rect & screen_bounds)133 void KeyboardControllerImpl::SendOnKeyboardVisibleBoundsChanged(
134     const gfx::Rect& screen_bounds) {
135   DVLOG(1) << "OnKeyboardVisibleBoundsChanged: " << screen_bounds.ToString();
136   for (auto& observer : observers_)
137     observer.OnKeyboardVisibleBoundsChanged(screen_bounds);
138 }
139 
SendOnKeyboardUIDestroyed()140 void KeyboardControllerImpl::SendOnKeyboardUIDestroyed() {
141   for (auto& observer : observers_)
142     observer.OnKeyboardUIDestroyed();
143 }
144 
145 // ash::KeyboardController
146 
GetKeyboardConfig()147 keyboard::KeyboardConfig KeyboardControllerImpl::GetKeyboardConfig() {
148   if (!keyboard_config_from_pref_enabled_)
149     return keyboard_ui_controller_->keyboard_config();
150 
151   PrefService* prefs = pref_change_registrar_->prefs();
152   KeyboardConfig config;
153   config.auto_complete =
154       GetVirtualKeyboardFeatureValue(prefs, kAutoCompleteEnabledKey);
155   config.auto_correct =
156       GetVirtualKeyboardFeatureValue(prefs, kAutoCorrectEnabledKey);
157   config.handwriting =
158       GetVirtualKeyboardFeatureValue(prefs, kHandwritingEnabledKey);
159   config.spell_check =
160       GetVirtualKeyboardFeatureValue(prefs, kSpellCheckEnabledKey);
161   config.voice_input =
162       GetVirtualKeyboardFeatureValue(prefs, kVoiceInputEnabledKey);
163   return config;
164 }
165 
SetKeyboardConfig(const KeyboardConfig & keyboard_config)166 void KeyboardControllerImpl::SetKeyboardConfig(
167     const KeyboardConfig& keyboard_config) {
168   keyboard_ui_controller_->UpdateKeyboardConfig(keyboard_config);
169 }
170 
IsKeyboardEnabled()171 bool KeyboardControllerImpl::IsKeyboardEnabled() {
172   return keyboard_ui_controller_->IsEnabled();
173 }
174 
SetEnableFlag(KeyboardEnableFlag flag)175 void KeyboardControllerImpl::SetEnableFlag(KeyboardEnableFlag flag) {
176   keyboard_ui_controller_->SetEnableFlag(flag);
177 }
178 
ClearEnableFlag(KeyboardEnableFlag flag)179 void KeyboardControllerImpl::ClearEnableFlag(KeyboardEnableFlag flag) {
180   keyboard_ui_controller_->ClearEnableFlag(flag);
181 }
182 
183 const std::set<keyboard::KeyboardEnableFlag>&
GetEnableFlags()184 KeyboardControllerImpl::GetEnableFlags() {
185   return keyboard_ui_controller_->keyboard_enable_flags();
186 }
187 
ReloadKeyboardIfNeeded()188 void KeyboardControllerImpl::ReloadKeyboardIfNeeded() {
189   keyboard_ui_controller_->Reload();
190 }
191 
RebuildKeyboardIfEnabled()192 void KeyboardControllerImpl::RebuildKeyboardIfEnabled() {
193   // Test IsKeyboardEnableRequested in case of an unlikely edge case where this
194   // is called while after the enable state changed to disabled (in which case
195   // we do not want to override the requested state).
196   keyboard_ui_controller_->RebuildKeyboardIfEnabled();
197 }
198 
IsKeyboardVisible()199 bool KeyboardControllerImpl::IsKeyboardVisible() {
200   return keyboard_ui_controller_->IsKeyboardVisible();
201 }
202 
ShowKeyboard()203 void KeyboardControllerImpl::ShowKeyboard() {
204   if (keyboard_ui_controller_->IsEnabled())
205     keyboard_ui_controller_->ShowKeyboard(false /* lock */);
206 }
207 
HideKeyboard(HideReason reason)208 void KeyboardControllerImpl::HideKeyboard(HideReason reason) {
209   if (!keyboard_ui_controller_->IsEnabled())
210     return;
211   switch (reason) {
212     case HideReason::kUser:
213       keyboard_ui_controller_->HideKeyboardByUser();
214       break;
215     case HideReason::kSystem:
216       keyboard_ui_controller_->HideKeyboardExplicitlyBySystem();
217       break;
218   }
219 }
220 
SetContainerType(keyboard::ContainerType container_type,const gfx::Rect & target_bounds,SetContainerTypeCallback callback)221 void KeyboardControllerImpl::SetContainerType(
222     keyboard::ContainerType container_type,
223     const gfx::Rect& target_bounds,
224     SetContainerTypeCallback callback) {
225   keyboard_ui_controller_->SetContainerType(container_type, target_bounds,
226                                             std::move(callback));
227 }
228 
SetKeyboardLocked(bool locked)229 void KeyboardControllerImpl::SetKeyboardLocked(bool locked) {
230   keyboard_ui_controller_->set_keyboard_locked(locked);
231 }
232 
SetOccludedBounds(const std::vector<gfx::Rect> & bounds)233 void KeyboardControllerImpl::SetOccludedBounds(
234     const std::vector<gfx::Rect>& bounds) {
235   // TODO(https://crbug.com/826617): Support occluded bounds with multiple
236   // rectangles.
237   keyboard_ui_controller_->SetOccludedBounds(bounds.empty() ? gfx::Rect()
238                                                             : bounds[0]);
239 }
240 
SetHitTestBounds(const std::vector<gfx::Rect> & bounds)241 void KeyboardControllerImpl::SetHitTestBounds(
242     const std::vector<gfx::Rect>& bounds) {
243   keyboard_ui_controller_->SetHitTestBounds(bounds);
244 }
245 
SetAreaToRemainOnScreen(const gfx::Rect & bounds)246 bool KeyboardControllerImpl::SetAreaToRemainOnScreen(const gfx::Rect& bounds) {
247   return keyboard_ui_controller_->SetAreaToRemainOnScreen(bounds);
248 }
249 
SetDraggableArea(const gfx::Rect & bounds)250 void KeyboardControllerImpl::SetDraggableArea(const gfx::Rect& bounds) {
251   keyboard_ui_controller_->SetDraggableArea(bounds);
252 }
253 
SetWindowBoundsInScreen(const gfx::Rect & bounds_in_screen)254 bool KeyboardControllerImpl::SetWindowBoundsInScreen(
255     const gfx::Rect& bounds_in_screen) {
256   return keyboard_ui_controller_->SetKeyboardWindowBoundsInScreen(
257       bounds_in_screen);
258 }
259 
SetKeyboardConfigFromPref(bool enabled)260 void KeyboardControllerImpl::SetKeyboardConfigFromPref(bool enabled) {
261   keyboard_config_from_pref_enabled_ = enabled;
262   SendKeyboardConfigUpdate();
263 }
264 
ShouldOverscroll()265 bool KeyboardControllerImpl::ShouldOverscroll() {
266   return keyboard_ui_controller_->IsKeyboardOverscrollEnabled();
267 }
268 
AddObserver(KeyboardControllerObserver * observer)269 void KeyboardControllerImpl::AddObserver(KeyboardControllerObserver* observer) {
270   observers_.AddObserver(observer);
271 }
272 
RemoveObserver(KeyboardControllerObserver * observer)273 void KeyboardControllerImpl::RemoveObserver(
274     KeyboardControllerObserver* observer) {
275   observers_.RemoveObserver(observer);
276 }
277 
GetKeyRepeatSettings()278 KeyRepeatSettings KeyboardControllerImpl::GetKeyRepeatSettings() {
279   PrefService* prefs = pref_change_registrar_->prefs();
280   bool enabled = prefs->GetBoolean(ash::prefs::kXkbAutoRepeatEnabled);
281   int delay_in_ms = prefs->GetInteger(ash::prefs::kXkbAutoRepeatDelay);
282   int interval_in_ms = prefs->GetInteger(ash::prefs::kXkbAutoRepeatInterval);
283   return KeyRepeatSettings{enabled,
284                            base::TimeDelta::FromMilliseconds(delay_in_ms),
285                            base::TimeDelta::FromMilliseconds(interval_in_ms)};
286 }
287 
288 // SessionObserver
OnSessionStateChanged(session_manager::SessionState state)289 void KeyboardControllerImpl::OnSessionStateChanged(
290     session_manager::SessionState state) {
291   if (!keyboard_ui_controller_->IsEnabled())
292     return;
293 
294   switch (state) {
295     case session_manager::SessionState::LOGGED_IN_NOT_ACTIVE:
296     case session_manager::SessionState::ACTIVE:
297       // Reload the keyboard on user profile change to refresh keyboard
298       // extensions with the new profile and ensure the extensions call the
299       // proper IME. |LOGGED_IN_NOT_ACTIVE| is needed so that the virtual
300       // keyboard works on supervised user creation, http://crbug.com/712873.
301       // |ACTIVE| is also needed for guest user workflow.
302       RebuildKeyboardIfEnabled();
303       break;
304     default:
305       break;
306   }
307 }
308 
OnSigninScreenPrefServiceInitialized(PrefService * prefs)309 void KeyboardControllerImpl::OnSigninScreenPrefServiceInitialized(
310     PrefService* prefs) {
311   ObservePrefs(prefs);
312 }
313 
OnActiveUserPrefServiceChanged(PrefService * prefs)314 void KeyboardControllerImpl::OnActiveUserPrefServiceChanged(
315     PrefService* prefs) {
316   ObservePrefs(prefs);
317 }
318 
319 // Start listening to key repeat preferences from the given service.
320 // Also immediately update observers with the service's current preferences.
321 //
322 // We only need to observe the most recent PrefService. It will either be the
323 // active user's PrefService, or the signin screen's PrefService if nobody's
324 // logged in yet.
ObservePrefs(PrefService * prefs)325 void KeyboardControllerImpl::ObservePrefs(PrefService* prefs) {
326   pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
327   pref_change_registrar_->Init(prefs);
328 
329   // Immediately tell all our observers to load this user's saved preferences.
330   SendKeyRepeatUpdate();
331   SendKeyboardConfigUpdate();
332 
333   // Listen to prefs changes and forward them to all observers.
334   // |prefs| is assumed to outlive |pref_change_registrar_|, and therefore also
335   // its callbacks.
336   pref_change_registrar_->Add(
337       ash::prefs::kXkbAutoRepeatEnabled,
338       base::BindRepeating(&KeyboardControllerImpl::SendKeyRepeatUpdate,
339                           base::Unretained(this)));
340   pref_change_registrar_->Add(
341       ash::prefs::kXkbAutoRepeatInterval,
342       base::BindRepeating(&KeyboardControllerImpl::SendKeyRepeatUpdate,
343                           base::Unretained(this)));
344   pref_change_registrar_->Add(
345       ash::prefs::kXkbAutoRepeatDelay,
346       base::BindRepeating(&KeyboardControllerImpl::SendKeyRepeatUpdate,
347                           base::Unretained(this)));
348   pref_change_registrar_->Add(
349       ash::prefs::kAccessibilityVirtualKeyboardFeatures,
350       base::BindRepeating(&KeyboardControllerImpl::SendKeyboardConfigUpdate,
351                           base::Unretained(this)));
352 }
353 
SendKeyRepeatUpdate()354 void KeyboardControllerImpl::SendKeyRepeatUpdate() {
355   OnKeyRepeatSettingsChanged(GetKeyRepeatSettings());
356 }
357 
SendKeyboardConfigUpdate()358 void KeyboardControllerImpl::SendKeyboardConfigUpdate() {
359   keyboard_ui_controller_->UpdateKeyboardConfig(GetKeyboardConfig());
360 }
361 
OnRootWindowClosing(aura::Window * root_window)362 void KeyboardControllerImpl::OnRootWindowClosing(aura::Window* root_window) {
363   if (keyboard_ui_controller_->GetRootWindow() == root_window) {
364     aura::Window* new_parent = GetContainerForDefaultDisplay();
365     DCHECK_NE(root_window, new_parent);
366     keyboard_ui_controller_->MoveToParentContainer(new_parent);
367   }
368 }
369 
GetContainerForDisplay(const display::Display & display)370 aura::Window* KeyboardControllerImpl::GetContainerForDisplay(
371     const display::Display& display) {
372   DCHECK(display.is_valid());
373 
374   RootWindowController* controller =
375       Shell::Get()->GetRootWindowControllerWithDisplayId(display.id());
376   aura::Window* container =
377       controller->GetContainer(kShellWindowId_VirtualKeyboardContainer);
378   DCHECK(container);
379   return container;
380 }
381 
GetContainerForDefaultDisplay()382 aura::Window* KeyboardControllerImpl::GetContainerForDefaultDisplay() {
383   const display::Screen* screen = display::Screen::GetScreen();
384   const base::Optional<display::Display> first_touch_display =
385       GetFirstTouchDisplay();
386   const bool has_touch_display = first_touch_display.has_value();
387 
388   if (window_util::GetFocusedWindow()) {
389     // Return the focused display if that display has touch capability or no
390     // other display has touch capability.
391     const display::Display focused_display =
392         screen->GetDisplayNearestWindow(window_util::GetFocusedWindow());
393     if (focused_display.is_valid() &&
394         (focused_display.touch_support() ==
395              display::Display::TouchSupport::AVAILABLE ||
396          !has_touch_display)) {
397       return GetContainerForDisplay(focused_display);
398     }
399   }
400 
401   // Return the first touch display, or the primary display if there are none.
402   return GetContainerForDisplay(
403       has_touch_display ? *first_touch_display : screen->GetPrimaryDisplay());
404 }
405 
TransferGestureEventToShelf(const ui::GestureEvent & e)406 void KeyboardControllerImpl::TransferGestureEventToShelf(
407     const ui::GestureEvent& e) {
408   ash::Shelf* shelf =
409       ash::Shelf::ForWindow(keyboard_ui_controller_->GetKeyboardWindow());
410   if (shelf) {
411     shelf->ProcessGestureEvent(e);
412     aura::Env::GetInstance()->gesture_recognizer()->TransferEventsTo(
413         keyboard_ui_controller_->GetGestureConsumer(), shelf->GetWindow(),
414         ui::TransferTouchesBehavior::kCancel);
415     HideKeyboard(HideReason::kUser);
416   }
417 }
418 
OnKeyboardConfigChanged(const keyboard::KeyboardConfig & config)419 void KeyboardControllerImpl::OnKeyboardConfigChanged(
420     const keyboard::KeyboardConfig& config) {
421   for (auto& observer : observers_)
422     observer.OnKeyboardConfigChanged(config);
423 }
424 
OnKeyRepeatSettingsChanged(const KeyRepeatSettings & settings)425 void KeyboardControllerImpl::OnKeyRepeatSettingsChanged(
426     const KeyRepeatSettings& settings) {
427   for (auto& observer : observers_)
428     observer.OnKeyRepeatSettingsChanged(settings);
429 }
430 
OnKeyboardVisibilityChanged(bool is_visible)431 void KeyboardControllerImpl::OnKeyboardVisibilityChanged(bool is_visible) {
432   for (auto& observer : observers_)
433     observer.OnKeyboardVisibilityChanged(is_visible);
434 }
435 
OnKeyboardVisibleBoundsChanged(const gfx::Rect & screen_bounds)436 void KeyboardControllerImpl::OnKeyboardVisibleBoundsChanged(
437     const gfx::Rect& screen_bounds) {
438   SendOnKeyboardVisibleBoundsChanged(screen_bounds);
439 }
440 
OnKeyboardOccludedBoundsChanged(const gfx::Rect & screen_bounds)441 void KeyboardControllerImpl::OnKeyboardOccludedBoundsChanged(
442     const gfx::Rect& screen_bounds) {
443   DVLOG(1) << "OnKeyboardOccludedBoundsChanged: " << screen_bounds.ToString();
444   for (auto& observer : observers_)
445     observer.OnKeyboardOccludedBoundsChanged(screen_bounds);
446 }
447 
OnKeyboardEnableFlagsChanged(const std::set<keyboard::KeyboardEnableFlag> & flags)448 void KeyboardControllerImpl::OnKeyboardEnableFlagsChanged(
449     const std::set<keyboard::KeyboardEnableFlag>& flags) {
450   for (auto& observer : observers_)
451     observer.OnKeyboardEnableFlagsChanged(flags);
452 }
453 
OnKeyboardEnabledChanged(bool is_enabled)454 void KeyboardControllerImpl::OnKeyboardEnabledChanged(bool is_enabled) {
455   for (auto& observer : observers_)
456     observer.OnKeyboardEnabledChanged(is_enabled);
457 }
458 
459 }  // namespace ash
460