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

Commit 8ab172e8 authored by John Spurlock's avatar John Spurlock
Browse files

Add rotation-lock to Quick Settings on phones.

Make the rotation-lock QS tile available for display on phones.

Devices < sw600dp are only allowed to lock rotation to their
natural orientation (i.e. portrait on most phones), so tweak
the QS tile label to make this clear.  e.g. "Locked to Portrait"
instead of "Rotation Locked" on portrait phones.

Simplify RotationLockController now that the sw600 check is no
longer hardcoded in RotationPolicy.

Remove redundant sw600dp check in SystemUI, everything driven
from the RotationPolicy helper, though SystemUI can still
choose not to display the tile at all with a resource config.

Clean up some of the docs in RotationPolicy to make clear the
subtle distinction between the two ways of locking rotation:
 - From Accessibility (locks to natural orientation on all devices)
 - From System UI (locks to natural < sw600dp, else current rotation)

Bug:11062710

Change-Id: I5caa4485c9501315da9fed964d6667d3012b43cb
parent 65048bdc
Loading
Loading
Loading
Loading
+41 −32
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ package com.android.internal.view;

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.Point;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
@@ -26,15 +28,20 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.view.Display;
import android.view.IWindowManager;
import android.view.Surface;
import android.view.WindowManagerGlobal;

import com.android.internal.R;

/**
 * Provides helper functions for configuring the display rotation policy.
 */
public final class RotationPolicy {
    private static final String TAG = "RotationPolicy";
    private static final int CURRENT_ROTATION = -1;
    private static final int NATURAL_ROTATION = Surface.ROTATION_0;

    private RotationPolicy() {
    }
@@ -55,23 +62,33 @@ public final class RotationPolicy {
    }

    /**
     * Returns true if the device supports the rotation-lock toggle feature
     * in the system UI or system bar.
     * Returns the orientation that will be used when locking the orientation from system UI
     * with {@link #setRotationLock}.
     *
     * When the rotation-lock toggle is supported, the "auto-rotate screen" option in
     * Display settings should be hidden, but it should remain available in Accessibility
     * settings.
     * If the device only supports locking to its natural orientation, this will be either
     * Configuration.ORIENTATION_PORTRAIT or Configuration.ORIENTATION_LANDSCAPE,
     * otherwise Configuration.ORIENTATION_UNDEFINED if any orientation is lockable.
     */
    public static boolean isRotationLockToggleSupported(Context context) {
        return isRotationSupported(context)
                && context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
    public static int getRotationLockOrientation(Context context) {
        if (!areAllRotationsAllowed(context)) {
            final Point size = new Point();
            final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
            try {
                wm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, size);
                return size.x < size.y ?
                        Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
            } catch (RemoteException e) {
                Log.w(TAG, "Unable to get the display size");
            }
        }
        return Configuration.ORIENTATION_UNDEFINED;
    }

    /**
     * Returns true if the rotation-lock toggle should be shown in the UI.
     * Returns true if the rotation-lock toggle should be shown in system UI.
     */
    public static boolean isRotationLockToggleVisible(Context context) {
        return isRotationLockToggleSupported(context) &&
        return isRotationSupported(context) &&
                Settings.System.getIntForUser(context.getContentResolver(),
                        Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0,
                        UserHandle.USER_CURRENT) == 0;
@@ -86,50 +103,42 @@ public final class RotationPolicy {
    }

    /**
     * Enables or disables rotation lock.
     *
     * Should be used by the rotation lock toggle.
     * Enables or disables rotation lock from the system UI toggle.
     */
    public static void setRotationLock(Context context, final boolean enabled) {
        Settings.System.putIntForUser(context.getContentResolver(),
                Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0,
                UserHandle.USER_CURRENT);

        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
                    if (enabled) {
                        wm.freezeRotation(-1);
                    } else {
                        wm.thawRotation();
                    }
                } catch (RemoteException exc) {
                    Log.w(TAG, "Unable to save auto-rotate setting");
                }
            }
        });
        final int rotation = areAllRotationsAllowed(context) ? CURRENT_ROTATION : NATURAL_ROTATION;
        setRotationLock(enabled, rotation);
    }

    /**
     * Enables or disables rotation lock and adjusts whether the rotation lock toggle
     * should be hidden for accessibility purposes.
     * Enables or disables natural rotation lock from Accessibility settings.
     *
     * Should be used by Display settings and Accessibility settings.
     * If rotation is locked for accessibility, the system UI toggle is hidden to avoid confusion.
     */
    public static void setRotationLockForAccessibility(Context context, final boolean enabled) {
        Settings.System.putIntForUser(context.getContentResolver(),
                Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0,
                        UserHandle.USER_CURRENT);

        setRotationLock(enabled, NATURAL_ROTATION);
    }

    private static boolean areAllRotationsAllowed(Context context) {
        return context.getResources().getBoolean(R.bool.config_allowAllRotations);
    }

    private static void setRotationLock(final boolean enabled, final int rotation) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
                    if (enabled) {
                        wm.freezeRotation(Surface.ROTATION_0);
                        wm.freezeRotation(rotation);
                    } else {
                        wm.thawRotation();
                    }
+0 −3
Original line number Diff line number Diff line
@@ -29,9 +29,6 @@
    <!-- The number of columns that the top level tiles span in the QuickSettings -->
    <integer name="quick_settings_user_time_settings_tile_span">1</integer>

    <!-- Whether rotation lock shows up in quick settings or not -->
    <bool name="quick_settings_show_rotation_lock">true</bool>

    <!-- Enable the "flip settings" panel -->
    <bool name="config_hasFlipSettingsPanel">false</bool>
</resources>
+1 −4
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@
    <!-- When true, show 1/2G networks as 3G. -->
    <bool name="config_showMin3G">false</bool>

    <!-- Show rotation lock button in phone-style notification panel. -->
    <!-- Show rotation lock toggle in System UI-->
    <bool name="config_showRotationLock">true</bool>

    <!-- Amount of time to hold off before showing the search panel when the user presses home -->
@@ -84,9 +84,6 @@
    <!-- The number of columns that the top level tiles span in the QuickSettings -->
    <integer name="quick_settings_user_time_settings_tile_span">1</integer>

    <!-- Whether rotation lock shows up in quick settings or not -->
    <bool name="quick_settings_show_rotation_lock">false</bool>

    <!-- Whether or not the RSSI tile is capitalized or not. -->
    <bool name="quick_settings_rssi_tile_capitalization">true</bool>

+4 −0
Original line number Diff line number Diff line
@@ -464,6 +464,10 @@
    <string name="quick_settings_rotation_unlocked_label">Auto Rotate</string>
    <!-- QuickSettings: Rotation Locked [CHAR LIMIT=NONE] -->
    <string name="quick_settings_rotation_locked_label">Rotation Locked</string>
    <!-- QuickSettings: Locked to Portrait [CHAR LIMIT=NONE] -->
    <string name="quick_settings_rotation_locked_portrait_label">Locked to Portrait</string>
    <!-- QuickSettings: Locked to Landscape [CHAR LIMIT=NONE] -->
    <string name="quick_settings_rotation_locked_landscape_label">Locked to Landscape</string>
    <!-- QuickSettings: IME [CHAR LIMIT=NONE] -->
    <string name="quick_settings_ime_label">Input Method</string>
    <!-- QuickSettings: Location [CHAR LIMIT=NONE] -->
+4 −1
Original line number Diff line number Diff line
@@ -534,7 +534,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
        mBatteryController = new BatteryController(mContext);
        mNetworkController = new NetworkController(mContext);
        mBluetoothController = new BluetoothController(mContext);
        if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)
                || QuickSettings.DEBUG_GONE_TILES) {
            mRotationLockController = new RotationLockController(mContext);
        }
        final SignalClusterView signalCluster =
                (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);

Loading