diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml index d9c61b59e6a..9bba489f3ee 100644 --- a/res/xml/accessibility_settings.xml +++ b/res/xml/accessibility_settings.xml @@ -97,7 +97,8 @@ + android:persistent="false" + settings:controller="com.android.settings.accessibility.LockScreenRotationPreferenceController"/> mCategoryToPrefCategoryMap = new ArrayMap<>(); private final Map mServicePreferenceToPreferenceCategoryMap = @@ -249,6 +240,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements private DarkUIPreferenceController mDarkUIPreferenceController; private LiveCaptionPreferenceController mLiveCaptionPreferenceController; + private LockScreenRotationPreferenceController mLockScreenRotationPreferenceController; + private int mLongPressTimeoutDefault; private DevicePolicyManager mDpm; @@ -318,20 +311,12 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false); mSettingsContentObserver.register(getContentResolver()); - if (RotationPolicy.isRotationSupported(getActivity())) { - RotationPolicy.registerRotationPolicyListener(getActivity(), - mRotationPolicyListener); - } } @Override public void onPause() { mSettingsPackageMonitor.unregister(); mSettingsContentObserver.unregister(getContentResolver()); - if (RotationPolicy.isRotationSupported(getActivity())) { - RotationPolicy.unregisterRotationPolicyListener(getActivity(), - mRotationPolicyListener); - } super.onPause(); } @@ -359,9 +344,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements } else if (mTogglePowerButtonEndsCallPreference == preference) { handleTogglePowerButtonEndsCallPreferenceClick(); return true; - } else if (mToggleLockScreenRotationPreference == preference) { - handleLockScreenRotationPreferenceClick(); - return true; } else if (mToggleLargePointerIconPreference == preference) { handleToggleLargePointerIconPreferenceClick(); return true; @@ -415,11 +397,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF)); } - private void handleLockScreenRotationPreferenceClick() { - RotationPolicy.setRotationLockForAccessibility(getActivity(), - !mToggleLockScreenRotationPreference.isChecked()); - } - private void handleToggleLargePointerIconPreferenceClick() { Settings.Secure.putInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, @@ -465,12 +442,11 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements } // Lock screen rotation. - mToggleLockScreenRotationPreference = - (SwitchPreference) findPreference(TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE); - if (!RotationPolicy.isRotationSupported(getActivity())) { - mCategoryToPrefCategoryMap.get(CATEGORY_INTERACTION_CONTROL) - .removePreference(mToggleLockScreenRotationPreference); - } + mToggleLockScreenRotationPreference = findPreference( + TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE); + mLockScreenRotationPreferenceController = new LockScreenRotationPreferenceController( + getContext(), TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE); + mLockScreenRotationPreferenceController.displayPreference(getPreferenceScreen()); // Large pointer icon. mToggleLargePointerIconPreference = @@ -765,7 +741,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements } // Auto-rotate screen - updateLockScreenRotationCheckbox(); + mLockScreenRotationPreferenceController.updateState(mToggleLockScreenRotationPreference); // Large pointer icon. mToggleLargePointerIconPreference.setChecked(Settings.Secure.getInt(getContentResolver(), @@ -941,14 +917,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements } } - private void updateLockScreenRotationCheckbox() { - Context context = getActivity(); - if (context != null) { - mToggleLockScreenRotationPreference.setChecked( - !RotationPolicy.isRotationLocked(context)); - } - } - private void updateDisableAnimationsToggle() { boolean allAnimationsDisabled = true; for (String animationSetting : TOGGLE_ANIMATION_TARGETS) { diff --git a/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java b/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java new file mode 100644 index 00000000000..a82b6e2bb20 --- /dev/null +++ b/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2019 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.accessibility; + +import android.content.Context; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.internal.view.RotationPolicy; +import com.android.internal.view.RotationPolicy.RotationPolicyListener; +import com.android.settings.core.TogglePreferenceController; +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 LockScreenRotationPreferenceController extends TogglePreferenceController implements + LifecycleObserver, OnPause, OnResume { + + private Preference mPreference; + private RotationPolicyListener mRotationPolicyListener; + + public LockScreenRotationPreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + /** + * Returns true if rotation lock is enabled. + */ + @Override + public boolean isChecked() { + return !RotationPolicy.isRotationLocked(mContext); + } + + /** + * Enables or disables screen rotation lock from Accessibility settings. If rotation is locked + * for accessibility, the toggle in Display settings is hidden to avoid confusion. + */ + @Override + public boolean setChecked(boolean isChecked) { + RotationPolicy.setRotationLockForAccessibility(mContext, !isChecked); + return true; + } + + @Override + public int getAvailabilityStatus() { + return RotationPolicy.isRotationSupported(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } + + @Override + public void onPause() { + if (mRotationPolicyListener != null) { + RotationPolicy.unregisterRotationPolicyListener(mContext, mRotationPolicyListener); + } + } + + @Override + public void onResume() { + if (mRotationPolicyListener == null) { + mRotationPolicyListener = new RotationPolicyListener() { + @Override + public void onChange() { + if (mPreference != null) { + updateState(mPreference); + } + } + }; + } + RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + mPreference = screen.findPreference(getPreferenceKey()); + super.displayPreference(screen); + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java new file mode 100644 index 00000000000..ef8f569e4fd --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2019 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.accessibility; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; + +import androidx.preference.SwitchPreference; + +import com.android.internal.view.RotationPolicy; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.testutils.shadow.ShadowRotationPolicy; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +public class LockScreenRotationPreferenceControllerTest { + + private Context mContext; + private SwitchPreference mPreference; + private LockScreenRotationPreferenceController mController; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mPreference = new SwitchPreference(mContext); + mController = new LockScreenRotationPreferenceController(mContext, "lock_screen"); + } + + @Test + @Config(shadows = {ShadowRotationPolicy.class}) + public void getAvailabilityStatus_supportedRotation_shouldReturnAvailable() { + ShadowRotationPolicy.setRotationSupported(true /* supported */); + + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.AVAILABLE); + } + + @Test + @Config(shadows = {ShadowRotationPolicy.class}) + public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() { + ShadowRotationPolicy.setRotationSupported(false /* supported */); + + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + @Config(shadows = {ShadowRotationPolicy.class}) + public void setChecked_enabled() { + mController.setChecked(true /* isChecked */); + + assertThat(mController.isChecked()).isTrue(); + assertThat(RotationPolicy.isRotationLocked(mContext)).isFalse(); + } + + @Test + @Config(shadows = {ShadowRotationPolicy.class}) + public void setChecked_disabled() { + mController.setChecked(false /* isChecked */); + + assertThat(mController.isChecked()).isFalse(); + assertThat(RotationPolicy.isRotationLocked(mContext)).isTrue(); + } + + @Test + public void updateState_settingIsOn_shouldTurnOnToggle() { + Settings.System.putIntForUser(mContext.getContentResolver(), + Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT); + + mController.updateState(mPreference); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void updateState_settingIsOff_shouldTurnOffToggle() { + Settings.System.putIntForUser(mContext.getContentResolver(), + Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT); + + mController.updateState(mPreference); + + assertThat(mPreference.isChecked()).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRotationPolicy.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRotationPolicy.java index a99c80e665d..1f1e2be0171 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRotationPolicy.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRotationPolicy.java @@ -34,6 +34,11 @@ public class ShadowRotationPolicy { rotationLockEnabled = enabled; } + @Implementation + protected static void setRotationLockForAccessibility(Context context, final boolean enabled) { + rotationLockEnabled = enabled; + } + @Implementation protected static boolean isRotationLocked(Context context) { return rotationLockEnabled;