No longer embedding activity if started-for-result across TFs

Instead of sending RESULT_CANCELED to the caller activity, let's
making sure the caller activity can get the result by stop embedding
the result activity in another TaskFragment.

Bug: 236668365
Test: atest TaskFragmentTest
Change-Id: I2a1d3203cc64df6a3b2004529d067990ae17d1d5
This commit is contained in:
Louis Chang
2022-07-13 02:59:43 +00:00
parent 61bfe6e0dc
commit ccb275fecb
3 changed files with 61 additions and 1 deletions

View File

@@ -83,6 +83,7 @@ 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;
@@ -3006,6 +3007,11 @@ 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;
}

View File

@@ -165,6 +165,13 @@ 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
@@ -175,6 +182,7 @@ 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 {}
@@ -567,9 +575,17 @@ class TaskFragment extends WindowContainer<WindowContainer> {
if (!isAllowedToEmbedActivityInUntrustedMode(a)
&& !isAllowedToEmbedActivityInTrustedMode(a, uid)) {
return EMBEDDING_DISALLOWED_UNTRUSTED_HOST;
} else if (smallerThanMinDimension(a)) {
}
if (smallerThanMinDimension(a)) {
return EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION;
}
// Cannot embed activity across TaskFragments for activity result.
if (a.resultTo != null && a.resultTo.getTaskFragment() != this) {
return EMBEDDING_DISALLOWED_NEW_TASK_FRAGMENT;
}
return EMBEDDING_ALLOWED;
}

View File

@@ -23,6 +23,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
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.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;
@@ -31,6 +32,9 @@ 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_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;
import static org.junit.Assert.assertEquals;
@@ -432,6 +436,40 @@ public class TaskFragmentTest extends WindowTestsBase {
assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode());
}
@Test
public void testIsAllowedToEmbedActivity() {
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
.setCreateParentTask()
.createActivityCount(1)
.build();
final ActivityRecord activity = taskFragment.getTopMostActivity();
// Not allow embedding activity if not a trusted host.
doReturn(false).when(taskFragment).isAllowedToEmbedActivityInUntrustedMode(any());
doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(any(), anyInt());
assertEquals(EMBEDDING_DISALLOWED_UNTRUSTED_HOST,
taskFragment.isAllowedToEmbedActivity(activity));
// Not allow embedding activity if the TaskFragment is smaller than activity min dimension.
doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(any(), anyInt());
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));
}
@Test
public void testIgnoreRequestedOrientationForActivityEmbeddingSplit() {
// Setup two activities in ActivityEmbedding split.