Loading core/java/android/window/TaskFragmentCreationParams.java +41 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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."); Loading @@ -118,6 +130,7 @@ public final class TaskFragmentCreationParams implements Parcelable { mPairedPrimaryFragmentToken = pairedPrimaryFragmentToken; mPairedActivityToken = pairedActivityToken; mAllowTransitionWhenEmpty = allowTransitionWhenEmpty; mOverrideOrientation = overrideOrientation; } @NonNull Loading Loading @@ -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(); Loading @@ -177,6 +195,7 @@ public final class TaskFragmentCreationParams implements Parcelable { mPairedPrimaryFragmentToken = in.readStrongBinder(); mPairedActivityToken = in.readStrongBinder(); mAllowTransitionWhenEmpty = in.readBoolean(); mOverrideOrientation = in.readInt(); } /** @hide */ Loading @@ -190,6 +209,7 @@ public final class TaskFragmentCreationParams implements Parcelable { dest.writeStrongBinder(mPairedPrimaryFragmentToken); dest.writeStrongBinder(mPairedActivityToken); dest.writeBoolean(mAllowTransitionWhenEmpty); dest.writeInt(mOverrideOrientation); } @NonNull Loading Loading @@ -217,6 +237,7 @@ public final class TaskFragmentCreationParams implements Parcelable { + " pairedFragmentToken=" + mPairedPrimaryFragmentToken + " pairedActivityToken=" + mPairedActivityToken + " allowTransitionWhenEmpty=" + mAllowTransitionWhenEmpty + " overrideOrientation=" + mOverrideOrientation + "}"; } Loading Loading @@ -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; Loading Loading @@ -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); } } } services/core/java/com/android/server/wm/WindowOrganizerController.java +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +54 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -1023,6 +1025,58 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { task.mChildren.indexOf(mTaskFragment)); } @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); Loading services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +16 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -751,6 +752,21 @@ public class TaskFragmentTest extends WindowTestsBase { assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, task.getOrientation(SCREEN_ORIENTATION_UNSET)); } @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. Loading Loading
core/java/android/window/TaskFragmentCreationParams.java +41 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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."); Loading @@ -118,6 +130,7 @@ public final class TaskFragmentCreationParams implements Parcelable { mPairedPrimaryFragmentToken = pairedPrimaryFragmentToken; mPairedActivityToken = pairedActivityToken; mAllowTransitionWhenEmpty = allowTransitionWhenEmpty; mOverrideOrientation = overrideOrientation; } @NonNull Loading Loading @@ -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(); Loading @@ -177,6 +195,7 @@ public final class TaskFragmentCreationParams implements Parcelable { mPairedPrimaryFragmentToken = in.readStrongBinder(); mPairedActivityToken = in.readStrongBinder(); mAllowTransitionWhenEmpty = in.readBoolean(); mOverrideOrientation = in.readInt(); } /** @hide */ Loading @@ -190,6 +209,7 @@ public final class TaskFragmentCreationParams implements Parcelable { dest.writeStrongBinder(mPairedPrimaryFragmentToken); dest.writeStrongBinder(mPairedActivityToken); dest.writeBoolean(mAllowTransitionWhenEmpty); dest.writeInt(mOverrideOrientation); } @NonNull Loading Loading @@ -217,6 +237,7 @@ public final class TaskFragmentCreationParams implements Parcelable { + " pairedFragmentToken=" + mPairedPrimaryFragmentToken + " pairedActivityToken=" + mPairedActivityToken + " allowTransitionWhenEmpty=" + mAllowTransitionWhenEmpty + " overrideOrientation=" + mOverrideOrientation + "}"; } Loading Loading @@ -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; Loading Loading @@ -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); } } }
services/core/java/com/android/server/wm/WindowOrganizerController.java +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +54 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -1023,6 +1025,58 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { task.mChildren.indexOf(mTaskFragment)); } @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); Loading
services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +16 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -751,6 +752,21 @@ public class TaskFragmentTest extends WindowTestsBase { assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, task.getOrientation(SCREEN_ORIENTATION_UNSET)); } @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. Loading