Fix performance issue caused by triggering hover focus animation accidentally
HoverAnimator and FocusAnimator are triggered unexpectedly on state transition. When it is already disabled, it is disabled again when user swipes to All Apps and triggers animators. Add checking to not trigger animator when the new enable status is the same as the current one.
Bug: 333688227
Test: Ran v2/android-crystalball-eng/health/microbench/systemui/main/systemui-misc-1-jank-suite in ab/
Flag: N/A
Change-Id: I090490f1c78a3427225c24bc536e1767700ec6c3
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index b8afd9d..c3efc3c 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -34,7 +34,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Flags;
import com.android.launcher3.R;
-import com.android.launcher3.statemanager.StatefulActivity;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
import com.android.quickstep.util.BorderAnimator;
@@ -136,6 +135,10 @@
* Enable or disable showing border on focus change
*/
public void setBorderEnabled(boolean enabled) {
+ if (mBorderEnabled == enabled) {
+ return;
+ }
+
mBorderEnabled = enabled;
if (mFocusBorderAnimator != null) {
mFocusBorderAnimator.setBorderVisibility(/* visible= */
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index c90e789..158c15d 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -583,6 +583,10 @@
* Enable or disable showing border on hover and focus change
*/
public void setBorderEnabled(boolean enabled) {
+ if (mBorderEnabled == enabled) {
+ return;
+ }
+
mBorderEnabled = enabled;
// Set the animation correctly in case it misses the hover/focus event during state
// transition
diff --git a/quickstep/tests/src/com/android/quickstep/TaskViewTest.java b/quickstep/tests/src/com/android/quickstep/TaskViewTest.java
index 8eec903..512557b 100644
--- a/quickstep/tests/src/com/android/quickstep/TaskViewTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaskViewTest.java
@@ -17,9 +17,11 @@
package com.android.quickstep;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -34,7 +36,6 @@
import androidx.test.filters.SmallTest;
-import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.quickstep.util.BorderAnimator;
import com.android.quickstep.views.TaskView;
@@ -74,6 +75,7 @@
@Test
public void notShowBorderOnBorderDisabled() {
+ presetBorderStatus(/* enabled= */ true);
mTaskView.setBorderEnabled(/* enabled= */ false);
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_ENTER, 0.0f, 0.0f, 0);
mTaskView.onHoverEvent(MotionEvent.obtain(event));
@@ -86,7 +88,7 @@
}
@Test
- public void showBorderOnBorderEnabled() {
+ public void showBorderOnHoverEvent() {
mTaskView.setBorderEnabled(/* enabled= */ true);
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_ENTER, 0.0f, 0.0f, 0);
mTaskView.onHoverEvent(MotionEvent.obtain(event));
@@ -98,7 +100,18 @@
}
@Test
+ public void showBorderOnBorderEnabled() {
+ presetBorderStatus(/* enabled= */ false);
+ mTaskView.setBorderEnabled(/* enabled= */ true);
+ verify(mHoverAnimator, times(1)).setBorderVisibility(/* visible= */ true, /* animated= */
+ true);
+ verify(mFocusAnimator, times(1)).setBorderVisibility(/* visible= */ true, /* animated= */
+ true);
+ }
+
+ @Test
public void hideBorderOnBorderDisabled() {
+ presetBorderStatus(/* enabled= */ true);
mTaskView.setBorderEnabled(/* enabled= */ false);
verify(mHoverAnimator, times(1)).setBorderVisibility(/* visible= */ false, /* animated= */
true);
@@ -107,13 +120,35 @@
}
@Test
+ public void notTriggerAnimatorWhenEnableStatusUnchanged() {
+ presetBorderStatus(/* enabled= */ false);
+ // Border is disabled by default, no animator is triggered after it is disabled again
+ mTaskView.setBorderEnabled(/* enabled= */ false);
+ verify(mHoverAnimator, never()).setBorderVisibility(/* visible= */
+ anyBoolean(), /* animated= */ anyBoolean());
+ verify(mFocusAnimator, never()).setBorderVisibility(/* visible= */
+ anyBoolean(), /* animated= */ anyBoolean());
+ }
+
+ private void presetBorderStatus(boolean enabled) {
+ // Make the task view focused and hovered
+ MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_ENTER, 0.0f, 0.0f, 0);
+ mTaskView.onHoverEvent(MotionEvent.obtain(event));
+ mTaskView.requestFocus();
+ mTaskView.setBorderEnabled(/* enabled= */ enabled);
+ // Reset invocation count after presetting status
+ reset(mHoverAnimator);
+ reset(mFocusAnimator);
+ }
+
+ @Test
public void notShowBorderByDefault() {
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_ENTER, 0.0f, 0.0f, 0);
mTaskView.onHoverEvent(MotionEvent.obtain(event));
- verify(mHoverAnimator, never()).setBorderVisibility(/* visible= */ false, /* animated= */
- true);
+ verify(mHoverAnimator, never()).setBorderVisibility(/* visible= */
+ anyBoolean(), /* animated= */ anyBoolean());
mTaskView.onFocusChanged(true, 0, new Rect());
- verify(mHoverAnimator, never()).setBorderVisibility(/* visible= */ false, /* animated= */
- true);
+ verify(mHoverAnimator, never()).setBorderVisibility(/* visible= */
+ anyBoolean(), /* animated= */ anyBoolean());
}
}