diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml index c2f1294d0f1..eaa4a6b498c 100644 --- a/res/xml/display_settings.xml +++ b/res/xml/display_settings.xml @@ -71,7 +71,8 @@ + settings:keywords="@string/keywords_auto_rotate" + settings:controller="com.android.settings.display.AutoRotatePreferenceController"/> buildPreferenceControllers( Context context, Lifecycle lifecycle) { final List controllers = new ArrayList<>(); - controllers.add(new AutoRotatePreferenceController(context, lifecycle)); controllers.add(new CameraGesturePreferenceController(context)); controllers.add(new LiftToWakePreferenceController(context)); controllers.add(new NightDisplayPreferenceController(context)); diff --git a/src/com/android/settings/core/TogglePreferenceController.java b/src/com/android/settings/core/TogglePreferenceController.java index 779775b3ba0..16cb18b7443 100644 --- a/src/com/android/settings/core/TogglePreferenceController.java +++ b/src/com/android/settings/core/TogglePreferenceController.java @@ -48,7 +48,7 @@ public abstract class TogglePreferenceController extends BasePreferenceControlle public abstract boolean setChecked(boolean isChecked); @Override - public final void updateState(Preference preference) { + public void updateState(Preference preference) { if (preference instanceof TwoStatePreference) { ((TwoStatePreference) preference).setChecked(isChecked()); } if (preference instanceof MasterSwitchPreference) { diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java index 2134b882638..596e2c6e3e9 100644 --- a/src/com/android/settings/display/AutoRotatePreferenceController.java +++ b/src/com/android/settings/display/AutoRotatePreferenceController.java @@ -15,59 +15,34 @@ package com.android.settings.display; import android.content.Context; import android.support.v7.preference.Preference; -import android.support.v7.preference.TwoStatePreference; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.view.RotationPolicy; import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.core.TogglePreferenceController; import com.android.settings.overlay.FeatureFactory; -import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; -import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; -public class AutoRotatePreferenceController extends AbstractPreferenceController implements +public class AutoRotatePreferenceController extends TogglePreferenceController implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause { - private static final String KEY_AUTO_ROTATE = "auto_rotate"; private final MetricsFeatureProvider mMetricsFeatureProvider; - private TwoStatePreference mPreference; + private Preference mPreference; private RotationPolicy.RotationPolicyListener mRotationPolicyListener; - public AutoRotatePreferenceController(Context context, Lifecycle lifecycle) { - super(context); + public AutoRotatePreferenceController(Context context, String key) { + super(context, key); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); - if (lifecycle != null) { - lifecycle.addObserver(this); - } - } - - @Override - public String getPreferenceKey() { - return KEY_AUTO_ROTATE; } @Override public void updateState(Preference preference) { - mPreference = (TwoStatePreference) preference; - updatePreference(); - } - - @Override - public boolean isAvailable() { - return RotationPolicy.isRotationLockToggleVisible(mContext); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean locked = !(boolean) newValue; - mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ROTATION_LOCK, - locked); - RotationPolicy.setRotationLock(mContext, locked); - return true; + mPreference = preference; + super.updateState(preference); } @Override @@ -76,7 +51,9 @@ public class AutoRotatePreferenceController extends AbstractPreferenceController mRotationPolicyListener = new RotationPolicy.RotationPolicyListener() { @Override public void onChange() { - updatePreference(); + if (mPreference != null) { + updateState(mPreference); + } } }; } @@ -91,10 +68,23 @@ public class AutoRotatePreferenceController extends AbstractPreferenceController } } - private void updatePreference() { - if (mPreference == null) { - return; - } - mPreference.setChecked(!RotationPolicy.isRotationLocked(mContext)); + @Override + public int getAvailabilityStatus() { + return RotationPolicy.isRotationLockToggleVisible(mContext) + ? AVAILABLE : DISABLED_UNSUPPORTED; + } + + @Override + public boolean isChecked() { + return !RotationPolicy.isRotationLocked(mContext); + } + + @Override + public boolean setChecked(boolean isChecked) { + final boolean isLocked = !isChecked; + mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ROTATION_LOCK, + isLocked); + RotationPolicy.setRotationLock(mContext, isLocked); + return true; } } diff --git a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java index 4795826f778..5815f4216b0 100644 --- a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java @@ -21,7 +21,6 @@ import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.when; -import android.arch.lifecycle.LifecycleOwner; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; @@ -29,10 +28,12 @@ import android.os.UserHandle; import android.provider.Settings; import android.support.v14.preference.SwitchPreference; +import com.android.internal.view.RotationPolicy; +import com.android.settings.core.BasePreferenceController; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowRotationPolicy; import com.android.settings.testutils.shadow.ShadowSystemSettings; -import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.After; import org.junit.Before; @@ -52,8 +53,6 @@ public class AutoRotatePreferenceControllerTest { private Context mContext; @Mock private PackageManager mPackageManager; - private LifecycleOwner mLifecycleOwner; - private Lifecycle mLifecycle; private SwitchPreference mPreference; private ContentResolver mContentResolver; private AutoRotatePreferenceController mController; @@ -63,13 +62,11 @@ public class AutoRotatePreferenceControllerTest { MockitoAnnotations.initMocks(this); FakeFeatureFactory.setupForTest(); mContentResolver = RuntimeEnvironment.application.getContentResolver(); - mLifecycleOwner = () -> mLifecycle; - mLifecycle = new Lifecycle(mLifecycleOwner); mPreference = new SwitchPreference(RuntimeEnvironment.application); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mContext.getContentResolver()).thenReturn(mContentResolver); - mController = new AutoRotatePreferenceController(mContext, mLifecycle); + mController = new AutoRotatePreferenceController(mContext, "auto_rotate"); } @After @@ -81,18 +78,14 @@ public class AutoRotatePreferenceControllerTest { public void isAvailableWhenPolicyAllows() { assertThat(mController.isAvailable()).isFalse(); - when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true); - when(mContext.getResources().getBoolean(anyInt())).thenReturn(true); - Settings.System.putInt(mContentResolver, - Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0); + enableAutoRotationPreference(); assertThat(mController.isAvailable()).isTrue(); } @Test public void updatePreference_settingsIsOff_shouldTurnOffToggle() { - Settings.System.putIntForUser(mContentResolver, - Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT); + disableAutoRotation(); mController.updateState(mPreference); @@ -101,11 +94,77 @@ public class AutoRotatePreferenceControllerTest { @Test public void updatePreference_settingsIsOn_shouldTurnOnToggle() { - Settings.System.putIntForUser(mContentResolver, - Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT); + enableAutoRotation(); mController.updateState(mPreference); assertThat(mPreference.isChecked()).isTrue(); } + + @Test + public void testGetAvailabilityStatus() { + assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController + .DISABLED_UNSUPPORTED); + + enableAutoRotationPreference(); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController + .AVAILABLE); + + disableAutoRotationPreference(); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController + .DISABLED_UNSUPPORTED); + } + + @Test + public void testIsCheck() { + assertThat(mController.isChecked()).isFalse(); + + enableAutoRotation(); + + assertThat(mController.isChecked()).isTrue(); + + disableAutoRotation(); + + assertThat(mController.isChecked()).isFalse(); + } + + @Test + @Config(shadows = {ShadowRotationPolicy.class}) + public void testSetCheck() { + ShadowRotationPolicy.setRotationSupported(true); + + mController.setChecked(false); + assertThat(mController.isChecked()).isFalse(); + assertThat(RotationPolicy.isRotationLocked(mContext)).isTrue(); + + mController.setChecked(true); + assertThat(mController.isChecked()).isTrue(); + assertThat(RotationPolicy.isRotationLocked(mContext)).isFalse(); + } + + private void enableAutoRotationPreference() { + when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true); + when(mContext.getResources().getBoolean(anyInt())).thenReturn(true); + Settings.System.putInt(mContentResolver, + Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0); + } + + private void disableAutoRotationPreference() { + when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true); + when(mContext.getResources().getBoolean(anyInt())).thenReturn(true); + Settings.System.putInt(mContentResolver, + Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 1); + } + + private void enableAutoRotation() { + Settings.System.putIntForUser(mContentResolver, + Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT); + } + + private void disableAutoRotation() { + Settings.System.putIntForUser(mContentResolver, + Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRotationPolicy.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRotationPolicy.java new file mode 100644 index 00000000000..47566cc34a7 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRotationPolicy.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils.shadow; + +import android.content.Context; + +import com.android.internal.view.RotationPolicy; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(RotationPolicy.class) +public class ShadowRotationPolicy { + private static boolean rotationLockEnabled = false; + private static boolean rotationSupported = true; + @Implementation + public static void setRotationLock(Context context, final boolean enabled) { + rotationLockEnabled = enabled; + } + + @Implementation + public static boolean isRotationLocked(Context context) { + return rotationLockEnabled; + } + + @Implementation + public static boolean isRotationSupported(Context context) { + return rotationSupported; + } + + public static void setRotationSupported(boolean supported) { + rotationSupported = supported; + } +}