Merge "Allow input during remote animation if the app is fully trusted" into tm-dev

This commit is contained in:
Chris Li
2022-05-13 00:11:15 +00:00
committed by Android (Google) Code Review
4 changed files with 77 additions and 13 deletions

View File

@@ -663,11 +663,16 @@ public class AppTransitionController {
"Override with TaskFragment remote animation for transit=%s", "Override with TaskFragment remote animation for transit=%s",
AppTransition.appTransitionOldToString(transit)); AppTransition.appTransitionOldToString(transit));
final int organizerUid = mDisplayContent.mAtmService.mTaskFragmentOrganizerController
.getTaskFragmentOrganizerUid(organizer);
final boolean shouldDisableInputForRemoteAnimation = !task.isFullyTrustedEmbedding(
organizerUid);
final RemoteAnimationController remoteAnimationController = final RemoteAnimationController remoteAnimationController =
mDisplayContent.mAppTransition.getRemoteAnimationController(); mDisplayContent.mAppTransition.getRemoteAnimationController();
if (remoteAnimationController != null) { if (shouldDisableInputForRemoteAnimation && remoteAnimationController != null) {
// We are going to use client-driven animation, Disable all input on activity windows // We are going to use client-driven animation, Disable all input on activity windows
// during the animation to ensure it is safe to allow client to animate the surfaces. // during the animation (unless it is fully trusted) to ensure it is safe to allow
// client to animate the surfaces.
// This is needed for all activity windows in the animation Task. // This is needed for all activity windows in the animation Task.
remoteAnimationController.setOnRemoteAnimationReady(() -> { remoteAnimationController.setOnRemoteAnimationReady(() -> {
final Consumer<ActivityRecord> updateActivities = final Consumer<ActivityRecord> updateActivities =

View File

@@ -562,13 +562,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
* @param uid uid of the TaskFragment organizer. * @param uid uid of the TaskFragment organizer.
*/ */
boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a, int uid) { boolean isAllowedToEmbedActivityInTrustedMode(@NonNull ActivityRecord a, int uid) {
if (UserHandle.getAppId(uid) == SYSTEM_UID) { if (isFullyTrustedEmbedding(a, uid)) {
// The system is trusted to embed other apps securely and for all users.
return true;
}
if (uid == a.getUid()) {
// Activities from the same UID can be embedded freely by the host.
return true; return true;
} }
@@ -586,14 +580,35 @@ class TaskFragment extends WindowContainer<WindowContainer> {
knownActivityEmbeddingCerts); knownActivityEmbeddingCerts);
} }
/**
* It is fully trusted for embedding in the system app or embedding in the same app. This is
* different from {@link #isAllowedToBeEmbeddedInTrustedMode()} since there may be a small
* chance for a previous trusted app to start doing something bad.
*/
private static boolean isFullyTrustedEmbedding(@NonNull ActivityRecord a, int uid) {
// The system is trusted to embed other apps securely and for all users.
return UserHandle.getAppId(uid) == SYSTEM_UID
// Activities from the same UID can be embedded freely by the host.
|| uid == a.getUid();
}
/**
* Checks if all activities in the task fragment are embedded as fully trusted.
* @see #isFullyTrustedEmbedding(ActivityRecord, int)
* @param uid uid of the TaskFragment organizer.
*/
boolean isFullyTrustedEmbedding(int uid) {
// Traverse all activities to see if any of them are not fully trusted embedding.
return !forAllActivities(r -> !isFullyTrustedEmbedding(r, uid));
}
/** /**
* Checks if all activities in the task fragment are allowed to be embedded in trusted mode. * Checks if all activities in the task fragment are allowed to be embedded in trusted mode.
* @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord) * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord)
*/ */
boolean isAllowedToBeEmbeddedInTrustedMode() { boolean isAllowedToBeEmbeddedInTrustedMode() {
// Traverse all activities to see if any of them are not in the trusted mode. // Traverse all activities to see if any of them are not in the trusted mode.
final Predicate<ActivityRecord> callback = r -> !isAllowedToEmbedActivityInTrustedMode(r); return !forAllActivities(r -> !isAllowedToEmbedActivityInTrustedMode(r));
return !forAllActivities(callback);
} }
/** /**

View File

@@ -378,6 +378,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
} }
} }
int getTaskFragmentOrganizerUid(ITaskFragmentOrganizer organizer) {
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
return state.mOrganizerUid;
}
void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) { void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) {
final TaskFragmentOrganizerState state = validateAndGetState(organizer); final TaskFragmentOrganizerState state = validateAndGetState(organizer);
if (!state.addTaskFragment(taskFragment)) { if (!state.addTaskFragment(taskFragment)) {

View File

@@ -1128,6 +1128,41 @@ public class AppTransitionControllerTest extends WindowTestsBase {
verify(activity).setDropInputMode(DropInputMode.NONE); verify(activity).setDropInputMode(DropInputMode.NONE);
} }
/**
* We don't need to drop input for fully trusted embedding (system app, and embedding in the
* same app). This will allow users to do fast tapping.
*/
@Test
public void testOverrideTaskFragmentAdapter_noInputProtectedForFullyTrustedAnimation() {
final Task task = createTask(mDisplayContent);
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
setupTaskFragmentRemoteAnimation(organizer, task.mTaskId, remoteAnimationRunner);
// Create a TaskFragment with only trusted embedded activity
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
.setParentTask(task)
.createActivityCount(1)
.setOrganizer(organizer)
.build();
final ActivityRecord activity = taskFragment.getChildAt(0).asActivityRecord();
prepareActivityForAppTransition(activity);
final int uid = mAtm.mTaskFragmentOrganizerController.getTaskFragmentOrganizerUid(
getITaskFragmentOrganizer(organizer));
doReturn(true).when(task).isFullyTrustedEmbedding(uid);
spyOn(mDisplayContent.mAppTransition);
// Prepare and start transition.
prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
// The animation will be animated remotely by client, but input should not be dropped for
// fully trusted.
assertTrue(remoteAnimationRunner.isAnimationStarted());
verify(activity, never()).setDropInputForAnimation(true);
verify(activity, never()).setDropInputMode(DropInputMode.ALL);
}
@Test @Test
public void testTransitionGoodToGoForTaskFragments() { public void testTransitionGoodToGoForTaskFragments() {
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
@@ -1197,8 +1232,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
TestRemoteAnimationRunner remoteAnimationRunner) { TestRemoteAnimationRunner remoteAnimationRunner) {
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
remoteAnimationRunner, 10, 1); remoteAnimationRunner, 10, 1);
final ITaskFragmentOrganizer iOrganizer = final ITaskFragmentOrganizer iOrganizer = getITaskFragmentOrganizer(organizer);
ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder());
final RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); final RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, adapter); definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, adapter);
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, adapter); definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, adapter);
@@ -1208,6 +1242,11 @@ public class AppTransitionControllerTest extends WindowTestsBase {
definition); definition);
} }
private static ITaskFragmentOrganizer getITaskFragmentOrganizer(
TaskFragmentOrganizer organizer) {
return ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder());
}
private void prepareAndTriggerAppTransition(@Nullable ActivityRecord openingActivity, private void prepareAndTriggerAppTransition(@Nullable ActivityRecord openingActivity,
@Nullable ActivityRecord closingActivity, @Nullable TaskFragment changingTaskFragment) { @Nullable ActivityRecord closingActivity, @Nullable TaskFragment changingTaskFragment) {
if (openingActivity != null) { if (openingActivity != null) {