Implement new rotation policy.

Show "auto-rotate screen" option in Display only if the Rotation Lock
feature is not available on the device.

When the "auto-rotate screen" option is disabled in Accessibility or
Display settings, hide the Rotation Lock feature.

Use new RotationPolicy class to adjust rotation settings.

Bug: 6523269
Change-Id: Ifa89ff055e5ad0a00888e10720dd76b0054fe290
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
index d2bfc0d..149e336 100644
--- a/src/com/android/settings/AccessibilitySettings.java
+++ b/src/com/android/settings/AccessibilitySettings.java
@@ -36,7 +36,6 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
@@ -45,18 +44,14 @@
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
 import android.text.TextUtils;
 import android.text.TextUtils.SimpleStringSplitter;
-import android.util.Log;
 import android.view.Gravity;
-import android.view.IWindowManager;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.Surface;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -65,6 +60,7 @@
 import android.widget.TextView;
 
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.view.RotationPolicy;
 import com.android.settings.AccessibilitySettings.ToggleSwitch.OnBeforeCheckedChangeListener;
 
 import java.util.HashMap;
@@ -78,8 +74,6 @@
  */
 public class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable,
         Preference.OnPreferenceChangeListener {
-    private static final String TAG = "AccessibilitySettings";
-
     private static final String DEFAULT_SCREENREADER_MARKET_LINK =
         "market://search?q=pname:com.google.android.marvin.talkback";
 
@@ -151,22 +145,11 @@
         }
     };
 
-    private final Uri mLockScreenRotationUri = Uri.withAppendedPath(Settings.System.CONTENT_URI,
-            Settings.System.ACCELEROMETER_ROTATION);
-
-    private final ContentObserver mSettingsContentObserver = new ContentObserver(mHandler) {
+    private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
+            new RotationPolicy.RotationPolicyListener() {
         @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (mLockScreenRotationUri.equals(uri)) {
-                try {
-                    final boolean lockRotationEnabled = (Settings.System.getInt(
-                            getActivity().getContentResolver(),
-                            Settings.System.ACCELEROMETER_ROTATION) == 0);
-                    mToggleLockScreenRotationPreference.setChecked(lockRotationEnabled);
-                } catch (SettingNotFoundException e) {
-                    /* ignore */
-                }
-            }
+        public void onChange() {
+            updateLockScreenRotationCheckbox();
         }
     };
 
@@ -200,14 +183,15 @@
             offerInstallAccessibilitySerivceOnce();
         }
         mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
-        getActivity().getContentResolver().registerContentObserver(mLockScreenRotationUri, false,
-                mSettingsContentObserver);
+        RotationPolicy.registerRotationPolicyListener(getActivity(),
+                mRotationPolicyListener);
     }
 
     @Override
     public void onPause() {
         mSettingsPackageMonitor.unregister();
-        getContentResolver().unregisterContentObserver(mSettingsContentObserver);
+        RotationPolicy.unregisterRotationPolicyListener(getActivity(),
+                mRotationPolicyListener);
         super.onPause();
     }
 
@@ -258,17 +242,8 @@
     }
 
     private void handleLockScreenRotationPreferenceClick() {
-        try {
-            IWindowManager wm = IWindowManager.Stub.asInterface(
-                    ServiceManager.getService(Context.WINDOW_SERVICE));
-            if (!mToggleLockScreenRotationPreference.isChecked()) {
-                wm.thawRotation();
-            } else {
-                wm.freezeRotation(Surface.ROTATION_0);
-            }
-        } catch (RemoteException exc) {
-            Log.w(TAG, "Unable to save auto-rotate setting");
-        }
+        RotationPolicy.setRotationLockForAccessibility(getActivity(),
+                !mToggleLockScreenRotationPreference.isChecked());
     }
 
     private void handleToggleSpeakPasswordPreferenceClick() {
@@ -453,9 +428,7 @@
         }
 
         // Auto-rotate screen
-        final boolean lockRotationEnabled = Settings.System.getInt(getContentResolver(),
-                Settings.System.ACCELEROMETER_ROTATION, 0) != 1;
-        mToggleLockScreenRotationPreference.setChecked(lockRotationEnabled);
+        updateLockScreenRotationCheckbox();
 
         // Speak passwords.
         final boolean speakPasswordEnabled = Settings.Secure.getInt(getContentResolver(),
@@ -475,6 +448,11 @@
         mToggleScriptInjectionPreference.setInjectionAllowed(scriptInjectionAllowed);
     }
 
+    private void updateLockScreenRotationCheckbox() {
+        mToggleLockScreenRotationPreference.setChecked(
+                !RotationPolicy.isRotationLocked(getActivity()));
+    }
+
     private void offerInstallAccessibilitySerivceOnce() {
         // There is always one preference - if no services it is just a message.
         if (mServicesCategory.getPreference(0) != mNoServicesMessagePreference) {
diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java
index df80f85..fc162e2 100644
--- a/src/com/android/settings/DisplaySettings.java
+++ b/src/com/android/settings/DisplaySettings.java
@@ -24,11 +24,8 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.database.ContentObserver;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
@@ -36,9 +33,8 @@
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
-import android.view.IWindowManager;
-import android.view.Surface;
 
+import com.android.internal.view.RotationPolicy;
 import com.android.settings.DreamSettings;
 
 import java.util.ArrayList;
@@ -65,9 +61,10 @@
     private ListPreference mScreenTimeoutPreference;
     private Preference mScreenSaverPreference;
 
-    private ContentObserver mAccelerometerRotationObserver = new ContentObserver(new Handler()) {
+    private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
+            new RotationPolicy.RotationPolicyListener() {
         @Override
-        public void onChange(boolean selfChange) {
+        public void onChange() {
             updateAccelerometerRotationCheckbox();
         }
     };
@@ -81,6 +78,11 @@
 
         mAccelerometer = (CheckBoxPreference) findPreference(KEY_ACCELEROMETER);
         mAccelerometer.setPersistent(false);
+        if (RotationPolicy.isRotationLockToggleSupported(getActivity())) {
+            // If rotation lock is supported, then we do not provide this option in
+            // Display settings.  However, is still available in Accessibility settings.
+            getPreferenceScreen().removePreference(mAccelerometer);
+        }
 
         mScreenSaverPreference = findPreference(KEY_SCREEN_SAVER);
         if (mScreenSaverPreference != null
@@ -210,16 +212,17 @@
         super.onResume();
 
         updateState();
-        getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), true,
-                mAccelerometerRotationObserver);
+
+        RotationPolicy.registerRotationPolicyListener(getActivity(),
+                mRotationPolicyListener);
     }
 
     @Override
     public void onPause() {
         super.onPause();
 
-        getContentResolver().unregisterContentObserver(mAccelerometerRotationObserver);
+        RotationPolicy.unregisterRotationPolicyListener(getActivity(),
+                mRotationPolicyListener);
     }
 
     private void updateState() {
@@ -237,9 +240,8 @@
 
     private void updateAccelerometerRotationCheckbox() {
         if (getActivity() == null) return;
-        mAccelerometer.setChecked(Settings.System.getInt(
-                getContentResolver(),
-                Settings.System.ACCELEROMETER_ROTATION, 0) != 0);
+
+        mAccelerometer.setChecked(!RotationPolicy.isRotationLocked(getActivity()));
     }
 
     public void writeFontSizePreference(Object objValue) {
@@ -254,17 +256,8 @@
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
         if (preference == mAccelerometer) {
-            try {
-                IWindowManager wm = IWindowManager.Stub.asInterface(
-                        ServiceManager.getService(Context.WINDOW_SERVICE));
-                if (mAccelerometer.isChecked()) {
-                    wm.thawRotation();
-                } else {
-                    wm.freezeRotation(Surface.ROTATION_0);
-                }
-            } catch (RemoteException exc) {
-                Log.w(TAG, "Unable to save auto-rotate setting");
-            }
+            RotationPolicy.setRotationLockForAccessibility(
+                    getActivity(), !mAccelerometer.isChecked());
         } else if (preference == mNotificationPulse) {
             boolean value = mNotificationPulse.isChecked();
             Settings.System.putInt(getContentResolver(), Settings.System.NOTIFICATION_LIGHT_PULSE,