Save one-way nudge history only

Fixes: 169805720
Test: atest com.android.car.ui.FocusAreaTest
Change-Id: I0feeb93147f5eb21b698dcc733e5f0ccbda465a3
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
index 810e65a..b0e7c88 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/FocusAreaTest.java
@@ -229,6 +229,12 @@
             arguments.putInt(NUDGE_DIRECTION, FOCUS_UP);
             mFocusArea2.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
             assertThat(mButton1.isFocused()).isTrue();
+
+            // Nudge back. It should fail and the focus should stay the same because of one-way
+            // nudge history.
+            arguments.putInt(NUDGE_DIRECTION, FOCUS_DOWN);
+            mFocusArea1.performAccessibilityAction(ACTION_NUDGE_TO_ANOTHER_FOCUS_AREA, arguments);
+            assertThat(mButton1.isFocused()).isTrue();
         });
     }
 
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
index fe578ce..b380e35 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
@@ -574,9 +574,6 @@
             success = targetFocusArea != null && targetFocusArea.focusOnDescendant();
         }
 
-        if (success) {
-            saveFocusAreaHistory(direction, this, targetFocusArea, elapsedRealtime);
-        }
         return success;
     }
 
@@ -586,14 +583,15 @@
                 : arguments.getInt(NUDGE_DIRECTION, INVALID_DIRECTION);
     }
 
-    /** Saves bidirectional FocusArea nudge history. */
     private void saveFocusAreaHistory(int direction, @NonNull FocusArea sourceFocusArea,
             @NonNull FocusArea targetFocusArea, long elapsedRealtime) {
-        sourceFocusArea.mRotaryCache.saveFocusArea(direction, targetFocusArea, elapsedRealtime);
-
-        int oppositeDirection = getOppositeDirection(direction);
-        targetFocusArea.mRotaryCache.saveFocusArea(oppositeDirection, sourceFocusArea,
-                elapsedRealtime);
+        // Save one-way rather than two-way nudge history to avoid infinite nudge loop.
+        if (sourceFocusArea.mRotaryCache.getCachedFocusArea(direction, elapsedRealtime) == null) {
+            // Save reversed nudge history so that the users can nudge back to where they were.
+            int oppositeDirection = getOppositeDirection(direction);
+            targetFocusArea.mRotaryCache.saveFocusArea(oppositeDirection, sourceFocusArea,
+                    elapsedRealtime);
+        }
     }
 
     /** Returns the direction opposite the given {@code direction} */