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

Commit 73013990 authored by Garfield Tan's avatar Garfield Tan Committed by Android (Google) Code Review
Browse files

Merge "Persist user rotations of external displays."

parents 74494b51 90c9005e
Loading
Loading
Loading
Loading
+33 −8
Original line number Diff line number Diff line
@@ -226,25 +226,50 @@ interface IWindowManager
    int getPreferredOptionsPanelGravity(int displayId);

    /**
     * Lock the device orientation to the specified rotation, or to the
     * current rotation if -1.  Sensor input will be ignored until
     * thawRotation() is called.
     * @hide
     * Equivalent to calling {@link #freezeDisplayRotation(int, int)} with {@link
     * android.view.Display#DEFAULT_DISPLAY} and given rotation.
     */
    void freezeRotation(int rotation);

    /**
     * Release the orientation lock imposed by freezeRotation().
     * @hide
     * Equivalent to calling {@link #thawDisplayRotation(int)} with {@link
     * android.view.Display#DEFAULT_DISPLAY}.
     */
    void thawRotation();

    /**
     * Gets whether the rotation is frozen.
     * Equivelant to call {@link #isDisplayRotationFrozen(int)} with {@link
     * android.view.Display#DEFAULT_DISPLAY}.
     */
    boolean isRotationFrozen();

    /**
     * Lock the display orientation to the specified rotation, or to the current
     * rotation if -1. Sensor input will be ignored until thawRotation() is called.
     *
     * @param displayId the ID of display which rotation should be frozen.
     * @param rotation one of {@link android.view.Surface#ROTATION_0},
     *        {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
     *        {@link android.view.Surface#ROTATION_270} or -1 to freeze it to current rotation.
     * @hide
     */
    void freezeDisplayRotation(int displayId, int rotation);

    /**
     * Release the orientation lock imposed by freezeRotation() on the display.
     *
     * @param displayId the ID of display which rotation should be thawed.
     * @hide
     */
    void thawDisplayRotation(int displayId);

    /**
     * Gets whether the rotation is frozen on the display.
     *
     * @param displayId the ID of display which frozen is needed.
     * @return Whether the rotation is frozen.
     */
    boolean isRotationFrozen();
    boolean isDisplayRotationFrozen(int displayId);

    /**
     * Screenshot the current wallpaper layer, including the whole screen.
+0 −31
Original line number Diff line number Diff line
@@ -6863,37 +6863,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        PhoneWindow.sendCloseSystemWindows(mContext, reason);
    }

    @Override
    public int getUserRotationMode() {
        return Settings.System.getIntForUser(mContext.getContentResolver(),
                Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
                        WindowManagerPolicy.USER_ROTATION_FREE :
                                WindowManagerPolicy.USER_ROTATION_LOCKED;
    }

    // User rotation: to be used when all else fails in assigning an orientation to the device
    @Override
    public void setUserRotationMode(int mode, int rot) {
        ContentResolver res = mContext.getContentResolver();

        // mUserRotationMode and mUserRotation will be assigned by the content observer
        if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
            Settings.System.putIntForUser(res,
                    Settings.System.USER_ROTATION,
                    rot,
                    UserHandle.USER_CURRENT);
            Settings.System.putIntForUser(res,
                    Settings.System.ACCELEROMETER_ROTATION,
                    0,
                    UserHandle.USER_CURRENT);
        } else {
            Settings.System.putIntForUser(res,
                    Settings.System.ACCELEROMETER_ROTATION,
                    1,
                    UserHandle.USER_CURRENT);
        }
    }

    @Override
    public void setSafeMode(boolean safeMode) {
        mSafeMode = safeMode;
+0 −21
Original line number Diff line number Diff line
@@ -82,7 +82,6 @@ import android.view.IApplicationToken;
import android.view.IWindowManager;
import android.view.InputEventReceiver;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants;
@@ -1482,26 +1481,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     */
    public void keepScreenOnStoppedLw();

    /**
     * Gets the current user rotation mode.
     *
     * @return The rotation mode.
     *
     * @see #USER_ROTATION_LOCKED
     * @see #USER_ROTATION_FREE
     */
    @UserRotationMode
    public int getUserRotationMode();

    /**
     * Inform the policy that the user has chosen a preferred orientation ("rotation lock").
     *
     * @param mode One of {@link #USER_ROTATION_LOCKED} or {@link #USER_ROTATION_FREE}.
     * @param rotation One of {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
     *                 {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
     */
    public void setUserRotationMode(@UserRotationMode int mode, @Surface.Rotation int rotation);

    /**
     * Called when a new system UI visibility is being reported, allowing
     * the policy to adjust what is actually reported.
+68 −5
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ public class DisplayRotation {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayRotation" : TAG_WM;

    private final WindowManagerService mService;
    private final DisplayContent mDisplayContent;
    private final DisplayPolicy mDisplayPolicy;
    private final Context mContext;
    private final Object mLock;
@@ -106,6 +107,7 @@ public class DisplayRotation {
    DisplayRotation(WindowManagerService service, DisplayContent displayContent,
            DisplayPolicy displayPolicy, Context context, Object lock) {
        mService = service;
        mDisplayContent = displayContent;
        mDisplayPolicy = displayPolicy;
        mContext = context;
        mLock = lock;
@@ -225,6 +227,70 @@ public class DisplayRotation {
        }
    }

    void restoreUserRotation(int userRotationMode, int userRotation) {
        if (userRotationMode != WindowManagerPolicy.USER_ROTATION_FREE
                && userRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) {
            Slog.w(TAG, "Trying to restore an invalid user rotation mode " + userRotationMode
                    + " for " + mDisplayContent);
            userRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
        }
        if (userRotation < Surface.ROTATION_0 || userRotation > Surface.ROTATION_270) {
            Slog.w(TAG, "Trying to restore an invalid user rotation " + userRotation
                    + " for " + mDisplayContent);
            userRotation = Surface.ROTATION_0;
        }
        mUserRotationMode = userRotationMode;
        mUserRotation = userRotation;
    }

    private void setUserRotation(int userRotationMode, int userRotation) {
        if (isDefaultDisplay) {
            // We'll be notified via settings listener, so we don't need to update internal values.
            final ContentResolver res = mContext.getContentResolver();
            final int accelerometerRotation =
                    userRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED ? 0 : 1;
            Settings.System.putIntForUser(res, Settings.System.ACCELEROMETER_ROTATION,
                    accelerometerRotation, UserHandle.USER_CURRENT);
            Settings.System.putIntForUser(res, Settings.System.USER_ROTATION, userRotation,
                    UserHandle.USER_CURRENT);
            return;
        }

        boolean changed = false;
        if (mUserRotationMode != userRotationMode) {
            mUserRotationMode = userRotationMode;
            changed = true;
        }
        if (mUserRotation != userRotation) {
            mUserRotation = userRotation;
            changed = true;
        }
        mService.mDisplaySettings.setUserRotation(mDisplayContent, userRotationMode, userRotation);
        if (changed) {
            mService.updateRotation(true /* alwaysSendConfiguration */,
                    false /* forceRelayout */);
            mService.mDisplaySettings.writeSettingsLocked();
        }
    }

    void freezeRotation(int rotation) {
        rotation = (rotation == -1) ? mDisplayContent.getRotation() : rotation;
        setUserRotation(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation);
    }

    void thawRotation() {
        setUserRotation(WindowManagerPolicy.USER_ROTATION_FREE, mUserRotation);
    }

    boolean isRotationFrozen() {
        if (!isDefaultDisplay) {
            return mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED;
        }

        return Settings.System.getIntForUser(mContext.getContentResolver(),
                Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) == 0;
    }

    /** @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true. */
    boolean isDefaultOrientationForced() {
        return mForceDefaultOrientation;
@@ -381,9 +447,6 @@ public class DisplayRotation {
     * @param orientation An orientation constant, such as
     * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
     * @param lastRotation The most recently used rotation.
     * @param defaultDisplay Flag indicating whether the rotation is computed for the default
     *                       display. Currently for all non-default displays sensors, docking mode,
     *                       rotation lock and other factors are ignored.
     * @return The surface rotation to use.
     */
    int rotationForOrientation(int orientation, int lastRotation) {
@@ -418,8 +481,8 @@ public class DisplayRotation {
        final int preferredRotation;
        if (!isDefaultDisplay) {
            // For secondary displays we ignore things like displays sensors, docking mode and
            // rotation lock, and always prefer a default rotation.
            preferredRotation = Surface.ROTATION_0;
            // rotation lock, and always prefer user rotation.
            preferredRotation = mUserRotation;
        } else if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
            // Ignore sensor when lid switch is open and rotation is forced.
            preferredRotation = mLidOpenRotation;
+113 −50
Original line number Diff line number Diff line
@@ -20,20 +20,23 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.app.WindowConfiguration;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Environment;
import android.provider.Settings;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.server.policy.WindowManagerPolicy;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.File;
import java.io.FileInputStream;
@@ -43,10 +46,6 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

/**
 * Current persistent settings about a display
 */
@@ -58,15 +57,25 @@ class DisplaySettings {
    private final HashMap<String, Entry> mEntries = new HashMap<String, Entry>();

    private static class Entry {
        private final String name;
        private int overscanLeft;
        private int overscanTop;
        private int overscanRight;
        private int overscanBottom;
        private int windowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
        private final String mName;
        private int mOverscanLeft;
        private int mOverscanTop;
        private int mOverscanRight;
        private int mOverscanBottom;
        private int mWindowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
        private int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
        private int mUserRotation = Surface.ROTATION_0;

        private Entry(String _name) {
            name = _name;
            mName = _name;
        }

        private boolean isEmpty() {
            return mOverscanLeft == 0 && mOverscanTop == 0 && mOverscanRight == 0
                    && mOverscanBottom == 0
                    && mWindowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED
                    && mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
                    && mUserRotation == Surface.ROTATION_0;
        }
    }

@@ -90,13 +99,30 @@ class DisplaySettings {
        return entry;
    }

    private Entry getOrCreateEntry(String uniqueId, String name) {
        Entry entry = getEntry(uniqueId, name);
        if (entry == null) {
            entry = new Entry(uniqueId);
            mEntries.put(uniqueId, entry);
        }
        return entry;
    }

    private void removeEntryIfEmpty(String uniqueId, String name) {
        final Entry entry = getEntry(uniqueId, name);
        if (entry.isEmpty()) {
            mEntries.remove(uniqueId);
            mEntries.remove(name);
        }
    }

    private void getOverscanLocked(String name, String uniqueId, Rect outRect) {
        final Entry entry = getEntry(name, uniqueId);
        if (entry != null) {
            outRect.left = entry.overscanLeft;
            outRect.top = entry.overscanTop;
            outRect.right = entry.overscanRight;
            outRect.bottom = entry.overscanBottom;
            outRect.left = entry.mOverscanLeft;
            outRect.top = entry.mOverscanTop;
            outRect.right = entry.mOverscanRight;
            outRect.bottom = entry.mOverscanBottom;
        } else {
            outRect.set(0, 0, 0, 0);
        }
@@ -104,28 +130,22 @@ class DisplaySettings {

    void setOverscanLocked(String uniqueId, String name, int left, int top, int right,
            int bottom) {
        if (left == 0 && top == 0 && right == 0 && bottom == 0) {
            // Right now all we are storing is overscan; if there is no overscan,
            // we have no need for the entry.
            mEntries.remove(uniqueId);
            // Legacy name might have been in used, so we need to clear it.
            mEntries.remove(name);
            return;
        }
        Entry entry = mEntries.get(uniqueId);
        if (entry == null) {
            entry = new Entry(uniqueId);
            mEntries.put(uniqueId, entry);
        if (left == 0 && top == 0 && right == 0 && bottom == 0 && entry == null) {
            // All default value, no action needed.
            return;
        }
        entry.overscanLeft = left;
        entry.overscanTop = top;
        entry.overscanRight = right;
        entry.overscanBottom = bottom;
        entry = getOrCreateEntry(uniqueId, name);
        entry.mOverscanLeft = left;
        entry.mOverscanTop = top;
        entry.mOverscanRight = right;
        entry.mOverscanBottom = bottom;
        removeEntryIfEmpty(uniqueId, name);
    }

    private int getWindowingModeLocked(String name, String uniqueId, int displayId) {
        final Entry entry = getEntry(name, uniqueId);
        int windowingMode = entry != null ? entry.windowingMode
        int windowingMode = entry != null ? entry.mWindowingMode
                : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
        // This display used to be in freeform, but we don't support freeform anymore, so fall
        // back to fullscreen.
@@ -148,6 +168,36 @@ class DisplaySettings {
        return windowingMode;
    }

    void setUserRotation(DisplayContent dc, int rotationMode, int rotation) {
        final DisplayInfo displayInfo = dc.getDisplayInfo();

        final String uniqueId = displayInfo.uniqueId;
        final String name = displayInfo.name;
        Entry entry = getEntry(displayInfo.name, uniqueId);
        if (rotationMode == WindowManagerPolicy.USER_ROTATION_FREE
                && rotation == Surface.ROTATION_0 && entry == null) {
            // All default values. No action needed.
            return;
        }

        entry = getOrCreateEntry(uniqueId, name);
        entry.mUserRotationMode = rotationMode;
        entry.mUserRotation = rotation;
        removeEntryIfEmpty(uniqueId, name);
    }

    private void restoreUserRotation(DisplayContent dc) {
        final DisplayInfo info = dc.getDisplayInfo();

        final Entry entry = getEntry(info.name, info.uniqueId);
        final int userRotationMode = entry != null ? entry.mUserRotationMode
                : WindowManagerPolicy.USER_ROTATION_FREE;
        final int userRotation = entry != null ? entry.mUserRotation
                : Surface.ROTATION_0;

        dc.getDisplayRotation().restoreUserRotation(userRotationMode, userRotation);
    }

    void applySettingsToDisplayLocked(DisplayContent dc) {
        final DisplayInfo displayInfo = dc.getDisplayInfo();

@@ -161,6 +211,8 @@ class DisplaySettings {
        displayInfo.overscanTop = rect.top;
        displayInfo.overscanRight = rect.right;
        displayInfo.overscanBottom = rect.bottom;

        restoreUserRotation(dc);
    }

    void readSettingsLocked() {
@@ -244,12 +296,16 @@ class DisplaySettings {
        String name = parser.getAttributeValue(null, "name");
        if (name != null) {
            Entry entry = new Entry(name);
            entry.overscanLeft = getIntAttribute(parser, "overscanLeft");
            entry.overscanTop = getIntAttribute(parser, "overscanTop");
            entry.overscanRight = getIntAttribute(parser, "overscanRight");
            entry.overscanBottom = getIntAttribute(parser, "overscanBottom");
            entry.windowingMode = getIntAttribute(parser, "windowingMode",
            entry.mOverscanLeft = getIntAttribute(parser, "overscanLeft");
            entry.mOverscanTop = getIntAttribute(parser, "overscanTop");
            entry.mOverscanRight = getIntAttribute(parser, "overscanRight");
            entry.mOverscanBottom = getIntAttribute(parser, "overscanBottom");
            entry.mWindowingMode = getIntAttribute(parser, "windowingMode",
                    WindowConfiguration.WINDOWING_MODE_UNDEFINED);
            entry.mUserRotationMode = getIntAttribute(parser, "userRotationMode",
                    WindowManagerPolicy.USER_ROTATION_FREE);
            entry.mUserRotation = getIntAttribute(parser, "userRotation",
                    Surface.ROTATION_0);
            mEntries.put(name, entry);
        }
        XmlUtils.skipCurrentTag(parser);
@@ -272,21 +328,28 @@ class DisplaySettings {

            for (Entry entry : mEntries.values()) {
                out.startTag(null, "display");
                out.attribute(null, "name", entry.name);
                if (entry.overscanLeft != 0) {
                    out.attribute(null, "overscanLeft", Integer.toString(entry.overscanLeft));
                out.attribute(null, "name", entry.mName);
                if (entry.mOverscanLeft != 0) {
                    out.attribute(null, "overscanLeft", Integer.toString(entry.mOverscanLeft));
                }
                if (entry.mOverscanTop != 0) {
                    out.attribute(null, "overscanTop", Integer.toString(entry.mOverscanTop));
                }
                if (entry.mOverscanRight != 0) {
                    out.attribute(null, "overscanRight", Integer.toString(entry.mOverscanRight));
                }
                if (entry.overscanTop != 0) {
                    out.attribute(null, "overscanTop", Integer.toString(entry.overscanTop));
                if (entry.mOverscanBottom != 0) {
                    out.attribute(null, "overscanBottom", Integer.toString(entry.mOverscanBottom));
                }
                if (entry.overscanRight != 0) {
                    out.attribute(null, "overscanRight", Integer.toString(entry.overscanRight));
                if (entry.mWindowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
                    out.attribute(null, "windowingMode", Integer.toString(entry.mWindowingMode));
                }
                if (entry.overscanBottom != 0) {
                    out.attribute(null, "overscanBottom", Integer.toString(entry.overscanBottom));
                if (entry.mUserRotationMode != WindowManagerPolicy.USER_ROTATION_FREE) {
                    out.attribute(null, "userRotationMode",
                            Integer.toString(entry.mUserRotationMode));
                }
                if (entry.windowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
                    out.attribute(null, "windowingMode", Integer.toString(entry.windowingMode));
                if (entry.mUserRotation != Surface.ROTATION_0) {
                    out.attribute(null, "userRotation", Integer.toString(entry.mUserRotation));
                }
                out.endTag(null, "display");
            }
Loading