Merge "Allow input during remote animation if the app is fully trusted" into tm-dev
This commit is contained in:
@@ -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 =
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user