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

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

Merge "Allow system organizer to watch additional config changes" into main

parents 16083ac8 a32517c0
Loading
Loading
Loading
Loading
+41 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.graphics.Rect;
import android.os.IBinder;
@@ -112,12 +113,21 @@ public final class TaskFragmentCreationParams implements Parcelable {
     */
    private final @ScreenOrientation int mOverrideOrientation;

    /**
     * {@link android.content.pm.ActivityInfo.Config} mask that specifies which
     * configuration changes should trigger TaskFragment info change callbacks.
     *
     * @see android.content.pm.ActivityInfo.Config
     */
    private final @ActivityInfo.Config int mConfigurationChangeMask;

    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,
            @ScreenOrientation int overrideOrientation) {
            @ScreenOrientation int overrideOrientation,
            @ActivityInfo.Config int configurationChangeMask) {
        if (pairedPrimaryFragmentToken != null && pairedActivityToken != null) {
            throw new IllegalArgumentException("pairedPrimaryFragmentToken and"
                    + " pairedActivityToken should not be set at the same time.");
@@ -131,6 +141,7 @@ public final class TaskFragmentCreationParams implements Parcelable {
        mPairedActivityToken = pairedActivityToken;
        mAllowTransitionWhenEmpty = allowTransitionWhenEmpty;
        mOverrideOrientation = overrideOrientation;
        mConfigurationChangeMask = configurationChangeMask;
    }

    @NonNull
@@ -186,6 +197,11 @@ public final class TaskFragmentCreationParams implements Parcelable {
        return mOverrideOrientation;
    }

    /** @hide */
    public @ActivityInfo.Config int getConfigurationChangeMask() {
        return mConfigurationChangeMask;
    }

    private TaskFragmentCreationParams(Parcel in) {
        mOrganizer = TaskFragmentOrganizerToken.CREATOR.createFromParcel(in);
        mFragmentToken = in.readStrongBinder();
@@ -196,6 +212,7 @@ public final class TaskFragmentCreationParams implements Parcelable {
        mPairedActivityToken = in.readStrongBinder();
        mAllowTransitionWhenEmpty = in.readBoolean();
        mOverrideOrientation = in.readInt();
        mConfigurationChangeMask = in.readInt();
    }

    /** @hide */
@@ -210,6 +227,7 @@ public final class TaskFragmentCreationParams implements Parcelable {
        dest.writeStrongBinder(mPairedActivityToken);
        dest.writeBoolean(mAllowTransitionWhenEmpty);
        dest.writeInt(mOverrideOrientation);
        dest.writeInt(mConfigurationChangeMask);
    }

    @NonNull
@@ -238,6 +256,7 @@ public final class TaskFragmentCreationParams implements Parcelable {
                + " pairedActivityToken=" + mPairedActivityToken
                + " allowTransitionWhenEmpty=" + mAllowTransitionWhenEmpty
                + " overrideOrientation=" + mOverrideOrientation
                + " configurationChangeMask=" + mConfigurationChangeMask
                + "}";
    }

@@ -275,6 +294,8 @@ public final class TaskFragmentCreationParams implements Parcelable {

        private @ScreenOrientation int mOverrideOrientation = SCREEN_ORIENTATION_UNSPECIFIED;

        private @ActivityInfo.Config int mConfigurationChangeMask = 0;

        public Builder(@NonNull TaskFragmentOrganizerToken organizer,
                @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken) {
            mOrganizer = organizer;
@@ -369,12 +390,30 @@ public final class TaskFragmentCreationParams implements Parcelable {
            return this;
        }

        /**
         * Sets {@link android.content.pm.ActivityInfo.Config} mask that specifies which
         * configuration changes should trigger TaskFragment info change callbacks.
         *
         * Only system organizers are allowed to configure this value. This value is ignored for
         * non-system organizers.
         *
         * @see android.content.pm.ActivityInfo.Config
         * @hide
         */
        @NonNull
        public Builder setConfigurationChangeMask(
                @ActivityInfo.Config int configurationChangeMask) {
            mConfigurationChangeMask = configurationChangeMask;
            return this;
        }

        /** Constructs the options to create TaskFragment with. */
        @NonNull
        public TaskFragmentCreationParams build() {
            return new TaskFragmentCreationParams(mOrganizer, mFragmentToken, mOwnerToken,
                    mInitialRelativeBounds, mWindowingMode, mPairedPrimaryFragmentToken,
                    mPairedActivityToken, mAllowTransitionWhenEmpty, mOverrideOrientation);
                    mPairedActivityToken, mAllowTransitionWhenEmpty, mOverrideOrientation,
                    mConfigurationChangeMask);
        }
    }
}
+17 −0
Original line number Diff line number Diff line
@@ -394,6 +394,12 @@ class TaskFragment extends WindowContainer<WindowContainer> {
     */
    private boolean mAllowTransitionWhenEmpty;

    /**
     * Specifies which configuration changes should trigger TaskFragment info changed callbacks.
     * Only system TaskFragment organizers are allowed to set this value.
     */
    private @ActivityInfo.Config int mConfigurationChangeMaskForOrganizer;

    /** When set, will force the task to report as invisible. */
    static final int FLAG_FORCE_HIDDEN_FOR_PINNED_TASK = 1;
    static final int FLAG_FORCE_HIDDEN_FOR_TASK_ORG = 1 << 1;
@@ -656,6 +662,17 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        mAllowTransitionWhenEmpty = allowTransitionWhenEmpty;
    }

    void setConfigurationChangeMaskForOrganizer(@ActivityInfo.Config int mask) {
        // Only system organizers are allowed to set configuration change mask.
        if (mTaskFragmentOrganizerController.isSystemOrganizer(mTaskFragmentOrganizer.asBinder())) {
            mConfigurationChangeMaskForOrganizer = mask;
        }
    }

    @ActivityInfo.Config int getConfigurationChangeMaskForOrganizer() {
        return mConfigurationChangeMaskForOrganizer;
    }

    /** @see #mIsolatedNav */
    boolean isIsolatedNav() {
        return isEmbedded() && mIsolatedNav;
+4 −2
Original line number Diff line number Diff line
@@ -349,8 +349,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
            // Check if the info is different from the last reported info.
            final TaskFragmentInfo info = tf.getTaskFragmentInfo();
            final TaskFragmentInfo lastInfo = mLastSentTaskFragmentInfos.get(tf);
            if (info.equalsForTaskFragmentOrganizer(lastInfo) && configurationsAreEqualForOrganizer(
                    info.getConfiguration(), lastInfo.getConfiguration())) {
            final int configurationChangeMask = tf.getConfigurationChangeMaskForOrganizer();
            if (info.equalsForTaskFragmentOrganizer(lastInfo)
                    && configurationsAreEqualForOrganizer(info.getConfiguration(),
                            lastInfo.getConfiguration(), configurationChangeMask)) {
                return null;
            }

+20 −0
Original line number Diff line number Diff line
@@ -2455,10 +2455,28 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
    /** Whether the configuration changes are important to report back to an organizer. */
    static boolean configurationsAreEqualForOrganizer(
            Configuration newConfig, @Nullable Configuration oldConfig) {
        return configurationsAreEqualForOrganizer(newConfig, oldConfig, 0 /* additionalMask */);
    }

    /**
     * Whether the configuration changes are important to report back to an organizer.
     *
     * @param newConfig the new configuration
     * @param oldConfig the old configuration
     * @param additionalMask specifies additional configuration changes that the organizer is
     *                       interested in. If the configuration change matches any bit in the mask,
     *                       {@code false} is returned.
     */
    static boolean configurationsAreEqualForOrganizer(
            Configuration newConfig, @Nullable Configuration oldConfig,
            @ActivityInfo.Config int additionalMask) {
        if (oldConfig == null) {
            return false;
        }
        int cfgChanges = newConfig.diff(oldConfig);
        if ((cfgChanges & additionalMask) != 0) {
            return false;
        }
        final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0
                ? (int) newConfig.windowConfiguration.diff(oldConfig.windowConfiguration,
                true /* compareUndefined */) : 0;
@@ -2665,6 +2683,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                ownerActivity.getUid(), ownerActivity.info.processName);
        if (mTaskFragmentOrganizerController.isSystemOrganizer(organizerToken.asBinder())) {
            taskFragment.setOverrideOrientation(creationParams.getOverrideOrientation());
            taskFragment.setConfigurationChangeMaskForOrganizer(
                    creationParams.getConfigurationChangeMask());
        }
        final int position;
        if (creationParams.getPairedPrimaryFragmentToken() != null) {
+27 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ 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.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -33,6 +34,8 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.content.res.Configuration.UI_MODE_NIGHT_NO;
import static android.content.res.Configuration.UI_MODE_NIGHT_YES;
import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
@@ -1983,6 +1986,30 @@ public class WindowOrganizerTests extends WindowTestsBase {
        testSetAlwaysOnTop(displayArea);
    }

    @Test
    public void testConfigurationsAreEqualForOrganizer() {
        Configuration config1 = new Configuration();
        config1.smallestScreenWidthDp = 300;
        config1.uiMode = UI_MODE_NIGHT_YES;

        Configuration config2 = new Configuration(config1);
        config2.uiMode = UI_MODE_NIGHT_NO;

        Configuration config3 = new Configuration(config1);
        config3.smallestScreenWidthDp = 500;

        // Should be equal for non-controllable configuration changes.
        assertTrue(WindowOrganizerController.configurationsAreEqualForOrganizer(config1, config2));

        // Should be unequal for non-controllable configuration changes if the organizer is
        // interested in that change.
        assertFalse(WindowOrganizerController.configurationsAreEqualForOrganizer(
                config1, config2, CONFIG_UI_MODE));

        // Should be unequal for controllable configuration changes.
        assertFalse(WindowOrganizerController.configurationsAreEqualForOrganizer(config1, config3));
    }

    private void testSetAlwaysOnTop(WindowContainer wc) {
        final WindowContainerTransaction t = new WindowContainerTransaction();
        t.setAlwaysOnTop(wc.mRemoteToken.toWindowContainerToken(), true);