Loading core/java/com/android/internal/jank/Cuj.java +7 −3 Original line number Diff line number Diff line Loading @@ -121,10 +121,11 @@ public class Cuj { public static final int CUJ_PREDICTIVE_BACK_CROSS_TASK = 85; public static final int CUJ_PREDICTIVE_BACK_HOME = 86; public static final int CUJ_LAUNCHER_SEARCH_QSB_OPEN = 87; public static final int CUJ_BACK_PANEL_ARROW = 88; // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE. @VisibleForTesting static final int LAST_CUJ = CUJ_LAUNCHER_SEARCH_QSB_OPEN; static final int LAST_CUJ = CUJ_BACK_PANEL_ARROW; /** @hide */ @IntDef({ Loading Loading @@ -207,6 +208,7 @@ public class Cuj { CUJ_PREDICTIVE_BACK_CROSS_TASK, CUJ_PREDICTIVE_BACK_HOME, CUJ_LAUNCHER_SEARCH_QSB_OPEN, CUJ_BACK_PANEL_ARROW, }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { Loading Loading @@ -298,8 +300,8 @@ public class Cuj { CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_ACTIVITY; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_CROSS_TASK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_TASK; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_HOME] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_HOME; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_SEARCH_QSB_OPEN] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_SEARCH_QSB_OPEN; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_SEARCH_QSB_OPEN] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_SEARCH_QSB_OPEN; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_BACK_PANEL_ARROW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BACK_PANEL_ARROW; } private Cuj() { Loading Loading @@ -474,6 +476,8 @@ public class Cuj { return "PREDICTIVE_BACK_HOME"; case CUJ_LAUNCHER_SEARCH_QSB_OPEN: return "LAUNCHER_SEARCH_QSB_OPEN"; case CUJ_BACK_PANEL_ARROW: return "BACK_PANEL_ARROW"; } return "UNKNOWN"; } Loading core/java/com/android/internal/jank/InteractionMonitorDebugOverlay.java +13 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.os.Handler; import android.os.Trace; import android.util.Log; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.WindowCallbacks; Loading @@ -52,6 +53,7 @@ import com.android.internal.jank.FrameTracker.Reasons; * @hide */ class InteractionMonitorDebugOverlay implements WindowCallbacks { private static final String TAG = "InteractionMonitorDebug"; private static final int REASON_STILL_RUNNING = -1000; private final Object mLock; // Sparse array where the key in the CUJ and the value is the session status, or null if Loading @@ -77,7 +79,7 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks { mDebugPaint.setAntiAlias(false); mDebugFontMetrics = new Paint.FontMetrics(); final Context context = ActivityThread.currentApplication(); mPackageName = context.getPackageName(); mPackageName = context == null ? "null" : context.getPackageName(); } @UiThread Loading Loading @@ -153,8 +155,14 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks { SparseArray<InteractionJankMonitor.RunningTracker> runningTrackers) { synchronized (mLock) { mRunningCujs.put(removedCuj, reason); boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG); if (isLoggable) { String cujName = Cuj.getNameOfCuj(removedCuj); Log.d(TAG, cujName + (reason == REASON_END_NORMAL ? " ended" : " cancelled")); } // If REASON_STILL_RUNNING is not in mRunningCujs, then all CUJs have ended if (mRunningCujs.indexOfValue(REASON_STILL_RUNNING) < 0) { if (isLoggable) Log.d(TAG, "All CUJs ended"); mRunningCujs.clear(); dispose(); } else { Loading Loading @@ -186,6 +194,10 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks { @UiThread void onTrackerAdded(@Cuj.CujType int addedCuj, InteractionJankMonitor.RunningTracker tracker) { if (Log.isLoggable(TAG, Log.DEBUG)) { String cujName = Cuj.getNameOfCuj(addedCuj); Log.d(TAG, cujName + " started"); } synchronized (mLock) { // Use REASON_STILL_RUNNING (not technically one of the '@Reasons') to indicate the CUJ // is still running Loading packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt +18 −2 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ import androidx.annotation.VisibleForTesting import androidx.core.os.postDelayed import androidx.core.view.isVisible import androidx.dynamicanimation.animation.DynamicAnimation import com.android.internal.jank.Cuj.CUJ_BACK_PANEL_ARROW import com.android.internal.jank.InteractionJankMonitor import com.android.internal.util.LatencyTracker import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.NavigationEdgeBackPlugin Loading Loading @@ -86,6 +88,7 @@ internal constructor( private val vibratorHelper: VibratorHelper, private val configurationController: ConfigurationController, private val latencyTracker: LatencyTracker, private val interactionJankMonitor: InteractionJankMonitor, ) : ViewController<BackPanel>(BackPanel(context, latencyTracker)), NavigationEdgeBackPlugin { /** Loading @@ -103,6 +106,7 @@ internal constructor( private val vibratorHelper: VibratorHelper, private val configurationController: ConfigurationController, private val latencyTracker: LatencyTracker, private val interactionJankMonitor: InteractionJankMonitor, ) { /** Construct a [BackPanelController]. */ fun create(context: Context): BackPanelController { Loading @@ -115,6 +119,7 @@ internal constructor( vibratorHelper, configurationController, latencyTracker, interactionJankMonitor ) backPanelController.init() return backPanelController Loading Loading @@ -183,7 +188,7 @@ internal constructor( /* Arrow is animating in */ ENTRY, /* could be entry, neutral, or stretched, releasing will commit back */ /* releasing will commit back */ ACTIVE, /* releasing will cancel back */ Loading Loading @@ -366,6 +371,7 @@ internal constructor( // Receiving a CANCEL implies that something else intercepted // the gesture, i.e., the user did not cancel their gesture. // Therefore, disappear immediately, with minimum fanfare. interactionJankMonitor.cancel(CUJ_BACK_PANEL_ARROW) updateArrowState(GestureState.GONE) velocityTracker = null } Loading Loading @@ -813,7 +819,7 @@ internal constructor( scale = when (currentState) { GestureState.ACTIVE, GestureState.FLUNG, -> params.activeIndicator.scale GestureState.FLUNG -> params.activeIndicator.scale GestureState.COMMITTED -> params.committedIndicator.scale else -> params.preThresholdIndicator.scale }, Loading Loading @@ -877,6 +883,16 @@ internal constructor( previousState = currentState currentState = newState // First, update the jank tracker when (currentState) { GestureState.ENTRY -> { interactionJankMonitor.cancel(CUJ_BACK_PANEL_ARROW) interactionJankMonitor.begin(mView, CUJ_BACK_PANEL_ARROW) } GestureState.GONE -> interactionJankMonitor.end(CUJ_BACK_PANEL_ARROW) else -> {} } when (currentState) { GestureState.CANCELLED -> { backCallback.cancelBack() Loading packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt +8 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.view.MotionEvent.ACTION_UP import android.view.ViewConfiguration import android.view.WindowManager import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.util.LatencyTracker import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.NavigationEdgeBackPlugin Loading @@ -40,8 +41,10 @@ import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest Loading @@ -59,12 +62,16 @@ class BackPanelControllerTest : SysuiTestCase() { @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var configurationController: ConfigurationController @Mock private lateinit var latencyTracker: LatencyTracker @Mock private lateinit var interactionJankMonitor: InteractionJankMonitor @Mock private lateinit var layoutParams: WindowManager.LayoutParams @Mock private lateinit var backCallback: NavigationEdgeBackPlugin.BackCallback @Before fun setup() { MockitoAnnotations.initMocks(this) `when`(interactionJankMonitor.begin(any(), anyInt())).thenReturn(true) `when`(interactionJankMonitor.end(anyInt())).thenReturn(true) `when`(interactionJankMonitor.cancel(anyInt())).thenReturn(true) mBackPanelController = BackPanelController( context, Loading @@ -74,6 +81,7 @@ class BackPanelControllerTest : SysuiTestCase() { vibratorHelper, configurationController, latencyTracker, interactionJankMonitor, ) mBackPanelController.setLayoutParams(layoutParams) mBackPanelController.setBackCallback(backCallback) Loading Loading
core/java/com/android/internal/jank/Cuj.java +7 −3 Original line number Diff line number Diff line Loading @@ -121,10 +121,11 @@ public class Cuj { public static final int CUJ_PREDICTIVE_BACK_CROSS_TASK = 85; public static final int CUJ_PREDICTIVE_BACK_HOME = 86; public static final int CUJ_LAUNCHER_SEARCH_QSB_OPEN = 87; public static final int CUJ_BACK_PANEL_ARROW = 88; // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE. @VisibleForTesting static final int LAST_CUJ = CUJ_LAUNCHER_SEARCH_QSB_OPEN; static final int LAST_CUJ = CUJ_BACK_PANEL_ARROW; /** @hide */ @IntDef({ Loading Loading @@ -207,6 +208,7 @@ public class Cuj { CUJ_PREDICTIVE_BACK_CROSS_TASK, CUJ_PREDICTIVE_BACK_HOME, CUJ_LAUNCHER_SEARCH_QSB_OPEN, CUJ_BACK_PANEL_ARROW, }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { Loading Loading @@ -298,8 +300,8 @@ public class Cuj { CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_ACTIVITY; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_CROSS_TASK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_TASK; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_HOME] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_HOME; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_SEARCH_QSB_OPEN] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_SEARCH_QSB_OPEN; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_SEARCH_QSB_OPEN] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_SEARCH_QSB_OPEN; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_BACK_PANEL_ARROW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BACK_PANEL_ARROW; } private Cuj() { Loading Loading @@ -474,6 +476,8 @@ public class Cuj { return "PREDICTIVE_BACK_HOME"; case CUJ_LAUNCHER_SEARCH_QSB_OPEN: return "LAUNCHER_SEARCH_QSB_OPEN"; case CUJ_BACK_PANEL_ARROW: return "BACK_PANEL_ARROW"; } return "UNKNOWN"; } Loading
core/java/com/android/internal/jank/InteractionMonitorDebugOverlay.java +13 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.os.Handler; import android.os.Trace; import android.util.Log; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.WindowCallbacks; Loading @@ -52,6 +53,7 @@ import com.android.internal.jank.FrameTracker.Reasons; * @hide */ class InteractionMonitorDebugOverlay implements WindowCallbacks { private static final String TAG = "InteractionMonitorDebug"; private static final int REASON_STILL_RUNNING = -1000; private final Object mLock; // Sparse array where the key in the CUJ and the value is the session status, or null if Loading @@ -77,7 +79,7 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks { mDebugPaint.setAntiAlias(false); mDebugFontMetrics = new Paint.FontMetrics(); final Context context = ActivityThread.currentApplication(); mPackageName = context.getPackageName(); mPackageName = context == null ? "null" : context.getPackageName(); } @UiThread Loading Loading @@ -153,8 +155,14 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks { SparseArray<InteractionJankMonitor.RunningTracker> runningTrackers) { synchronized (mLock) { mRunningCujs.put(removedCuj, reason); boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG); if (isLoggable) { String cujName = Cuj.getNameOfCuj(removedCuj); Log.d(TAG, cujName + (reason == REASON_END_NORMAL ? " ended" : " cancelled")); } // If REASON_STILL_RUNNING is not in mRunningCujs, then all CUJs have ended if (mRunningCujs.indexOfValue(REASON_STILL_RUNNING) < 0) { if (isLoggable) Log.d(TAG, "All CUJs ended"); mRunningCujs.clear(); dispose(); } else { Loading Loading @@ -186,6 +194,10 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks { @UiThread void onTrackerAdded(@Cuj.CujType int addedCuj, InteractionJankMonitor.RunningTracker tracker) { if (Log.isLoggable(TAG, Log.DEBUG)) { String cujName = Cuj.getNameOfCuj(addedCuj); Log.d(TAG, cujName + " started"); } synchronized (mLock) { // Use REASON_STILL_RUNNING (not technically one of the '@Reasons') to indicate the CUJ // is still running Loading
packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt +18 −2 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ import androidx.annotation.VisibleForTesting import androidx.core.os.postDelayed import androidx.core.view.isVisible import androidx.dynamicanimation.animation.DynamicAnimation import com.android.internal.jank.Cuj.CUJ_BACK_PANEL_ARROW import com.android.internal.jank.InteractionJankMonitor import com.android.internal.util.LatencyTracker import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.NavigationEdgeBackPlugin Loading Loading @@ -86,6 +88,7 @@ internal constructor( private val vibratorHelper: VibratorHelper, private val configurationController: ConfigurationController, private val latencyTracker: LatencyTracker, private val interactionJankMonitor: InteractionJankMonitor, ) : ViewController<BackPanel>(BackPanel(context, latencyTracker)), NavigationEdgeBackPlugin { /** Loading @@ -103,6 +106,7 @@ internal constructor( private val vibratorHelper: VibratorHelper, private val configurationController: ConfigurationController, private val latencyTracker: LatencyTracker, private val interactionJankMonitor: InteractionJankMonitor, ) { /** Construct a [BackPanelController]. */ fun create(context: Context): BackPanelController { Loading @@ -115,6 +119,7 @@ internal constructor( vibratorHelper, configurationController, latencyTracker, interactionJankMonitor ) backPanelController.init() return backPanelController Loading Loading @@ -183,7 +188,7 @@ internal constructor( /* Arrow is animating in */ ENTRY, /* could be entry, neutral, or stretched, releasing will commit back */ /* releasing will commit back */ ACTIVE, /* releasing will cancel back */ Loading Loading @@ -366,6 +371,7 @@ internal constructor( // Receiving a CANCEL implies that something else intercepted // the gesture, i.e., the user did not cancel their gesture. // Therefore, disappear immediately, with minimum fanfare. interactionJankMonitor.cancel(CUJ_BACK_PANEL_ARROW) updateArrowState(GestureState.GONE) velocityTracker = null } Loading Loading @@ -813,7 +819,7 @@ internal constructor( scale = when (currentState) { GestureState.ACTIVE, GestureState.FLUNG, -> params.activeIndicator.scale GestureState.FLUNG -> params.activeIndicator.scale GestureState.COMMITTED -> params.committedIndicator.scale else -> params.preThresholdIndicator.scale }, Loading Loading @@ -877,6 +883,16 @@ internal constructor( previousState = currentState currentState = newState // First, update the jank tracker when (currentState) { GestureState.ENTRY -> { interactionJankMonitor.cancel(CUJ_BACK_PANEL_ARROW) interactionJankMonitor.begin(mView, CUJ_BACK_PANEL_ARROW) } GestureState.GONE -> interactionJankMonitor.end(CUJ_BACK_PANEL_ARROW) else -> {} } when (currentState) { GestureState.CANCELLED -> { backCallback.cancelBack() Loading
packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt +8 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.view.MotionEvent.ACTION_UP import android.view.ViewConfiguration import android.view.WindowManager import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.util.LatencyTracker import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.NavigationEdgeBackPlugin Loading @@ -40,8 +41,10 @@ import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest Loading @@ -59,12 +62,16 @@ class BackPanelControllerTest : SysuiTestCase() { @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var configurationController: ConfigurationController @Mock private lateinit var latencyTracker: LatencyTracker @Mock private lateinit var interactionJankMonitor: InteractionJankMonitor @Mock private lateinit var layoutParams: WindowManager.LayoutParams @Mock private lateinit var backCallback: NavigationEdgeBackPlugin.BackCallback @Before fun setup() { MockitoAnnotations.initMocks(this) `when`(interactionJankMonitor.begin(any(), anyInt())).thenReturn(true) `when`(interactionJankMonitor.end(anyInt())).thenReturn(true) `when`(interactionJankMonitor.cancel(anyInt())).thenReturn(true) mBackPanelController = BackPanelController( context, Loading @@ -74,6 +81,7 @@ class BackPanelControllerTest : SysuiTestCase() { vibratorHelper, configurationController, latencyTracker, interactionJankMonitor, ) mBackPanelController.setLayoutParams(layoutParams) mBackPanelController.setBackCallback(backCallback) Loading