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

Commit 7673f3f8 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Check null before getting task bounds

The task bounds was used to decide whether multiple launches can
be combined into one event for tracking launch time.

With below sample:
startActivities(new Intent[] {
    new Intent(c, Activity1.class),
    new Intent(c, Activity2.class).setFlags(
        Intent.FLAG_ACTIVITY_CLEAR_TASK
        | Intent.FLAG_ACTIVITY_NEW_TASK) });

When launching Activity2, because Activity1 hasn't real started,
Activity1 will be removed from task directly. Then its task will
be null, that causes mLastLaunchedActivity.getTask() to be null.

If the task is not available, check if the launched activity has
the same uid as the caller uid.

Fix: 276513946
Test: atest ActivityMetricsLaunchObserverTests#testConsecutiveLaunch

Change-Id: I731f0446b62b666b22ba1a6b37364d95efd0a32c
parent b4a8a82f
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -397,9 +397,21 @@ class ActivityMetricsLogger {

        /** Returns {@code true} if the incoming activity can belong to this transition. */
        boolean canCoalesce(ActivityRecord r) {
            return mLastLaunchedActivity.mDisplayContent == r.mDisplayContent
                    && mLastLaunchedActivity.getTask().getBounds().equals(r.getTask().getBounds())
                    && mLastLaunchedActivity.getWindowingMode() == r.getWindowingMode();
            if (mLastLaunchedActivity.mDisplayContent != r.mDisplayContent
                    || mLastLaunchedActivity.getWindowingMode() != r.getWindowingMode()) {
                return false;
            }
            // The current task should be non-null because it is just launched. While the
            // last task can be cleared when starting activity with FLAG_ACTIVITY_CLEAR_TASK.
            final Task lastTask = mLastLaunchedActivity.getTask();
            final Task currentTask = r.getTask();
            if (lastTask != null && currentTask != null) {
                if (lastTask == currentTask) {
                    return true;
                }
                return lastTask.getBounds().equals(currentTask.getBounds());
            }
            return mLastLaunchedActivity.isUid(r.launchedFromUid);
        }

        /** @return {@code true} if the activity matches a launched activity in this transition. */
+7 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMor

import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
@@ -501,6 +502,12 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
        onActivityLaunched(mTrampolineActivity);
        mActivityMetricsLogger.notifyActivityLaunching(mTopActivity.intent,
                mTrampolineActivity /* caller */, mTrampolineActivity.getUid());

        // Simulate a corner case that the trampoline activity is removed by CLEAR_TASK.
        // The 2 launch events can still be coalesced to one by matching the uid.
        mTrampolineActivity.takeFromHistory();
        assertNull(mTrampolineActivity.getTask());

        notifyActivityLaunched(START_SUCCESS, mTopActivity);
        transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
    }