Handle intermediate task overlay for metrics logger
The corner case is introduced by intercepting trampoline
activity launch with launching task overlay.
E.g. trampoline -> permission prompt -> main -> permission prompt
Because the prompt is overlay, there may not have visibility
change. The first prompt may be cancelled by consecutive launch
too earlier. And the second prompt which finishes immediately
may miss to cancel.
Bug: 222576471
Test: ActivityMetricsLaunchObserverTests# \
testOnActivityLaunchCancelled_finishedBeforeDrawn
Change-Id: Ife39b7238169a1d54f3d60d1655868cc3cb73f25
This commit is contained in:
@@ -657,7 +657,7 @@ class ActivityMetricsLogger {
|
||||
for (int i = mTransitionInfoList.size() - 2; i >= 0; i--) {
|
||||
final TransitionInfo prevInfo = mTransitionInfoList.get(i);
|
||||
if (prevInfo.mIsDrawn || !prevInfo.mLastLaunchedActivity.mVisibleRequested) {
|
||||
abort(prevInfo, "nothing will be drawn");
|
||||
scheduleCheckActivityToBeDrawn(prevInfo.mLastLaunchedActivity, 0 /* delay */);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -757,6 +757,10 @@ class ActivityMetricsLogger {
|
||||
/** Makes sure that the reference to the removed activity is cleared. */
|
||||
void notifyActivityRemoved(@NonNull ActivityRecord r) {
|
||||
mLastTransitionInfo.remove(r);
|
||||
final TransitionInfo info = getActiveTransitionInfo(r);
|
||||
if (info != null) {
|
||||
abort(info, "removed");
|
||||
}
|
||||
|
||||
final int packageUid = r.info.applicationInfo.uid;
|
||||
final PackageCompatStateInfo compatStateInfo = mPackageUidToCompatStateInfo.get(packageUid);
|
||||
|
||||
@@ -256,6 +256,14 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
|
||||
mActivityMetricsLogger.notifyVisibilityChanged(noDrawnActivity);
|
||||
|
||||
verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(noDrawnActivity));
|
||||
|
||||
// If an activity is removed immediately before visibility update, it should cancel too.
|
||||
final ActivityRecord removedImm = new ActivityBuilder(mAtm).setCreateTask(true).build();
|
||||
clearInvocations(mLaunchObserver);
|
||||
onActivityLaunched(removedImm);
|
||||
removedImm.removeImmediately();
|
||||
// Verify any() instead of proto because the field of record may be changed.
|
||||
verifyAsync(mLaunchObserver).onActivityLaunchCancelled(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -299,15 +307,16 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
|
||||
@Test
|
||||
public void testOnReportFullyDrawn() {
|
||||
// Create an invisible event that should be cancelled after the next event starts.
|
||||
onActivityLaunched(mTrampolineActivity);
|
||||
mTrampolineActivity.mVisibleRequested = false;
|
||||
final ActivityRecord prev = new ActivityBuilder(mAtm).setCreateTask(true).build();
|
||||
onActivityLaunched(prev);
|
||||
prev.mVisibleRequested = false;
|
||||
|
||||
mActivityOptions = ActivityOptions.makeBasic();
|
||||
mActivityOptions.setSourceInfo(SourceInfo.TYPE_LAUNCHER, SystemClock.uptimeMillis() - 10);
|
||||
onIntentStarted(mTopActivity.intent);
|
||||
notifyActivityLaunched(START_SUCCESS, mTopActivity);
|
||||
verifyAsync(mLaunchObserver).onActivityLaunched(eqProto(mTopActivity), anyInt());
|
||||
verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(mTrampolineActivity));
|
||||
verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(prev));
|
||||
|
||||
// The activity reports fully drawn before windows drawn, then the fully drawn event will
|
||||
// be pending (see {@link WindowingModeTransitionInfo#pendingFullyDrawn}).
|
||||
|
||||
Reference in New Issue
Block a user