Compute visibilities when finishing activity with a translucent resume activity

When there is a translucent activity in foreground and finishing
a next intermediate activity. Since the visibility of next below
activity was not updated. The black background shown below the
translucent resume activity.

The CL update the visibilities with above condition and add test
case to verify.

Bug: 153927250
Test: atest WmTests:ActivityRecordTests
Change-Id: Ie5fc13872becb48b8bdcd572d710111534424a72
This commit is contained in:
Jeff Chang
2020-04-10 17:23:43 +08:00
parent ea2d4bf1fd
commit de2c5f1358
2 changed files with 63 additions and 10 deletions

View File

@@ -2669,15 +2669,28 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return this;
}
// Ensure activity visibilities and update lockscreen occluded/dismiss state when
// finishing the top activity that occluded keyguard. So that, the
// ActivityStack#mTopActivityOccludesKeyguard can be updated and the activity below won't
// be resumed.
if (isState(PAUSED)
&& mStackSupervisor.getKeyguardController().isKeyguardLocked()
&& getStack().topActivityOccludesKeyguard()) {
getDisplay().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
false /* preserveWindows */, false /* notifyClients */);
final boolean isCurrentVisible = mVisibleRequested || isState(PAUSED);
if (isCurrentVisible) {
final ActivityStack stack = getStack();
final ActivityRecord activity = stack.mResumedActivity;
boolean ensureVisibility = false;
if (activity != null && !activity.occludesParent()) {
// If the resume activity is not opaque, we need to make sure the visibilities of
// activities be updated, they may be seen by users.
ensureVisibility = true;
} else if (mStackSupervisor.getKeyguardController().isKeyguardLocked()
&& stack.topActivityOccludesKeyguard()) {
// Ensure activity visibilities and update lockscreen occluded/dismiss state when
// finishing the top activity that occluded keyguard. So that, the
// ActivityStack#mTopActivityOccludesKeyguard can be updated and the activity below
// won't be resumed.
ensureVisibility = true;
}
if (ensureVisibility) {
getDisplay().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
false /* preserveWindows */, true /* notifyClients */);
}
}
boolean activityRemoved = false;
@@ -2698,7 +2711,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// than destroy immediately.
final boolean isNextNotYetVisible = next != null
&& (!next.nowVisible || !next.mVisibleRequested);
if ((mVisibleRequested || isState(PAUSED)) && isNextNotYetVisible) {
if (isCurrentVisible && isNextNotYetVisible) {
// Add this activity to the list of stopping activities. It will be processed and
// destroyed when the next activity reports idle.
addToStopping(false /* scheduleIdle */, false /* idleDelayed */,

View File

@@ -1082,6 +1082,46 @@ public class ActivityRecordTests extends ActivityTestsBase {
assertFalse(mStack.topActivityOccludesKeyguard());
}
/**
* Verify that complete finish request for an activity which the resume activity is translucent
* must ensure the visibilities of activities being updated.
*/
@Test
public void testCompleteFinishing_ensureActivitiesVisible() {
final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
firstActivity.mVisibleRequested = false;
firstActivity.nowVisible = false;
firstActivity.setState(STOPPED, "true");
final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
secondActivity.mVisibleRequested = true;
secondActivity.nowVisible = true;
secondActivity.setState(PAUSED, "true");
final ActivityRecord translucentActivity =
new ActivityBuilder(mService).setTask(mTask).build();
translucentActivity.mVisibleRequested = true;
translucentActivity.nowVisible = true;
translucentActivity.setState(RESUMED, "true");
doReturn(false).when(translucentActivity).occludesParent();
// Finish the second activity
secondActivity.finishing = true;
secondActivity.completeFinishing("test");
verify(secondActivity.getDisplay()).ensureActivitiesVisible(null /* starting */,
0 /* configChanges */ , false /* preserveWindows */,
true /* notifyClients */);
// Finish the first activity
firstActivity.finishing = true;
firstActivity.mVisibleRequested = true;
firstActivity.completeFinishing("test");
verify(firstActivity.getDisplay(), times(2)).ensureActivitiesVisible(null /* starting */,
0 /* configChanges */ , false /* preserveWindows */,
true /* notifyClients */);
}
/**
* Verify destroy activity request completes successfully.
*/