Intercept nudges while HUN is focused

Bug: 171507183
Test: build, manual
Change-Id: I6c6609476de9ed9248abd95303b846b2734eba49
diff --git a/src/com/android/car/rotary/Navigator.java b/src/com/android/car/rotary/Navigator.java
index c4e44c1..f1c10e9 100644
--- a/src/com/android/car/rotary/Navigator.java
+++ b/src/com/android/car/rotary/Navigator.java
@@ -382,7 +382,7 @@
      * HUN appears at the top or bottom of the screen and on the height of the notification being
      * displayed so they aren't used.
      */
-    private boolean isHunWindow(@NonNull AccessibilityWindowInfo window) {
+    boolean isHunWindow(@NonNull AccessibilityWindowInfo window) {
         if (window.getType() != AccessibilityWindowInfo.TYPE_SYSTEM) {
             return false;
         }
diff --git a/src/com/android/car/rotary/RotaryService.java b/src/com/android/car/rotary/RotaryService.java
index 475fb9f..deee6f8 100644
--- a/src/com/android/car/rotary/RotaryService.java
+++ b/src/com/android/car/rotary/RotaryService.java
@@ -227,6 +227,14 @@
     private int mHunNudgeDirection;
 
     /**
+     * The direction to escape the HUN. If the focused node is inside the HUN, nudging to this
+     * direction will move focus to a node outside the HUN, while nudging to other directions
+     * will do nothing.
+     */
+    @View.FocusRealDirection
+    private int mHunEscapeNudgeDirection;
+
+    /**
      * Possible actions to do after receiving {@link AccessibilityEvent#TYPE_VIEW_SCROLLED}.
      *
      * @see #injectScrollEvent
@@ -344,6 +352,7 @@
         int hunRight = displayWidth - hunMarginHorizontal;
         boolean showHunOnBottom = res.getBoolean(R.bool.config_showHeadsUpNotificationOnBottom);
         mHunNudgeDirection = showHunOnBottom ? View.FOCUS_DOWN : View.FOCUS_UP;
+        mHunEscapeNudgeDirection = showHunOnBottom ? View.FOCUS_UP : View.FOCUS_DOWN;
 
         mIgnoreViewClickedMs = res.getInteger(R.integer.ignore_view_clicked_ms);
         mAfterScrollTimeoutMs = res.getInteger(R.integer.after_scroll_timeout_ms);
@@ -1043,6 +1052,14 @@
             return;
         }
 
+        // If the HUN is currently focused, we should only handle nudge events that are in the
+        // opposite direction of the HUN nudge direction.
+        if (mNavigator.isHunWindow(mFocusedNode.getWindow())
+                && direction != mHunEscapeNudgeDirection) {
+            Utils.recycleWindows(windows);
+            return;
+        }
+
         // If the focused node is not in direct manipulation mode, try to move the focus to another
         // node.
         boolean success = nudgeTo(windows, direction);