Merge "Enforce onActivityReparentedToTask" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f31b5dc063
@@ -34,6 +34,7 @@ import static java.util.Objects.requireNonNull;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Binder;
|
||||
@@ -322,9 +323,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
||||
+ " is not in a task belong to the organizer app.");
|
||||
return null;
|
||||
}
|
||||
if (task.isAllowedToEmbedActivity(activity, mOrganizerUid) != EMBEDDING_ALLOWED) {
|
||||
if (task.isAllowedToEmbedActivity(activity, mOrganizerUid) != EMBEDDING_ALLOWED
|
||||
|| !task.isAllowedToEmbedActivityInTrustedMode(activity, mOrganizerUid)) {
|
||||
Slog.d(TAG, "Reparent activity=" + activity.token
|
||||
+ " is not allowed to be embedded.");
|
||||
+ " is not allowed to be embedded in trusted mode.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -350,7 +352,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
||||
activity.token, task.mTaskId);
|
||||
return new TaskFragmentTransaction.Change(TYPE_ACTIVITY_REPARENTED_TO_TASK)
|
||||
.setTaskId(task.mTaskId)
|
||||
.setActivityIntent(activity.intent)
|
||||
.setActivityIntent(trimIntent(activity.intent))
|
||||
.setActivityToken(activityToken);
|
||||
}
|
||||
|
||||
@@ -1095,4 +1097,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the given Intent to only those that are needed to for embedding rules. This helps to
|
||||
* make it safer for cross-uid embedding even if we only send the Intent for trusted embedding.
|
||||
*/
|
||||
private static Intent trimIntent(@NonNull Intent intent) {
|
||||
return new Intent()
|
||||
.setComponent(intent.getComponent())
|
||||
.setPackage(intent.getPackage())
|
||||
.setAction(intent.getAction());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,12 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -403,7 +405,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
final TaskFragmentTransaction.Change change = changes.get(0);
|
||||
assertEquals(TYPE_ACTIVITY_REPARENTED_TO_TASK, change.getType());
|
||||
assertEquals(task.mTaskId, change.getTaskId());
|
||||
assertEquals(activity.intent, change.getActivityIntent());
|
||||
assertIntentsEqualForOrganizer(activity.intent, change.getActivityIntent());
|
||||
assertNotEquals(activity.token, change.getActivityToken());
|
||||
mTransaction.reparentActivityToTaskFragment(mFragmentToken, change.getActivityToken());
|
||||
assertApplyTransactionAllowed(mTransaction);
|
||||
@@ -414,6 +416,62 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
change.getActivityToken()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityReparentedToTask_untrustedEmbed_notReported() {
|
||||
final int pid = Binder.getCallingPid();
|
||||
final int uid = Binder.getCallingUid();
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizer.getOrganizerToken(), uid,
|
||||
DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
|
||||
mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
|
||||
final Task task = createTask(mDisplayContent);
|
||||
task.addChild(mTaskFragment, POSITION_TOP);
|
||||
final ActivityRecord activity = createActivityRecord(task);
|
||||
|
||||
// Make sure the activity is embedded in untrusted mode.
|
||||
activity.info.applicationInfo.uid = uid + 1;
|
||||
doReturn(pid + 1).when(activity).getPid();
|
||||
task.effectiveUid = uid;
|
||||
doReturn(EMBEDDING_ALLOWED).when(task).isAllowedToEmbedActivity(activity, uid);
|
||||
doReturn(false).when(task).isAllowedToEmbedActivityInTrustedMode(activity, uid);
|
||||
doReturn(true).when(task).isAllowedToEmbedActivityInUntrustedMode(activity);
|
||||
|
||||
// Notify organizer if it was embedded before entered Pip.
|
||||
// Create a temporary token since the activity doesn't belong to the same process.
|
||||
clearInvocations(mOrganizer);
|
||||
activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
|
||||
mController.onActivityReparentedToTask(activity);
|
||||
mController.dispatchPendingEvents();
|
||||
|
||||
// Disallow organizer to reparent activity that is untrusted embedded.
|
||||
verify(mOrganizer, never()).onTransactionReady(mTransactionCaptor.capture());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityReparentedToTask_trimReportedIntent() {
|
||||
// Make sure the activity pid/uid is the same as the organizer caller.
|
||||
final int pid = Binder.getCallingPid();
|
||||
final int uid = Binder.getCallingUid();
|
||||
final ActivityRecord activity = createActivityRecord(mDisplayContent);
|
||||
final Task task = activity.getTask();
|
||||
activity.info.applicationInfo.uid = uid;
|
||||
doReturn(pid).when(activity).getPid();
|
||||
task.effectiveUid = uid;
|
||||
activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
|
||||
|
||||
// Test the Intent trim in #assertIntentTrimmed
|
||||
activity.intent.setComponent(new ComponentName("TestPackage", "TestClass"))
|
||||
.setPackage("TestPackage")
|
||||
.setAction("TestAction")
|
||||
.setData(mock(Uri.class))
|
||||
.putExtra("Test", 123)
|
||||
.setFlags(10);
|
||||
|
||||
mController.onActivityReparentedToTask(activity);
|
||||
mController.dispatchPendingEvents();
|
||||
|
||||
assertActivityReparentedToTaskTransaction(task.mTaskId, activity.intent, activity.token);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterRemoteAnimations() {
|
||||
mController.registerRemoteAnimations(mIOrganizer, TASK_ID, mDefinition);
|
||||
@@ -1425,7 +1483,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
final TaskFragmentTransaction.Change change = changes.remove(0);
|
||||
assertEquals(TYPE_ACTIVITY_REPARENTED_TO_TASK, change.getType());
|
||||
assertEquals(taskId, change.getTaskId());
|
||||
assertEquals(intent, change.getActivityIntent());
|
||||
assertIntentsEqualForOrganizer(intent, change.getActivityIntent());
|
||||
assertIntentTrimmed(change.getActivityIntent());
|
||||
assertEquals(activityToken, change.getActivityToken());
|
||||
}
|
||||
|
||||
@@ -1452,4 +1511,17 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
mockParent.lastActiveTime = 100;
|
||||
doReturn(true).when(mockParent).shouldBeVisible(any());
|
||||
}
|
||||
|
||||
private static void assertIntentsEqualForOrganizer(@NonNull Intent expected,
|
||||
@NonNull Intent actual) {
|
||||
assertEquals(expected.getComponent(), actual.getComponent());
|
||||
assertEquals(expected.getPackage(), actual.getPackage());
|
||||
assertEquals(expected.getAction(), actual.getAction());
|
||||
}
|
||||
|
||||
private static void assertIntentTrimmed(@NonNull Intent intent) {
|
||||
assertNull(intent.getData());
|
||||
assertNull(intent.getExtras());
|
||||
assertEquals(0, intent.getFlags());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user