Merge "Avoid canceling WaitInfo by trampoline activity" into sc-v2-dev am: d87aebcacd

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

Change-Id: I540adf12db9d9fe75b90d7f98e6a106c44b15268
This commit is contained in:
Riddle Hsu
2021-08-16 02:32:17 +00:00
committed by Automerger Merge Worker
4 changed files with 23 additions and 9 deletions

View File

@@ -187,6 +187,10 @@ class ActivityMetricsLogger {
return mAssociatedTransitionInfo != null && mAssociatedTransitionInfo.allDrawn(); return mAssociatedTransitionInfo != null && mAssociatedTransitionInfo.allDrawn();
} }
boolean hasActiveTransitionInfo() {
return mAssociatedTransitionInfo != null;
}
boolean contains(ActivityRecord r) { boolean contains(ActivityRecord r) {
return mAssociatedTransitionInfo != null && mAssociatedTransitionInfo.contains(r); return mAssociatedTransitionInfo != null && mAssociatedTransitionInfo.contains(r);
} }
@@ -336,10 +340,11 @@ class ActivityMetricsLogger {
} }
/** Only keep the records which can be drawn. */ /** Only keep the records which can be drawn. */
void updatePendingDraw() { void updatePendingDraw(boolean keepInitializing) {
for (int i = mPendingDrawActivities.size() - 1; i >= 0; i--) { for (int i = mPendingDrawActivities.size() - 1; i >= 0; i--) {
final ActivityRecord r = mPendingDrawActivities.get(i); final ActivityRecord r = mPendingDrawActivities.get(i);
if (!r.mVisibleRequested) { if (!r.mVisibleRequested
&& !(keepInitializing && r.isState(ActivityRecord.State.INITIALIZING))) {
if (DEBUG_METRICS) Slog.i(TAG, "Discard pending draw " + r); if (DEBUG_METRICS) Slog.i(TAG, "Discard pending draw " + r);
mPendingDrawActivities.remove(i); mPendingDrawActivities.remove(i);
} }
@@ -663,7 +668,7 @@ class ActivityMetricsLogger {
// visible such as after the top task is finished. // visible such as after the top task is finished.
for (int i = mTransitionInfoList.size() - 2; i >= 0; i--) { for (int i = mTransitionInfoList.size() - 2; i >= 0; i--) {
final TransitionInfo prevInfo = mTransitionInfoList.get(i); final TransitionInfo prevInfo = mTransitionInfoList.get(i);
prevInfo.updatePendingDraw(); prevInfo.updatePendingDraw(false /* keepInitializing */);
if (prevInfo.allDrawn()) { if (prevInfo.allDrawn()) {
abort(prevInfo, "nothing will be drawn"); abort(prevInfo, "nothing will be drawn");
} }
@@ -749,7 +754,9 @@ class ActivityMetricsLogger {
info.mCurrentTransitionDelayMs = info.calculateDelay(timestampNs); info.mCurrentTransitionDelayMs = info.calculateDelay(timestampNs);
info.mReason = activityToReason.valueAt(index); info.mReason = activityToReason.valueAt(index);
info.mLoggedTransitionStarting = true; info.mLoggedTransitionStarting = true;
info.updatePendingDraw(); // Do not remove activity in initializing state because the transition may be started
// by starting window. The initializing activity may be requested to visible soon.
info.updatePendingDraw(true /* keepInitializing */);
if (info.allDrawn()) { if (info.allDrawn()) {
done(false /* abort */, info, "notifyTransitionStarting - all windows drawn", done(false /* abort */, info, "notifyTransitionStarting - all windows drawn",
timestampNs); timestampNs);

View File

@@ -2596,7 +2596,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
} }
boolean matches(ActivityRecord r) { boolean matches(ActivityRecord r) {
return mTargetComponent.equals(r.mActivityComponent) || mLaunchingState.contains(r); if (!mLaunchingState.hasActiveTransitionInfo()) {
return mTargetComponent.equals(r.mActivityComponent);
}
return mLaunchingState.contains(r);
} }
void dump(PrintWriter pw, String prefix) { void dump(PrintWriter pw, String prefix) {

View File

@@ -404,6 +404,7 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
// Another round without setting visibility of the trampoline activity. // Another round without setting visibility of the trampoline activity.
onActivityLaunchedTrampoline(); onActivityLaunchedTrampoline();
mTrampolineActivity.setState(ActivityRecord.State.PAUSING, "test");
notifyWindowsDrawn(mTopActivity); notifyWindowsDrawn(mTopActivity);
// If the transition can start, the invisible activities should be discarded and the launch // If the transition can start, the invisible activities should be discarded and the launch
// event be reported successfully. // event be reported successfully.

View File

@@ -49,6 +49,7 @@ import androidx.test.filters.MediumTest;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -108,16 +109,18 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase {
final ActivityMetricsLogger.LaunchingState launchingState = final ActivityMetricsLogger.LaunchingState launchingState =
new ActivityMetricsLogger.LaunchingState(); new ActivityMetricsLogger.LaunchingState();
spyOn(launchingState); spyOn(launchingState);
doReturn(true).when(launchingState).contains(eq(secondActivity)); doReturn(true).when(launchingState).hasActiveTransitionInfo();
doReturn(true).when(launchingState).contains(
ArgumentMatchers.argThat(r -> r == firstActivity || r == secondActivity));
// The test case already runs inside global lock, so above thread can only execute after // The test case already runs inside global lock, so above thread can only execute after
// this waiting method that releases the lock. // this waiting method that releases the lock.
mSupervisor.waitActivityVisibleOrLaunched(taskToFrontWait, firstActivity, launchingState); mSupervisor.waitActivityVisibleOrLaunched(taskToFrontWait, firstActivity, launchingState);
// Assert that the thread is finished. // Assert that the thread is finished.
assertTrue(condition.block(TIMEOUT_MS)); assertTrue(condition.block(TIMEOUT_MS));
assertEquals(taskToFrontWait.result, START_TASK_TO_FRONT); assertEquals(START_TASK_TO_FRONT, taskToFrontWait.result);
assertEquals(taskToFrontWait.who, secondActivity.mActivityComponent); assertEquals(secondActivity.mActivityComponent, taskToFrontWait.who);
assertEquals(taskToFrontWait.launchState, WaitResult.LAUNCH_STATE_HOT); assertEquals(WaitResult.LAUNCH_STATE_HOT, taskToFrontWait.launchState);
// START_TASK_TO_FRONT means that another component will be visible, so the component // START_TASK_TO_FRONT means that another component will be visible, so the component
// should not be assigned as the first activity. // should not be assigned as the first activity.
assertNull(launchedComponent[0]); assertNull(launchedComponent[0]);