From 5012640ab2123416e6d10777bc014097f1d0e5ac Mon Sep 17 00:00:00 2001 From: helencheuk Date: Mon, 16 Sep 2024 16:24:37 +0100 Subject: [PATCH] [Contextual Edu] Update Edu stats when going to overview and all apps from home Update education stats when - go overview and all apps by swiping up at homepage (AbstractStateChangeTouchController) - go home from all apps by swiping down the all apps panel (AbstractStateChangeTouchController) - go home from all apps or overview by swiping up from the bottom nav bar (NavBarToHomeTouchController) - in 3 button navgiation mode (TaskbarNavButtonController) NavBarToHomeTouchController does not inherit from AbstractStateChangeTouchController so logic are added separately. Bug: 363480554 Test: TaskbarNavButtonControllerTest Flag: com.android.systemui.keyboard_touchpad_contextual_education Change-Id: I0662704a9093b9f5a4d2f086a8297429fbc49881 --- .../launcher3/taskbar/TaskbarManager.java | 2 ++ .../taskbar/TaskbarNavButtonController.java | 11 +++++++ .../NavBarToHomeTouchController.java | 4 +++ .../TaskbarNavButtonControllerTest.java | 29 +++++++++++++++++++ .../AbstractStateChangeTouchController.java | 18 ++++++++++++ .../launcher3/touch/BaseSwipeDetector.java | 9 +++++- 6 files changed, 72 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index 1b4db7a5cf..78e7b470ff 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -60,6 +60,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.statehandlers.DesktopVisibilityController; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks; @@ -247,6 +248,7 @@ public class TaskbarManager { context, navCallbacks, SystemUiProxy.INSTANCE.get(mContext), + ContextualEduStatsManager.INSTANCE.get(mContext), new Handler(), AssistUtils.newInstance(mContext)); mComponentCallbacks = new ComponentCallbacks() { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java index 872a4d087b..15c35b644e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java @@ -45,12 +45,14 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import com.android.launcher3.R; +import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskUtils; import com.android.quickstep.util.AssistUtils; +import com.android.systemui.contextualeducation.GestureType; import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; import java.io.PrintWriter; @@ -109,6 +111,7 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa private final Context mContext; private final TaskbarNavButtonCallbacks mCallbacks; private final SystemUiProxy mSystemUiProxy; + private final ContextualEduStatsManager mContextualEduStatsManager; private final Handler mHandler; private final AssistUtils mAssistUtils; @Nullable private StatsLogManager mStatsLogManager; @@ -119,11 +122,13 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa Context context, TaskbarNavButtonCallbacks callbacks, SystemUiProxy systemUiProxy, + ContextualEduStatsManager contextualEduStatsManager, Handler handler, AssistUtils assistUtils) { mContext = context; mCallbacks = callbacks; mSystemUiProxy = systemUiProxy; + mContextualEduStatsManager = contextualEduStatsManager; mHandler = handler; mAssistUtils = assistUtils; } @@ -137,14 +142,20 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa switch (buttonType) { case BUTTON_BACK: logEvent(LAUNCHER_TASKBAR_BACK_BUTTON_TAP); + mContextualEduStatsManager.updateEduStats(/* isTrackpadGesture= */ false, + GestureType.BACK); executeBack(); break; case BUTTON_HOME: logEvent(LAUNCHER_TASKBAR_HOME_BUTTON_TAP); + mContextualEduStatsManager.updateEduStats(/* isTrackpadGesture= */ false, + GestureType.HOME); navigateHome(); break; case BUTTON_RECENTS: logEvent(LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP); + mContextualEduStatsManager.updateEduStats(/* isTrackpadGesture= */ false, + GestureType.OVERVIEW); navigateToOverview(); break; case BUTTON_IME_SWITCH: diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 11e0ed528c..1d9e49201d 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -45,6 +45,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.touch.SingleAxisSwipeDetector; import com.android.launcher3.util.DisplayController; @@ -53,6 +54,7 @@ import com.android.quickstep.TaskUtils; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.OverviewToHomeAnim; import com.android.quickstep.views.RecentsView; +import com.android.systemui.contextualeducation.GestureType; import java.util.function.BiConsumer; @@ -219,6 +221,8 @@ public class NavBarToHomeTouchController implements TouchController, } if (mStartState != mEndState) { logHomeGesture(); + ContextualEduStatsManager.INSTANCE.get(mLauncher).updateEduStats( + mSwipeDetector.isTrackpadGesture(), GestureType.HOME); } AbstractFloatingView topOpenView = AbstractFloatingView.getTopOpenView(mLauncher); if (topOpenView != null) { diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java index 399aea612d..02d62186b1 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -33,11 +34,13 @@ import android.view.inputmethod.Flags; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; +import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TouchInteractionService; import com.android.quickstep.util.AssistUtils; +import com.android.systemui.contextualeducation.GestureType; import org.junit.Before; import org.junit.Test; @@ -52,6 +55,10 @@ public class TaskbarNavButtonControllerTest { @Mock SystemUiProxy mockSystemUiProxy; + + @Mock + ContextualEduStatsManager mockContextualEduStatsManager; + @Mock TouchInteractionService mockService; @Mock @@ -100,6 +107,7 @@ public class TaskbarNavButtonControllerTest { mockService, mCallbacks, mockSystemUiProxy, + mockContextualEduStatsManager, mockHandler, mockAssistUtils); } @@ -110,6 +118,13 @@ public class TaskbarNavButtonControllerTest { verify(mockSystemUiProxy, times(1)).onBackPressed(); } + @Test + public void testPressBack_updateContextualEduData() { + mNavButtonController.onButtonClick(BUTTON_BACK, mockView); + verify(mockContextualEduStatsManager, times(1)) + .updateEduStats(/* isTrackpad= */ eq(false), eq(GestureType.BACK)); + } + @Test public void testPressImeSwitcher() { mNavButtonController.init(mockTaskbarControllers); @@ -194,12 +209,26 @@ public class TaskbarNavButtonControllerTest { assertThat(mHomePressCount).isEqualTo(1); } + @Test + public void testPressHome_updateContextualEduData() { + mNavButtonController.onButtonClick(BUTTON_HOME, mockView); + verify(mockContextualEduStatsManager, times(1)) + .updateEduStats(/* isTrackpad= */ eq(false), eq(GestureType.HOME)); + } + @Test public void testPressRecents() { mNavButtonController.onButtonClick(BUTTON_RECENTS, mockView); assertThat(mOverviewToggleCount).isEqualTo(1); } + @Test + public void testPressRecents_updateContextualEduData() { + mNavButtonController.onButtonClick(BUTTON_RECENTS, mockView); + verify(mockContextualEduStatsManager, times(1)) + .updateEduStats(/* isTrackpad= */ eq(false), eq(GestureType.OVERVIEW)); + } + @Test public void testPressRecentsWithScreenPinned_noNavigationToOverview() { mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING); diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 3817563b0b..efd1f0d6b4 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -40,11 +40,13 @@ import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherState; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.util.FlingBlockCheck; import com.android.launcher3.util.TouchController; +import com.android.systemui.contextualeducation.GestureType; /** * TouchController for handling state changes @@ -388,6 +390,7 @@ public abstract class AbstractStateChangeTouchController } else { logReachedState(mToState); } + updateContextualEduStats(targetState); } protected void goToTargetState(LauncherState targetState) { @@ -403,6 +406,21 @@ public abstract class AbstractStateChangeTouchController .setDuration(0).start(); } + private void updateContextualEduStats(LauncherState targetState) { + if (targetState == NORMAL) { + ContextualEduStatsManager.INSTANCE.get( + mLauncher).updateEduStats(mDetector.isTrackpadGesture(), GestureType.HOME); + } else if (targetState == OVERVIEW) { + ContextualEduStatsManager.INSTANCE.get( + mLauncher).updateEduStats(mDetector.isTrackpadGesture(), GestureType.OVERVIEW); + } else if (targetState == ALL_APPS && !mDetector.isTrackpadGesture()) { + // Only update if it is touch gesture as trackpad gesture is not relevant for all apps + // which only provides keyboard education. + ContextualEduStatsManager.INSTANCE.get( + mLauncher).updateEduStats(/* isTrackpadGesture= */ false, GestureType.ALL_APPS); + } + } + private void logReachedState(LauncherState targetState) { if (mStartState == targetState) { return; diff --git a/src/com/android/launcher3/touch/BaseSwipeDetector.java b/src/com/android/launcher3/touch/BaseSwipeDetector.java index 52c358143a..faac4a3eb6 100644 --- a/src/com/android/launcher3/touch/BaseSwipeDetector.java +++ b/src/com/android/launcher3/touch/BaseSwipeDetector.java @@ -17,6 +17,8 @@ package com.android.launcher3.touch; import static android.view.MotionEvent.INVALID_POINTER_ID; +import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent; + import android.content.Context; import android.graphics.PointF; import android.util.Log; @@ -64,6 +66,7 @@ public abstract class BaseSwipeDetector { protected PointF mSubtractDisplacement = new PointF(); @VisibleForTesting ScrollState mState = ScrollState.IDLE; private boolean mIsSettingState; + protected boolean mIsTrackpadGesture; protected boolean mIgnoreSlopWhenSettling; protected Context mContext; @@ -122,6 +125,10 @@ public abstract class BaseSwipeDetector { return mState == ScrollState.DRAGGING || mState == ScrollState.SETTLING; } + public boolean isTrackpadGesture() { + return mIsTrackpadGesture; + } + public void finishedScrolling() { setState(ScrollState.IDLE); } @@ -147,7 +154,7 @@ public abstract class BaseSwipeDetector { mLastPos.set(mDownPos); mLastDisplacement.set(0, 0); mDisplacement.set(0, 0); - + mIsTrackpadGesture = isTrackpadMotionEvent(ev); if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) { setState(ScrollState.DRAGGING); }