Adds a pref for autoclick menu location within the screen.

The user will be able to move the autoclick menu around the
screen. This adds a preference to track the user's preferred
menu position, with a default in the lower right corner.

Bug: 943703
Change-Id: I2a2d147455971624dd396970264927567ce6029d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1531387
Commit-Queue: Katie Dektar <katie@chromium.org>
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Reviewed-by: James Cook <jamescook@chromium.org>
Reviewed-by: David Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#642773}
diff --git a/ash/accessibility/accessibility_controller.cc b/ash/accessibility/accessibility_controller.cc
index 9d069279..e769cba 100644
--- a/ash/accessibility/accessibility_controller.cc
+++ b/ash/accessibility/accessibility_controller.cc
@@ -270,6 +270,9 @@
     registry->RegisterIntegerPref(
         prefs::kAccessibilityAutoclickMovementThreshold,
         kDefaultAutoclickMovementThreshold);
+    registry->RegisterIntegerPref(
+        prefs::kAccessibilityAutoclickMenuPosition,
+        static_cast<int>(kDefaultAutoclickMenuPosition));
     registry->RegisterBooleanPref(prefs::kAccessibilityCaretHighlightEnabled,
                                   false);
     registry->RegisterBooleanPref(prefs::kAccessibilityCursorHighlightEnabled,
@@ -320,6 +323,7 @@
       prefs::kAccessibilityAutoclickRevertToLeftClick);
   registry->RegisterForeignPref(
       prefs::kAccessibilityAutoclickMovementThreshold);
+  registry->RegisterForeignPref(prefs::kAccessibilityAutoclickMenuPosition);
   registry->RegisterForeignPref(prefs::kAccessibilityCaretHighlightEnabled);
   registry->RegisterForeignPref(prefs::kAccessibilityCursorHighlightEnabled);
   registry->RegisterForeignPref(prefs::kAccessibilityDictationEnabled);
@@ -837,6 +841,11 @@
           &AccessibilityController::UpdateAutoclickMovementThresholdFromPref,
           base::Unretained(this)));
   pref_change_registrar_->Add(
+      prefs::kAccessibilityAutoclickMenuPosition,
+      base::BindRepeating(
+          &AccessibilityController::UpdateAutoclickMenuPositionFromPref,
+          base::Unretained(this)));
+  pref_change_registrar_->Add(
       prefs::kAccessibilityCaretHighlightEnabled,
       base::BindRepeating(
           &AccessibilityController::UpdateCaretHighlightFromPref,
@@ -900,6 +909,7 @@
   UpdateAutoclickEventTypeFromPref();
   UpdateAutoclickRevertToLeftClickFromPref();
   UpdateAutoclickMovementThresholdFromPref();
+  UpdateAutoclickMenuPositionFromPref();
   UpdateCaretHighlightFromPref();
   UpdateCursorHighlightFromPref();
   UpdateDictationFromPref();
@@ -980,6 +990,15 @@
       movement_threshold);
 }
 
+void AccessibilityController::UpdateAutoclickMenuPositionFromPref() {
+  DCHECK(active_user_prefs_);
+  mojom::AutoclickMenuPosition menu_position =
+      static_cast<mojom::AutoclickMenuPosition>(active_user_prefs_->GetInteger(
+          prefs::kAccessibilityAutoclickMenuPosition));
+
+  Shell::Get()->autoclick_controller()->SetMenuPosition(menu_position);
+}
+
 void AccessibilityController::UpdateCaretHighlightFromPref() {
   DCHECK(active_user_prefs_);
   const bool enabled = active_user_prefs_->GetBoolean(
diff --git a/ash/accessibility/accessibility_controller.h b/ash/accessibility/accessibility_controller.h
index b24e12f..774a5ac 100644
--- a/ash/accessibility/accessibility_controller.h
+++ b/ash/accessibility/accessibility_controller.h
@@ -206,6 +206,7 @@
   void UpdateAutoclickEventTypeFromPref();
   void UpdateAutoclickRevertToLeftClickFromPref();
   void UpdateAutoclickMovementThresholdFromPref();
+  void UpdateAutoclickMenuPositionFromPref();
   void UpdateCaretHighlightFromPref();
   void UpdateCursorHighlightFromPref();
   void UpdateDictationFromPref();
diff --git a/ash/autoclick/autoclick_controller.cc b/ash/autoclick/autoclick_controller.cc
index 445e479..cf312d9 100644
--- a/ash/autoclick/autoclick_controller.cc
+++ b/ash/autoclick/autoclick_controller.cc
@@ -7,7 +7,6 @@
 #include "ash/accessibility/accessibility_controller.h"
 #include "ash/autoclick/autoclick_drag_event_rewriter.h"
 #include "ash/autoclick/autoclick_ring_handler.h"
-#include "ash/public/cpp/ash_constants.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shell.h"
@@ -65,17 +64,7 @@
 }
 
 AutoclickController::AutoclickController()
-    : enabled_(false),
-      event_type_(kDefaultAutoclickEventType),
-      revert_to_left_click_(true),
-      movement_threshold_(kDefaultAutoclickMovementThreshold),
-      tap_down_target_(nullptr),
-      delay_(GetDefaultAutoclickDelay()),
-      mouse_event_flags_(ui::EF_NONE),
-      anchor_location_(-kDefaultAutoclickMovementThreshold,
-                       -kDefaultAutoclickMovementThreshold),
-      gesture_anchor_location_(-kDefaultAutoclickMovementThreshold,
-                               -kDefaultAutoclickMovementThreshold),
+    : delay_(GetDefaultAutoclickDelay()),
       autoclick_ring_handler_(std::make_unique<AutoclickRingHandler>()),
       drag_event_rewriter_(std::make_unique<AutoclickDragEventRewriter>()) {
   Shell::GetPrimaryRootWindow()->GetHost()->GetEventSource()->AddEventRewriter(
@@ -147,6 +136,12 @@
   UpdateRingSize();
 }
 
+void AutoclickController::SetMenuPosition(
+    mojom::AutoclickMenuPosition menu_position) {
+  menu_position_ = menu_position;
+  // TODO(katie): When the on-screen menu exists, update its position here.
+}
+
 void AutoclickController::CreateAutoclickRingWidget(
     const gfx::Point& point_in_screen) {
   aura::Window* target = ash::wm::GetRootWindowAt(point_in_screen);
diff --git a/ash/autoclick/autoclick_controller.h b/ash/autoclick/autoclick_controller.h
index ef85ba3..85e0247 100644
--- a/ash/autoclick/autoclick_controller.h
+++ b/ash/autoclick/autoclick_controller.h
@@ -6,6 +6,7 @@
 #define ASH_AUTOCLICK_AUTOCLICK_CONTROLLER_H
 
 #include "ash/ash_export.h"
+#include "ash/public/cpp/ash_constants.h"
 #include "ash/public/interfaces/accessibility_controller_enums.mojom.h"
 #include "base/macros.h"
 #include "base/time/time.h"
@@ -56,6 +57,9 @@
   // a new Autoclick event.
   void SetMovementThreshold(int movement_threshold);
 
+  // Sets the menu position and updates the UI.
+  void SetMenuPosition(mojom::AutoclickMenuPosition menu_position);
+
   // Sets whether to revert to a left click after any other event type.
   void set_revert_to_left_click(bool revert_to_left_click) {
     revert_to_left_click_ = revert_to_left_click;
@@ -89,16 +93,32 @@
   // aura::WindowObserver overrides:
   void OnWindowDestroying(aura::Window* window) override;
 
-  bool enabled_;
-  mojom::AutoclickEventType event_type_;
-  bool revert_to_left_click_;
-  int movement_threshold_;
+  // Whether Autoclick is currently enabled.
+  bool enabled_ = false;
+  mojom::AutoclickEventType event_type_ = kDefaultAutoclickEventType;
+  bool revert_to_left_click_ = true;
+  int movement_threshold_ = kDefaultAutoclickMovementThreshold;
+  mojom::AutoclickMenuPosition menu_position_ = kDefaultAutoclickMenuPosition;
+  int mouse_event_flags_ = ui::EF_NONE;
   // The target window is observed by AutoclickController for the duration
   // of a autoclick gesture.
-  aura::Window* tap_down_target_;
+  aura::Window* tap_down_target_ = nullptr;
+  // The position in screen coordinates used to determine the distance the
+  // mouse has moved since dwell began. It is used to determine
+  // if move events should cancel the gesture.
+  gfx::Point anchor_location_ = gfx::Point(-kDefaultAutoclickMovementThreshold,
+                                           -kDefaultAutoclickMovementThreshold);
+  // The position in screen coodinates tracking where the autoclick gesture
+  // should be anchored. While the |start_gesture_timer_| is running and before
+  // the animation is drawn, subtle mouse movements will update the
+  // |gesture_anchor_location_|, so that once animation begins it can focus on
+  // the most recent mose point.
+  gfx::Point gesture_anchor_location_ =
+      gfx::Point(-kDefaultAutoclickMovementThreshold,
+                 -kDefaultAutoclickMovementThreshold);
+
   std::unique_ptr<views::Widget> widget_;
   base::TimeDelta delay_;
-  int mouse_event_flags_;
   // The timer that counts down from the beginning of a gesture until a click.
   std::unique_ptr<base::RetainingOneShotTimer> autoclick_timer_;
   // The timer that counts from when the user stops moving the mouse
@@ -106,16 +126,6 @@
   // showing up when the mouse cursor is moving quickly across the screen,
   // instead waiting for the mouse to begin a dwell.
   std::unique_ptr<base::RetainingOneShotTimer> start_gesture_timer_;
-  // The position in screen coordinates used to determine the distance the
-  // mouse has moved since dwell began. It is used to determine
-  // if move events should cancel the gesture.
-  gfx::Point anchor_location_;
-  // The position in screen coodinates tracking where the autoclick gesture
-  // should be anchored. While the |start_gesture_timer_| is running and before
-  // the animation is drawn, subtle mouse movements will update the
-  // |gesture_anchor_location_|, so that once animation begins it can focus on
-  // the most recent mose point.
-  gfx::Point gesture_anchor_location_;
   std::unique_ptr<AutoclickRingHandler> autoclick_ring_handler_;
   std::unique_ptr<AutoclickDragEventRewriter> drag_event_rewriter_;
 
diff --git a/ash/public/cpp/ash_constants.h b/ash/public/cpp/ash_constants.h
index d5018b4..a437660 100644
--- a/ash/public/cpp/ash_constants.h
+++ b/ash/public/cpp/ash_constants.h
@@ -47,6 +47,10 @@
 // a new autoclick.
 constexpr int kDefaultAutoclickMovementThreshold = 20;
 
+// The default automatic click menu position.
+constexpr mojom::AutoclickMenuPosition kDefaultAutoclickMenuPosition =
+    mojom::AutoclickMenuPosition::kBottomRight;
+
 // The default frame color.
 constexpr SkColor kDefaultFrameColor = SkColorSetRGB(0xFD, 0xFE, 0xFF);
 
diff --git a/ash/public/cpp/ash_pref_names.cc b/ash/public/cpp/ash_pref_names.cc
index f845d24f..8b20938 100644
--- a/ash/public/cpp/ash_pref_names.cc
+++ b/ash/public/cpp/ash_pref_names.cc
@@ -61,6 +61,9 @@
 // a new autoclick.
 const char kAccessibilityAutoclickMovementThreshold[] =
     "settings.a11y.autoclick_movement_threshold";
+// The Autoclick menu position on the screen, an mojom::AutoclickMenuPosition.
+const char kAccessibilityAutoclickMenuPosition[] =
+    "settings.a11y.autoclick_menu_position";
 // A boolean pref which determines whether caret highlighting is enabled.
 const char kAccessibilityCaretHighlightEnabled[] =
     "settings.a11y.caret_highlight";
diff --git a/ash/public/cpp/ash_pref_names.h b/ash/public/cpp/ash_pref_names.h
index 5e142f7..69cc8e7 100644
--- a/ash/public/cpp/ash_pref_names.h
+++ b/ash/public/cpp/ash_pref_names.h
@@ -26,6 +26,7 @@
 ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickEventType[];
 ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickRevertToLeftClick[];
 ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickMovementThreshold[];
+ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickMenuPosition[];
 ASH_PUBLIC_EXPORT extern const char kAccessibilityCaretHighlightEnabled[];
 ASH_PUBLIC_EXPORT extern const char kAccessibilityCursorHighlightEnabled[];
 ASH_PUBLIC_EXPORT extern const char kAccessibilityFocusHighlightEnabled[];
diff --git a/ash/public/interfaces/accessibility_controller_enums.mojom b/ash/public/interfaces/accessibility_controller_enums.mojom
index 696c7a9..6acf46a 100644
--- a/ash/public/interfaces/accessibility_controller_enums.mojom
+++ b/ash/public/interfaces/accessibility_controller_enums.mojom
@@ -78,11 +78,10 @@
   kSelectToSpeakStateSpeaking,
 };
 
-// The type of mouse event the dwell control feature should perform when
+// The type of mouse event the Automatic Clicks feature should perform when
 // dwelling. These values are written to prefs and correspond to
 // AutoclickActionType in enums.xml, so should not be changed. New values
 // should be added at the end.
-[Extensible]
 enum AutoclickEventType {
   // Perform a left click.
   kLeftClick,
@@ -102,3 +101,20 @@
 
   // TODO(katie): Add scroll.
 };
+
+// The Automatic Clicks feature's on-screen menu display location. These values
+// are written to prefs so they should not be changed. New values should be
+// added at the end.
+enum AutoclickMenuPosition {
+  // The bottom right of the screen.
+  kBottomRight,
+
+  // The bottom left of the screen.
+  kBottomLeft,
+
+  // The top left of the screen.
+  kTopLeft,
+
+  // The top right of the screen.
+  kTopRight,
+};
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index f391461..0a449d9 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -296,6 +296,10 @@
       ash::prefs::kAccessibilityAutoclickMovementThreshold,
       ash::kDefaultAutoclickMovementThreshold,
       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
+  registry->RegisterIntegerPref(
+      ash::prefs::kAccessibilityAutoclickMenuPosition,
+      static_cast<int>(ash::kDefaultAutoclickMenuPosition),
+      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
   registry->RegisterBooleanPref(
       ash::prefs::kAccessibilityVirtualKeyboardEnabled, false,
       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);