diff options
5 files changed, 31 insertions, 46 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index cf728330e121..e776e68f108c 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3327,9 +3327,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants, resultTo.getUriPermissionsLocked()); } - if (mForceSendResultForMediaProjection) { - resultTo.sendResult(this.getUid(), resultWho, requestCode, resultCode, - resultData, resultGrants, true /* forceSendForMediaProjection */); + if (mForceSendResultForMediaProjection || resultTo.isState(RESUMED)) { + // Sending the result to the resultTo activity asynchronously to prevent the + // resultTo activity getting results before this Activity paused. + final ActivityRecord resultToActivity = resultTo; + mAtmService.mH.post(() -> { + synchronized (mAtmService.mGlobalLock) { + resultToActivity.sendResult(this.getUid(), resultWho, requestCode, + resultCode, resultData, resultGrants, + mForceSendResultForMediaProjection); + } + }); } else { resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData); } @@ -4640,7 +4648,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A false /* forceSendForMediaProjection */); } - private void sendResult(int callingUid, String resultWho, int requestCode, int resultCode, + void sendResult(int callingUid, String resultWho, int requestCode, int resultCode, Intent data, NeededUriGrants dataGrants, boolean forceSendForMediaProjection) { if (callingUid > 0) { mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(dataGrants, diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 435caa7adc08..27869c7cd44b 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -85,7 +85,6 @@ import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT; import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK; -import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT; import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -3076,11 +3075,6 @@ class ActivityStarter { errMsg = "The app:" + mCallingUid + "is not trusted to " + mStartActivity; break; } - case EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT: { - errMsg = "Cannot embed activity across TaskFragments for result, resultTo: " - + mStartActivity.resultTo; - break; - } default: errMsg = "Unhandled embed result:" + result; } diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index f5a09e04fc4b..7eb9c16a25ff 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -170,13 +170,6 @@ class TaskFragment extends WindowContainer<WindowContainer> { * indicate that an Activity can't be embedded because the Activity is started on a new task. */ static final int EMBEDDING_DISALLOWED_NEW_TASK = 3; - /** - * An embedding check result of - * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: - * indicate that an Activity can't be embedded because the Activity is started on a new - * TaskFragment, e.g. start an Activity on a new TaskFragment for result. - */ - static final int EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT = 4; /** * Embedding check results of {@link #isAllowedToEmbedActivity(ActivityRecord)} or @@ -187,7 +180,6 @@ class TaskFragment extends WindowContainer<WindowContainer> { EMBEDDING_DISALLOWED_UNTRUSTED_HOST, EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION, EMBEDDING_DISALLOWED_NEW_TASK, - EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT, }) @interface EmbeddingCheckResult {} @@ -614,14 +606,6 @@ class TaskFragment extends WindowContainer<WindowContainer> { return EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; } - // Cannot embed activity across TaskFragments for activity result. - // If the activity that started for result is finishing, it's likely that this start mode - // is used to place an activity in the same task. Since the finishing activity won't be - // able to get the results, so it's OK to embed in a different TaskFragment. - if (a.resultTo != null && !a.resultTo.finishing && a.resultTo.getTaskFragment() != this) { - return EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT; - } - return EMBEDDING_ALLOWED; } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index d3e638f10c54..53e0b2b7a615 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1206,6 +1206,25 @@ public class ActivityRecordTests extends WindowTestsBase { } } + @Test + public void testFinishActivityIfPossible_sendResultImmediatelyIfResumed() { + final Task task = new TaskBuilder(mSupervisor).build(); + final TaskFragment taskFragment1 = createTaskFragmentWithParentTask(task); + final TaskFragment taskFragment2 = createTaskFragmentWithParentTask(task); + final ActivityRecord resultToActivity = taskFragment1.getTopMostActivity(); + final ActivityRecord targetActivity = taskFragment2.getTopMostActivity(); + resultToActivity.setState(RESUMED, "test"); + targetActivity.setState(RESUMED, "test"); + targetActivity.resultTo = resultToActivity; + + clearInvocations(mAtm.getLifecycleManager()); + targetActivity.finishIfPossible(0, new Intent(), null, "test", false /* oomAdj */); + waitUntilHandlersIdle(); + + verify(resultToActivity).sendResult(anyInt(), eq(null), anyInt(), anyInt(), any(), eq(null), + anyBoolean()); + } + /** * Verify that complete finish request for non-finishing activity is invalid. */ diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java index 97e5755fec02..38a712ed0435 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java @@ -24,7 +24,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; -import static android.os.Process.FIRST_APPLICATION_UID; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; @@ -33,9 +32,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityRecord.State.RESUMED; -import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; -import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT; import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -477,23 +474,6 @@ public class TaskFragmentTest extends WindowTestsBase { doReturn(true).when(taskFragment).smallerThanMinDimension(any()); assertEquals(EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION, taskFragment.isAllowedToEmbedActivity(activity)); - - // Not allow to start activity across TaskFragments for result. - final TaskFragment newTaskFragment = new TaskFragmentBuilder(mAtm) - .setParentTask(taskFragment.getTask()) - .build(); - final ActivityRecord newActivity = new ActivityBuilder(mAtm) - .setUid(FIRST_APPLICATION_UID) - .build(); - doReturn(true).when(newTaskFragment).isAllowedToEmbedActivityInTrustedMode(any(), anyInt()); - doReturn(false).when(newTaskFragment).smallerThanMinDimension(any()); - newActivity.resultTo = activity; - assertEquals(EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT, - newTaskFragment.isAllowedToEmbedActivity(newActivity)); - - // Allow embedding if the resultTo activity is finishing. - activity.finishing = true; - assertEquals(EMBEDDING_ALLOWED, newTaskFragment.isAllowedToEmbedActivity(newActivity)); } @Test |