Merge "Check visibility for consecutive launch while device is sleeping" into sc-v2-dev am: 6da7b677c8 am: 0c0cf1787f
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15435679 Change-Id: I0aac44e7e82b7985323308eac150c792f62140f2
This commit is contained in:
@@ -633,6 +633,7 @@ class ActivityMetricsLogger {
|
||||
if (crossPackage) {
|
||||
startLaunchTrace(info);
|
||||
}
|
||||
scheduleCheckActivityToBeDrawnIfSleeping(launchedActivity);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -654,13 +655,7 @@ class ActivityMetricsLogger {
|
||||
// As abort for no process switch.
|
||||
launchObserverNotifyIntentFailed();
|
||||
}
|
||||
if (launchedActivity.mDisplayContent.isSleeping()) {
|
||||
// It is unknown whether the activity can be drawn or not, e.g. it depends on the
|
||||
// keyguard states and the attributes or flags set by the activity. If the activity
|
||||
// keeps invisible in the grace period, the tracker will be cancelled so it won't get
|
||||
// a very long launch time that takes unlocking as the end of launch.
|
||||
scheduleCheckActivityToBeDrawn(launchedActivity, UNKNOWN_VISIBILITY_CHECK_DELAY_MS);
|
||||
}
|
||||
scheduleCheckActivityToBeDrawnIfSleeping(launchedActivity);
|
||||
|
||||
// If the previous transitions are no longer visible, abort them to avoid counting the
|
||||
// launch time when resuming from back stack. E.g. launch 2 independent tasks in a short
|
||||
@@ -675,6 +670,16 @@ class ActivityMetricsLogger {
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleCheckActivityToBeDrawnIfSleeping(@NonNull ActivityRecord r) {
|
||||
if (r.mDisplayContent.isSleeping()) {
|
||||
// It is unknown whether the activity can be drawn or not, e.g. it depends on the
|
||||
// keyguard states and the attributes or flags set by the activity. If the activity
|
||||
// keeps invisible in the grace period, the tracker will be cancelled so it won't get
|
||||
// a very long launch time that takes unlocking as the end of launch.
|
||||
scheduleCheckActivityToBeDrawn(r, UNKNOWN_VISIBILITY_CHECK_DELAY_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the tracker that all windows of the app have been drawn.
|
||||
*
|
||||
|
||||
@@ -27,6 +27,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMor
|
||||
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
@@ -70,6 +71,7 @@ import java.util.function.ToIntFunction;
|
||||
@Presubmit
|
||||
@RunWith(WindowTestRunner.class)
|
||||
public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
|
||||
private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5);
|
||||
private ActivityMetricsLogger mActivityMetricsLogger;
|
||||
private ActivityMetricsLogger.LaunchingState mLaunchingState;
|
||||
private ActivityMetricsLaunchObserver mLaunchObserver;
|
||||
@@ -137,7 +139,7 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
|
||||
// messages that are waiting for the lock.
|
||||
waitHandlerIdle(mAtm.mH);
|
||||
// AMLO callbacks happen on a separate thread than AML calls, so we need to use a timeout.
|
||||
return verify(mock, timeout(TimeUnit.SECONDS.toMillis(5)));
|
||||
return verify(mock, timeout(TIMEOUT_MS));
|
||||
}
|
||||
|
||||
private void verifyOnActivityLaunchFinished(ActivityRecord activity) {
|
||||
@@ -258,15 +260,40 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testOnActivityLaunchWhileSleeping() {
|
||||
notifyActivityLaunching(mTopActivity.intent);
|
||||
notifyActivityLaunched(START_SUCCESS, mTopActivity);
|
||||
doReturn(true).when(mTopActivity.mDisplayContent).isSleeping();
|
||||
mTopActivity.setState(ActivityRecord.State.RESUMED, "test");
|
||||
mTopActivity.setVisibility(false);
|
||||
notifyActivityLaunching(mTrampolineActivity.intent);
|
||||
notifyActivityLaunched(START_SUCCESS, mTrampolineActivity);
|
||||
doReturn(true).when(mTrampolineActivity.mDisplayContent).isSleeping();
|
||||
mTrampolineActivity.setState(ActivityRecord.State.RESUMED, "test");
|
||||
mTrampolineActivity.setVisibility(false);
|
||||
waitHandlerIdle(mAtm.mH);
|
||||
// Not cancel immediately because in one of real cases, the keyguard may be going away or
|
||||
// occluded later, then the activity can be drawn.
|
||||
verify(mLaunchObserver, never()).onActivityLaunchCancelled(eqProto(mTopActivity));
|
||||
verify(mLaunchObserver, never()).onActivityLaunchCancelled(eqProto(mTrampolineActivity));
|
||||
|
||||
clearInvocations(mLaunchObserver);
|
||||
mLaunchTopByTrampoline = true;
|
||||
mTopActivity.mVisibleRequested = false;
|
||||
notifyActivityLaunching(mTopActivity.intent);
|
||||
// It should schedule a message with UNKNOWN_VISIBILITY_CHECK_DELAY_MS to check whether
|
||||
// the launch event is still valid.
|
||||
notifyActivityLaunched(START_SUCCESS, mTopActivity);
|
||||
|
||||
// The posted message will acquire wm lock, so the test needs to release the lock to verify.
|
||||
final Throwable error = awaitInWmLock(() -> {
|
||||
try {
|
||||
// Though the aborting target should be eqProto(mTopActivity), use any() to avoid
|
||||
// any changes in proto that may cause failure by different arguments.
|
||||
verify(mLaunchObserver, timeout(TIMEOUT_MS)).onActivityLaunchCancelled(any());
|
||||
} catch (Throwable e) {
|
||||
// Catch any errors including assertion because this runs in another thread.
|
||||
return e;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
// The launch event must be cancelled because the activity keeps invisible.
|
||||
if (error != null) {
|
||||
throw new AssertionError(error);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user