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.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
@@ -322,9 +323,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
+ " is not in a task belong to the organizer app.");
|
+ " is not in a task belong to the organizer app.");
|
||||||
return null;
|
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
|
Slog.d(TAG, "Reparent activity=" + activity.token
|
||||||
+ " is not allowed to be embedded.");
|
+ " is not allowed to be embedded in trusted mode.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +352,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
activity.token, task.mTaskId);
|
activity.token, task.mTaskId);
|
||||||
return new TaskFragmentTransaction.Change(TYPE_ACTIVITY_REPARENTED_TO_TASK)
|
return new TaskFragmentTransaction.Change(TYPE_ACTIVITY_REPARENTED_TO_TASK)
|
||||||
.setTaskId(task.mTaskId)
|
.setTaskId(task.mTaskId)
|
||||||
.setActivityIntent(activity.intent)
|
.setActivityIntent(trimIntent(activity.intent))
|
||||||
.setActivityToken(activityToken);
|
.setActivityToken(activityToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1095,4 +1097,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
return false;
|
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 static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -403,7 +405,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
final TaskFragmentTransaction.Change change = changes.get(0);
|
final TaskFragmentTransaction.Change change = changes.get(0);
|
||||||
assertEquals(TYPE_ACTIVITY_REPARENTED_TO_TASK, change.getType());
|
assertEquals(TYPE_ACTIVITY_REPARENTED_TO_TASK, change.getType());
|
||||||
assertEquals(task.mTaskId, change.getTaskId());
|
assertEquals(task.mTaskId, change.getTaskId());
|
||||||
assertEquals(activity.intent, change.getActivityIntent());
|
assertIntentsEqualForOrganizer(activity.intent, change.getActivityIntent());
|
||||||
assertNotEquals(activity.token, change.getActivityToken());
|
assertNotEquals(activity.token, change.getActivityToken());
|
||||||
mTransaction.reparentActivityToTaskFragment(mFragmentToken, change.getActivityToken());
|
mTransaction.reparentActivityToTaskFragment(mFragmentToken, change.getActivityToken());
|
||||||
assertApplyTransactionAllowed(mTransaction);
|
assertApplyTransactionAllowed(mTransaction);
|
||||||
@@ -414,6 +416,62 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
change.getActivityToken()));
|
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
|
@Test
|
||||||
public void testRegisterRemoteAnimations() {
|
public void testRegisterRemoteAnimations() {
|
||||||
mController.registerRemoteAnimations(mIOrganizer, TASK_ID, mDefinition);
|
mController.registerRemoteAnimations(mIOrganizer, TASK_ID, mDefinition);
|
||||||
@@ -1425,7 +1483,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
final TaskFragmentTransaction.Change change = changes.remove(0);
|
final TaskFragmentTransaction.Change change = changes.remove(0);
|
||||||
assertEquals(TYPE_ACTIVITY_REPARENTED_TO_TASK, change.getType());
|
assertEquals(TYPE_ACTIVITY_REPARENTED_TO_TASK, change.getType());
|
||||||
assertEquals(taskId, change.getTaskId());
|
assertEquals(taskId, change.getTaskId());
|
||||||
assertEquals(intent, change.getActivityIntent());
|
assertIntentsEqualForOrganizer(intent, change.getActivityIntent());
|
||||||
|
assertIntentTrimmed(change.getActivityIntent());
|
||||||
assertEquals(activityToken, change.getActivityToken());
|
assertEquals(activityToken, change.getActivityToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1452,4 +1511,17 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
mockParent.lastActiveTime = 100;
|
mockParent.lastActiveTime = 100;
|
||||||
doReturn(true).when(mockParent).shouldBeVisible(any());
|
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