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

Commit 340ce855 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Make process level rotated config and display metrics consistent"

parents 24cf07c2 d5c5a1b4
Loading
Loading
Loading
Loading
+51 −48
Original line number Diff line number Diff line
@@ -3271,12 +3271,6 @@ public final class ActivityThread extends ClientTransactionHandler {
        sendMessage(H.CLEAN_UP_CONTEXT, cci);
    }

    @Override
    public void handleFixedRotationAdjustments(@NonNull IBinder token,
            @Nullable FixedRotationAdjustments fixedRotationAdjustments) {
        handleFixedRotationAdjustments(token, fixedRotationAdjustments, null /* overrideConfig */);
    }

    /**
     * Applies the rotation adjustments to override display information in resources belong to the
     * provided token. If the token is activity token, the adjustments also apply to application
@@ -3286,51 +3280,39 @@ public final class ActivityThread extends ClientTransactionHandler {
     * @param fixedRotationAdjustments The information to override the display adjustments of
     *                                 corresponding resources. If it is null, the exiting override
     *                                 will be cleared.
     * @param overrideConfig The override configuration of activity. It is used to override
     *                       application configuration. If it is non-null, it means the token is
     *                       confirmed as activity token. Especially when launching new activity,
     *                       {@link #mActivities} hasn't put the new token.
     */
    private void handleFixedRotationAdjustments(@NonNull IBinder token,
            @Nullable FixedRotationAdjustments fixedRotationAdjustments,
            @Nullable Configuration overrideConfig) {
        // The element of application configuration override is set only if the application
        // adjustments are needed, because activity already has its own override configuration.
        final Configuration[] appConfigOverride;
        final Consumer<DisplayAdjustments> override;
        if (fixedRotationAdjustments != null) {
            appConfigOverride = new Configuration[1];
            override = displayAdjustments -> {
                displayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments);
                if (appConfigOverride[0] != null) {
                    displayAdjustments.getConfiguration().updateFrom(appConfigOverride[0]);
                }
            };
        } else {
            appConfigOverride = null;
            override = null;
        }
    @Override
    public void handleFixedRotationAdjustments(@NonNull IBinder token,
            @Nullable FixedRotationAdjustments fixedRotationAdjustments) {
        final Consumer<DisplayAdjustments> override = fixedRotationAdjustments != null
                ? displayAdjustments -> displayAdjustments
                        .setFixedRotationAdjustments(fixedRotationAdjustments)
                : null;
        if (!mResourcesManager.overrideTokenDisplayAdjustments(token, override)) {
            // No resources are associated with the token.
            return;
        }
        if (overrideConfig == null) {
            final ActivityClientRecord r = mActivities.get(token);
            if (r == null) {
                // It is not an activity token. Nothing to do for application.
        if (mActivities.get(token) == null) {
            // Nothing to do for application if it is not an activity token.
            return;
        }
            overrideConfig = r.overrideConfig;
        }
        if (appConfigOverride != null) {
            appConfigOverride[0] = overrideConfig;

        overrideApplicationDisplayAdjustments(token, override);
    }

        // Apply the last override to application resources for compatibility. Because the Resources
        // of Display can be from application, e.g.
        //    applicationContext.getSystemService(DisplayManager.class).getDisplay(displayId)
        // and the deprecated usage:
        //    applicationContext.getSystemService(WindowManager.class).getDefaultDisplay();
    /**
     * Applies the last override to application resources for compatibility. Because the Resources
     * of Display can be from application, e.g.
     *   applicationContext.getSystemService(DisplayManager.class).getDisplay(displayId)
     * and the deprecated usage:
     *   applicationContext.getSystemService(WindowManager.class).getDefaultDisplay();
     *
     * @param token The owner and target of the override.
     * @param override The display adjustments override for application resources. If it is null,
     *                 the override of the token will be removed and pop the last one to use.
     */
    private void overrideApplicationDisplayAdjustments(@NonNull IBinder token,
            @Nullable Consumer<DisplayAdjustments> override) {
        final Consumer<DisplayAdjustments> appOverride;
        if (mActiveRotationAdjustments == null) {
            mActiveRotationAdjustments = new ArrayList<>(2);
@@ -3559,8 +3541,13 @@ public final class ActivityThread extends ClientTransactionHandler {
        // The rotation adjustments must be applied before creating the activity, so the activity
        // can get the adjusted display info during creation.
        if (r.mPendingFixedRotationAdjustments != null) {
            handleFixedRotationAdjustments(r.token, r.mPendingFixedRotationAdjustments,
                    r.overrideConfig);
            // The adjustments should have been set by handleLaunchActivity, so the last one is the
            // override for activity resources.
            if (mActiveRotationAdjustments != null && !mActiveRotationAdjustments.isEmpty()) {
                mResourcesManager.overrideTokenDisplayAdjustments(r.token,
                        mActiveRotationAdjustments.get(
                                mActiveRotationAdjustments.size() - 1).second);
            }
            r.mPendingFixedRotationAdjustments = null;
        }

@@ -3599,6 +3586,13 @@ public final class ActivityThread extends ClientTransactionHandler {
            mProfiler.startProfiling();
        }

        if (r.mPendingFixedRotationAdjustments != null) {
            // The rotation adjustments must be applied before handling configuration, so process
            // level display metrics can be adjusted.
            overrideApplicationDisplayAdjustments(r.token, adjustments ->
                    adjustments.setFixedRotationAdjustments(r.mPendingFixedRotationAdjustments));
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

@@ -5735,7 +5729,15 @@ public final class ActivityThread extends ClientTransactionHandler {
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
                    + config);

            mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
            final Resources appResources = mInitialApplication.getResources();
            if (appResources.hasOverrideDisplayAdjustments()) {
                // The value of Display#getRealSize will be adjusted by FixedRotationAdjustments,
                // but Display#getSize refers to DisplayAdjustments#mConfiguration. So the rotated
                // configuration also needs to set to the adjustments for consistency.
                appResources.getDisplayAdjustments().getConfiguration().updateFrom(config);
            }
            mResourcesManager.applyConfigurationToResourcesLocked(config, compat,
                    appResources.getDisplayAdjustments());
            updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                    mResourcesManager.getConfiguration().getLocales());

@@ -7359,7 +7361,8 @@ public final class ActivityThread extends ClientTransactionHandler {
                // We need to apply this change to the resources immediately, because upon returning
                // the view hierarchy will be informed about it.
                if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
                        null /* compat */)) {
                        null /* compat */,
                        mInitialApplication.getResources().getDisplayAdjustments())) {
                    updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                            mResourcesManager.getConfiguration().getLocales());

+13 −2
Original line number Diff line number Diff line
@@ -1262,12 +1262,18 @@ public class ResourcesManager {
    public final boolean applyConfigurationToResources(@NonNull Configuration config,
            @Nullable CompatibilityInfo compat) {
        synchronized(this) {
            return applyConfigurationToResourcesLocked(config, compat);
            return applyConfigurationToResourcesLocked(config, compat, null /* adjustments */);
        }
    }

    public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config,
            @Nullable CompatibilityInfo compat) {
        return applyConfigurationToResourcesLocked(config, compat, null /* adjustments */);
    }

    /** Applies the global configuration to the managed resources. */
    public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config,
            @Nullable CompatibilityInfo compat, @Nullable DisplayAdjustments adjustments) {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                    "ResourcesManager#applyConfigurationToResourcesLocked");
@@ -1291,6 +1297,11 @@ public class ResourcesManager {
            }

            DisplayMetrics displayMetrics = getDisplayMetrics();
            if (adjustments != null) {
                // Currently the only case where the adjustment takes effect is to simulate placing
                // an app in a rotated display.
                adjustments.adjustGlobalAppMetrics(displayMetrics);
            }
            Resources.updateSystemConfiguration(config, displayMetrics, compat);

            ApplicationPackageManager.configurationChanged();
+31 −9
Original line number Diff line number Diff line
@@ -130,14 +130,16 @@ public class DisplayAdjustments {
        w = metrics.noncompatWidthPixels;
        metrics.noncompatWidthPixels = metrics.noncompatHeightPixels;
        metrics.noncompatHeightPixels = w;
    }

        float x = metrics.xdpi;
        metrics.xdpi = metrics.ydpi;
        metrics.ydpi = x;

        x = metrics.noncompatXdpi;
        metrics.noncompatXdpi = metrics.noncompatYdpi;
        metrics.noncompatYdpi = x;
    /** Adjusts global display metrics that is available to applications. */
    public void adjustGlobalAppMetrics(@NonNull DisplayMetrics metrics) {
        final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
        if (rotationAdjustments == null) {
            return;
        }
        metrics.noncompatWidthPixels = metrics.widthPixels = rotationAdjustments.mAppWidth;
        metrics.noncompatHeightPixels = metrics.heightPixels = rotationAdjustments.mAppHeight;
    }

    /** Returns the adjusted cutout if available. Otherwise the original cutout is returned. */
@@ -178,7 +180,7 @@ public class DisplayAdjustments {

    /**
     * An application can be launched in different rotation than the real display. This class
     * provides the information to adjust the values returned by {@link #Display}.
     * provides the information to adjust the values returned by {@link Display}.
     * @hide
     */
    public static class FixedRotationAdjustments implements Parcelable {
@@ -186,12 +188,24 @@ public class DisplayAdjustments {
        @Surface.Rotation
        final int mRotation;

        /**
         * The rotated {@link DisplayInfo#appWidth}. The value cannot be simply swapped according
         * to rotation because it minus the region of screen decorations.
         */
        final int mAppWidth;

        /** The rotated {@link DisplayInfo#appHeight}. */
        final int mAppHeight;

        /** Non-null if the device has cutout. */
        @Nullable
        final DisplayCutout mRotatedDisplayCutout;

        public FixedRotationAdjustments(@Surface.Rotation int rotation, DisplayCutout cutout) {
        public FixedRotationAdjustments(@Surface.Rotation int rotation, int appWidth, int appHeight,
                DisplayCutout cutout) {
            mRotation = rotation;
            mAppWidth = appWidth;
            mAppHeight = appHeight;
            mRotatedDisplayCutout = cutout;
        }

@@ -199,6 +213,8 @@ public class DisplayAdjustments {
        public int hashCode() {
            int hash = 17;
            hash = hash * 31 + mRotation;
            hash = hash * 31 + mAppWidth;
            hash = hash * 31 + mAppHeight;
            hash = hash * 31 + Objects.hashCode(mRotatedDisplayCutout);
            return hash;
        }
@@ -210,12 +226,14 @@ public class DisplayAdjustments {
            }
            final FixedRotationAdjustments other = (FixedRotationAdjustments) o;
            return mRotation == other.mRotation
                    && mAppWidth == other.mAppWidth && mAppHeight == other.mAppHeight
                    && Objects.equals(mRotatedDisplayCutout, other.mRotatedDisplayCutout);
        }

        @Override
        public String toString() {
            return "FixedRotationAdjustments{rotation=" + Surface.rotationToString(mRotation)
                    + " appWidth=" + mAppWidth + " appHeight=" + mAppHeight
                    + " cutout=" + mRotatedDisplayCutout + "}";
        }

@@ -227,12 +245,16 @@ public class DisplayAdjustments {
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(mRotation);
            dest.writeInt(mAppWidth);
            dest.writeInt(mAppHeight);
            dest.writeTypedObject(
                    new DisplayCutout.ParcelableWrapper(mRotatedDisplayCutout), flags);
        }

        private FixedRotationAdjustments(Parcel in) {
            mRotation = in.readInt();
            mAppWidth = in.readInt();
            mAppHeight = in.readInt();
            final DisplayCutout.ParcelableWrapper cutoutWrapper =
                    in.readTypedObject(DisplayCutout.ParcelableWrapper.CREATOR);
            mRotatedDisplayCutout = cutoutWrapper != null ? cutoutWrapper.get() : null;
+3 −2
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ public class TransactionParcelTests {
        PersistableBundle persistableBundle = new PersistableBundle();
        persistableBundle.putInt("k", 4);
        FixedRotationAdjustments fixedRotationAdjustments = new FixedRotationAdjustments(
                Surface.ROTATION_90, DisplayCutout.NO_CUTOUT);
                Surface.ROTATION_90, 1920, 1080, DisplayCutout.NO_CUTOUT);

        LaunchActivityItem item = LaunchActivityItem.obtain(intent, ident, activityInfo,
                config(), overrideConfig, compat, referrer, null /* voiceInteractor */,
@@ -352,7 +352,8 @@ public class TransactionParcelTests {
        ClientTransaction transaction = ClientTransaction.obtain(new StubAppThread(),
                null /* activityToken */);
        transaction.addCallback(FixedRotationAdjustmentsItem.obtain(new Binder(),
                new FixedRotationAdjustments(Surface.ROTATION_270, DisplayCutout.NO_CUTOUT)));
                new FixedRotationAdjustments(Surface.ROTATION_270, 1920, 1080,
                        DisplayCutout.NO_CUTOUT)));

        writeAndPrepareForReading(transaction);

+14 −4
Original line number Diff line number Diff line
@@ -77,8 +77,10 @@ public class DisplayAdjustmentsTests {
        final int realRotation = Surface.ROTATION_0;
        final int fixedRotation = Surface.ROTATION_90;

        mDisplayAdjustments.setFixedRotationAdjustments(
                new FixedRotationAdjustments(fixedRotation, null /* cutout */));
        final int appWidth = 1080;
        final int appHeight = 1920;
        mDisplayAdjustments.setFixedRotationAdjustments(new FixedRotationAdjustments(
                fixedRotation, appWidth, appHeight, null /* cutout */));

        final int w = 1000;
        final int h = 2000;
@@ -95,13 +97,21 @@ public class DisplayAdjustmentsTests {
        metrics.heightPixels = metrics.noncompatHeightPixels = h;

        final DisplayMetrics flippedMetrics = new DisplayMetrics();
        flippedMetrics.xdpi = flippedMetrics.noncompatXdpi = h;
        // The physical dpi should not be adjusted.
        flippedMetrics.xdpi = flippedMetrics.noncompatXdpi = w;
        flippedMetrics.widthPixels = flippedMetrics.noncompatWidthPixels = h;
        flippedMetrics.ydpi = flippedMetrics.noncompatYdpi = w;
        flippedMetrics.ydpi = flippedMetrics.noncompatYdpi = h;
        flippedMetrics.heightPixels = flippedMetrics.noncompatHeightPixels = w;

        mDisplayAdjustments.adjustMetrics(metrics, realRotation);

        assertEquals(flippedMetrics, metrics);

        mDisplayAdjustments.adjustGlobalAppMetrics(metrics);

        assertEquals(appWidth, metrics.widthPixels);
        assertEquals(appWidth, metrics.noncompatWidthPixels);
        assertEquals(appHeight, metrics.heightPixels);
        assertEquals(appHeight, metrics.noncompatHeightPixels);
    }
}
Loading