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

Commit d4b1d1ee authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Don't send configuration that app doesn't support to it.

If an app doesn't support the current device orientation configuration,
then don't run the app in that configuration. Instead have the run in
the last configuration that it supports.
This mostly fixes transient cases where there is a short window that the
device is switching configuration and the app could be sent the single
incorrect configuration that is quickly corrected

Test: Will be added soon.
Fixes: 36897968
Change-Id: I030a04200fdf33c4c1938bda980ea8c14aa1c736
parent 030107f0
Loading
Loading
Loading
Loading
+24 −8
Original line number Diff line number Diff line
@@ -985,10 +985,18 @@ public class ActivityInfo extends ComponentInfo
     * @hide
     */
    boolean isFixedOrientationLandscape() {
        return screenOrientation == SCREEN_ORIENTATION_LANDSCAPE
                || screenOrientation == SCREEN_ORIENTATION_SENSOR_LANDSCAPE
                || screenOrientation == SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                || screenOrientation == SCREEN_ORIENTATION_USER_LANDSCAPE;
        return isFixedOrientationLandscape(screenOrientation);
    }

    /**
     * Returns true if the activity's orientation is fixed to landscape.
     * @hide
     */
    public static boolean isFixedOrientationLandscape(@ScreenOrientation int orientation) {
        return orientation == SCREEN_ORIENTATION_LANDSCAPE
                || orientation == SCREEN_ORIENTATION_SENSOR_LANDSCAPE
                || orientation == SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                || orientation == SCREEN_ORIENTATION_USER_LANDSCAPE;
    }

    /**
@@ -996,10 +1004,18 @@ public class ActivityInfo extends ComponentInfo
     * @hide
     */
    boolean isFixedOrientationPortrait() {
        return screenOrientation == SCREEN_ORIENTATION_PORTRAIT
                || screenOrientation == SCREEN_ORIENTATION_SENSOR_PORTRAIT
                || screenOrientation == SCREEN_ORIENTATION_REVERSE_PORTRAIT
                || screenOrientation == SCREEN_ORIENTATION_USER_PORTRAIT;
        return isFixedOrientationPortrait(screenOrientation);
    }

    /**
     * Returns true if the activity's orientation is fixed to portrait.
     * @hide
     */
    public static boolean isFixedOrientationPortrait(@ScreenOrientation int orientation) {
        return orientation == SCREEN_ORIENTATION_PORTRAIT
                || orientation == SCREEN_ORIENTATION_SENSOR_PORTRAIT
                || orientation == SCREEN_ORIENTATION_REVERSE_PORTRAIT
                || orientation == SCREEN_ORIENTATION_USER_PORTRAIT;
    }

    /**
+49 −8
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
import static android.content.res.Configuration.EMPTY;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -2222,22 +2224,46 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
    }

    @Override
    void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
        super.onOverrideConfigurationChanged(overrideConfiguration);
        if (mWindowContainerController != null) {
            mWindowContainerController.onOverrideConfigurationChanged(
                    overrideConfiguration, mBounds);
    void onOverrideConfigurationChanged(Configuration newConfig) {
        final Configuration currentConfig = getOverrideConfiguration();
        if (currentConfig.equals(newConfig)) {
            return;
        }
        super.onOverrideConfigurationChanged(newConfig);
        if (mWindowContainerController == null) {
            return;
        }
        mWindowContainerController.onOverrideConfigurationChanged(newConfig, mBounds);
        // TODO(b/36505427): Can we consolidate the call points of onOverrideConfigurationSent()
        // to just use this method instead?
        onOverrideConfigurationSent();
    }
    }

    // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
    private void updateOverrideConfiguration() {
        mTmpConfig.unset();
        computeBounds(mTmpBounds);
        if (mTmpBounds.equals(mBounds)) {
            final ActivityStack stack = getStack();
            if (!mBounds.isEmpty() || task == null || stack == null || !task.mFullscreen) {
                // We don't want to influence the override configuration here if our task is in
                // multi-window mode or there is a bounds specified to calculate the override
                // config. In both of this cases the app should be compatible with whatever the
                // current configuration is or will be.
                return;
            }

            // Currently limited to the top activity for now to avoid situations where non-top
            // visible activity and top might have conflicting requests putting the non-top activity
            // windows in an odd state.
            final ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
            final Configuration parentConfig = getParent().getConfiguration();
            if (top != this || isConfigurationCompatible(parentConfig)) {
                onOverrideConfigurationChanged(mTmpConfig);
            } else if (isConfigurationCompatible(
                    mLastReportedConfiguration.getMergedConfiguration())) {
                onOverrideConfigurationChanged(mLastReportedConfiguration.getMergedConfiguration());
            }
            return;
        }

@@ -2250,6 +2276,21 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
        onOverrideConfigurationChanged(mTmpConfig);
    }

    /** Returns true if the configuration is compatible with this activity. */
    private boolean isConfigurationCompatible(Configuration config) {
        final int orientation = mWindowContainerController != null
                ? mWindowContainerController.getOrientation() : info.screenOrientation;
        if (isFixedOrientationPortrait(orientation)
                && config.orientation != ORIENTATION_PORTRAIT) {
            return false;
        }
        if (isFixedOrientationLandscape(orientation)
                && config.orientation != ORIENTATION_LANDSCAPE) {
            return false;
        }
        return true;
    }

    /**
     * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
     */