diff options
| author | 2024-04-12 16:17:51 +0000 | |
|---|---|---|
| committer | 2024-04-12 16:17:51 +0000 | |
| commit | d46319583fd20e7824c65fc6d24a250eb845542e (patch) | |
| tree | c478dadad0ebc3611a94a6a57b97539f3f7f0679 | |
| parent | 65ed54918576e10eee0379f5cb09f0e2fc27cb7c (diff) | |
| parent | f3ad69e1bccce37acabe2eb5f9158279e9352de6 (diff) | |
Merge "Allow system organizer to specify TF override orientation" into main
4 files changed, 114 insertions, 2 deletions
diff --git a/core/java/android/window/TaskFragmentCreationParams.java b/core/java/android/window/TaskFragmentCreationParams.java index 93297e64c621..89327fe358f5 100644 --- a/core/java/android/window/TaskFragmentCreationParams.java +++ b/core/java/android/window/TaskFragmentCreationParams.java @@ -18,10 +18,13 @@ package android.window; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WindowingMode; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.TestApi; +import android.content.pm.ActivityInfo.ScreenOrientation; import android.graphics.Rect; import android.os.IBinder; import android.os.Parcel; @@ -101,11 +104,20 @@ public final class TaskFragmentCreationParams implements Parcelable { */ private final boolean mAllowTransitionWhenEmpty; + /** + * The override orientation for the TaskFragment. This is effective only for a system organizer. + * The value is ignored otherwise. Default to {@code SCREEN_ORIENTATION_UNSPECIFIED}. + * + * @see TaskFragmentOrganizer#registerOrganizer(boolean) + */ + private final @ScreenOrientation int mOverrideOrientation; + private TaskFragmentCreationParams( @NonNull TaskFragmentOrganizerToken organizer, @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken, @NonNull Rect initialRelativeBounds, @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken, - @Nullable IBinder pairedActivityToken, boolean allowTransitionWhenEmpty) { + @Nullable IBinder pairedActivityToken, boolean allowTransitionWhenEmpty, + @ScreenOrientation int overrideOrientation) { if (pairedPrimaryFragmentToken != null && pairedActivityToken != null) { throw new IllegalArgumentException("pairedPrimaryFragmentToken and" + " pairedActivityToken should not be set at the same time."); @@ -118,6 +130,7 @@ public final class TaskFragmentCreationParams implements Parcelable { mPairedPrimaryFragmentToken = pairedPrimaryFragmentToken; mPairedActivityToken = pairedActivityToken; mAllowTransitionWhenEmpty = allowTransitionWhenEmpty; + mOverrideOrientation = overrideOrientation; } @NonNull @@ -168,6 +181,11 @@ public final class TaskFragmentCreationParams implements Parcelable { return mAllowTransitionWhenEmpty; } + /** @hide */ + public @ScreenOrientation int getOverrideOrientation() { + return mOverrideOrientation; + } + private TaskFragmentCreationParams(Parcel in) { mOrganizer = TaskFragmentOrganizerToken.CREATOR.createFromParcel(in); mFragmentToken = in.readStrongBinder(); @@ -177,6 +195,7 @@ public final class TaskFragmentCreationParams implements Parcelable { mPairedPrimaryFragmentToken = in.readStrongBinder(); mPairedActivityToken = in.readStrongBinder(); mAllowTransitionWhenEmpty = in.readBoolean(); + mOverrideOrientation = in.readInt(); } /** @hide */ @@ -190,6 +209,7 @@ public final class TaskFragmentCreationParams implements Parcelable { dest.writeStrongBinder(mPairedPrimaryFragmentToken); dest.writeStrongBinder(mPairedActivityToken); dest.writeBoolean(mAllowTransitionWhenEmpty); + dest.writeInt(mOverrideOrientation); } @NonNull @@ -217,6 +237,7 @@ public final class TaskFragmentCreationParams implements Parcelable { + " pairedFragmentToken=" + mPairedPrimaryFragmentToken + " pairedActivityToken=" + mPairedActivityToken + " allowTransitionWhenEmpty=" + mAllowTransitionWhenEmpty + + " overrideOrientation=" + mOverrideOrientation + "}"; } @@ -252,6 +273,8 @@ public final class TaskFragmentCreationParams implements Parcelable { private boolean mAllowTransitionWhenEmpty; + private @ScreenOrientation int mOverrideOrientation = SCREEN_ORIENTATION_UNSPECIFIED; + public Builder(@NonNull TaskFragmentOrganizerToken organizer, @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken) { mOrganizer = organizer; @@ -330,12 +353,28 @@ public final class TaskFragmentCreationParams implements Parcelable { return this; } + /** + * Sets the override orientation for the TaskFragment. This is effective only for a system + * organizer. The value is ignored otherwise. Default to + * {@code SCREEN_ORIENTATION_UNSPECIFIED}. + * + * @see TaskFragmentOrganizer#registerOrganizer(boolean) + * + * @hide + */ + @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS) + @NonNull + public Builder setOverrideOrientation(@ScreenOrientation int overrideOrientation) { + mOverrideOrientation = overrideOrientation; + return this; + } + /** Constructs the options to create TaskFragment with. */ @NonNull public TaskFragmentCreationParams build() { return new TaskFragmentCreationParams(mOrganizer, mFragmentToken, mOwnerToken, mInitialRelativeBounds, mWindowingMode, mPairedPrimaryFragmentToken, - mPairedActivityToken, mAllowTransitionWhenEmpty); + mPairedActivityToken, mAllowTransitionWhenEmpty, mOverrideOrientation); } } } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 393a01ff0406..8c9317a32483 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -2310,6 +2310,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub TaskFragmentOrganizerToken organizerToken = creationParams.getOrganizer(); taskFragment.setTaskFragmentOrganizer(organizerToken, ownerActivity.getUid(), ownerActivity.info.processName); + if (mTaskFragmentOrganizerController.isSystemOrganizer(organizerToken.asBinder())) { + taskFragment.setOverrideOrientation(creationParams.getOverrideOrientation()); + } final int position; if (creationParams.getPairedPrimaryFragmentToken() != null) { // When there is a paired primary TaskFragment, we want to place the new TaskFragment diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index 52485eec8505..002a3d5a0d53 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -19,6 +19,8 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; @@ -1024,6 +1026,58 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { } @Test + public void testApplyTransaction_createTaskFragment_overrideOrientation_systemOrganizer() { + mSetFlagsRule.enableFlags(Flags.FLAG_TASK_FRAGMENT_SYSTEM_ORGANIZER_FLAG); + mController.unregisterOrganizer(mIOrganizer); + registerTaskFragmentOrganizer(mIOrganizer, true /* isSystemOrganizer */); + + final Task task = createTask(mDisplayContent); + final ActivityRecord activity = createActivityRecord(task); + final int uid = Binder.getCallingUid(); + activity.info.applicationInfo.uid = uid; + activity.getTask().effectiveUid = uid; + final IBinder fragmentToken = new Binder(); + + // Create a TaskFragment with OverrideOrientation set. + final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder( + mOrganizerToken, fragmentToken, activity.token) + .setOverrideOrientation(SCREEN_ORIENTATION_BEHIND) + .build(); + mTransaction.setTaskFragmentOrganizer(mIOrganizer); + mTransaction.createTaskFragment(params); + assertApplyTransactionAllowed(mTransaction); + + // TaskFragment override orientation should be set for a system organizer. + final TaskFragment taskFragment = mWindowOrganizerController.getTaskFragment(fragmentToken); + assertNotNull(taskFragment); + assertEquals(SCREEN_ORIENTATION_BEHIND, taskFragment.getOverrideOrientation()); + } + + @Test + public void testApplyTransaction_createTaskFragment_overrideOrientation_nonSystemOrganizer() { + final Task task = createTask(mDisplayContent); + final ActivityRecord activity = createActivityRecord(task); + final int uid = Binder.getCallingUid(); + activity.info.applicationInfo.uid = uid; + activity.getTask().effectiveUid = uid; + final IBinder fragmentToken = new Binder(); + + // Create a TaskFragment with OverrideOrientation set. + final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder( + mOrganizerToken, fragmentToken, activity.token) + .setOverrideOrientation(SCREEN_ORIENTATION_BEHIND) + .build(); + mTransaction.setTaskFragmentOrganizer(mIOrganizer); + mTransaction.createTaskFragment(params); + assertApplyTransactionAllowed(mTransaction); + + // TaskFragment override orientation is ignored for a non-system organizer. + final TaskFragment taskFragment = mWindowOrganizerController.getTaskFragment(fragmentToken); + assertNotNull(taskFragment); + assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, taskFragment.getOverrideOrientation()); + } + + @Test public void testApplyTransaction_reparentActivityToTaskFragment_triggerLifecycleUpdate() { final Task task = createTask(mDisplayContent); final ActivityRecord activity = createActivityRecord(task); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java index 3c5b12c68e1c..4837fcbfc262 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java @@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; 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; @@ -752,6 +753,21 @@ public class TaskFragmentTest extends WindowTestsBase { } @Test + public void testGetOrientation_reportOverrideOrientation() { + final Task task = createTask(mDisplayContent); + final TaskFragment tf = createTaskFragmentWithActivity(task); + final ActivityRecord activity = tf.getTopMostActivity(); + tf.setOverrideOrientation(SCREEN_ORIENTATION_BEHIND); + + // Should report the override orientation + assertEquals(SCREEN_ORIENTATION_BEHIND, tf.getOrientation(SCREEN_ORIENTATION_UNSET)); + + // Should report the override orientation even if the activity requests a different value + activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); + assertEquals(SCREEN_ORIENTATION_BEHIND, tf.getOrientation(SCREEN_ORIENTATION_UNSET)); + } + + @Test public void testUpdateImeParentForActivityEmbedding() { // Setup two activities in ActivityEmbedding. final Task task = createTask(mDisplayContent); |