Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c0cf178 authored by Riddle Hsu's avatar Riddle Hsu Committed by Automerger Merge Worker
Browse files

Merge "Check visibility for consecutive launch while device is sleeping" into...

Merge "Check visibility for consecutive launch while device is sleeping" into sc-v2-dev am: 6da7b677

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15435679

Change-Id: Ida14198ed1186cc0ce1ebb0b694dbbbeea6c5fbb
parents 6ca71255 6da7b677
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -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.
     *
+34 −7
Original line number Diff line number Diff line
@@ -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