Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4631958 authored by Jiaming Liu's avatar Jiaming Liu Committed by Android (Google) Code Review
Browse files

Merge "Allow system organizer to specify TF override orientation" into main

parents 65ed5491 f3ad69e1
Loading
Loading
Loading
Loading
+41 −2
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -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
+54 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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);
+16 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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.