Add support for device state based auto-rotation preferences in Settings.

- Creates new preferences that are shown when device-state rotation
  is supported.
- Hides standard preferences when device-state rotation is supported.
- Controllers/Preferences for individual folded/unfolded rotation
  settings are created and added programatically based on the settable
  device states available.

Test: Manually + Unit tests
Bug: 195757480
Change-Id: I16f50fd3664756b363c7eb79e5c35eb0d3b6df17
This commit is contained in:
Christian Göllner
2022-02-17 11:32:54 +00:00
parent a01477087c
commit ff9065ac95
24 changed files with 1106 additions and 14 deletions

View File

@@ -570,7 +570,19 @@
<item>2</item>
<item>3</item>
</integer-array>
<!-- The settings/preference description for each settable device state defined in the array
"config_perDeviceStateRotationLockDefaults".
The item in position "i" describes the auto-rotation setting for the device state also in
position "i" in the array "config_perDeviceStateRotationLockDefaults". -->
<string-array name="config_settableAutoRotationDeviceStatesDescriptions">
<!-- Example:
<item>Auto-rotate when folded</item>
<item>@null</item> No description for state in position 1
<item>Auto-rotate when unfolded</item>
-->
</string-array>
<!-- Whether to aggregate for network selection list-->
<bool name="config_network_selection_list_aggregation_enabled">false</bool>
@@ -596,4 +608,5 @@
<!-- Whether the dream setup activity should be enabled as part of setupwizard -->
<bool name="dream_setup_supported">false</bool>
</resources>

View File

@@ -42,9 +42,22 @@
android:title="@string/accessibility_power_button_ends_call_prerefence_title"
settings:controller="com.android.settings.accessibility.PowerButtonEndsCallPreferenceController"/>
<!-- Standard auto-rotation preference that will be shown when device state based auto-rotation
settings are NOT available. -->
<SwitchPreference
android:key="toggle_lock_screen_rotation_preference"
android:persistent="false"
android:title="@string/accelerometer_title"
settings:controller="com.android.settings.accessibility.LockScreenRotationPreferenceController"/>
<!-- Auto-rotation preference that will be shown when device state based auto-rotation settings
are available. -->
<Preference
android:key="device_state_auto_rotate_accessibility"
android:persistent="false"
android:title="@string/accelerometer_title"
android:fragment="com.android.settings.display.DeviceStateAutoRotateDetailsFragment"
settings:keywords="@string/keywords_auto_rotate"
settings:controller="com.android.settings.display.DeviceStateAutoRotateOverviewController"/>
</PreferenceScreen>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2022 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/accelerometer_title" >
<!-- Device state based auto-rotation preferences will be added programmatically here. -->
</PreferenceScreen>

View File

@@ -96,12 +96,27 @@
<PreferenceCategory
android:title="@string/category_name_display_controls">
<!--
Standard auto-rotation preference that will be shown when device state based
auto-rotation settings are NOT available.
-->
<SwitchPreference
android:key="auto_rotate"
android:title="@string/accelerometer_title"
settings:keywords="@string/keywords_auto_rotate"
settings:controller="com.android.settings.display.AutoRotatePreferenceController"/>
<!--
Auto-rotation preference that will be shown when device state based auto-rotation
settings are available.
-->
<Preference
android:key="device_state_auto_rotate"
android:title="@string/accelerometer_title"
android:fragment="com.android.settings.display.DeviceStateAutoRotateDetailsFragment"
settings:keywords="@string/keywords_auto_rotate"
settings:controller="com.android.settings.display.DeviceStateAutoRotateOverviewController"/>
<SwitchPreference
android:key="display_white_balance"
android:title="@string/display_white_balance_title"

View File

@@ -25,6 +25,7 @@ import com.android.internal.view.RotationPolicy;
import com.android.internal.view.RotationPolicy.RotationPolicyListener;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.display.DeviceStateAutoRotationHelper;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -59,7 +60,9 @@ public class LockScreenRotationPreferenceController extends TogglePreferenceCont
@Override
public int getAvailabilityStatus() {
return RotationPolicy.isRotationSupported(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
return RotationPolicy.isRotationSupported(mContext)
&& !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabledForA11y(mContext)
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override

View File

@@ -53,6 +53,7 @@ import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -280,6 +281,11 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
return null;
}
/** Returns all controllers of type T. */
protected <T extends AbstractPreferenceController> List<T> useAll(Class<T> clazz) {
return (List<T>) mPreferenceControllers.getOrDefault(clazz, Collections.emptyList());
}
protected void addPreferenceController(AbstractPreferenceController controller) {
if (mPreferenceControllers.get(controller.getClass()) == null) {
mPreferenceControllers.put(controller.getClass(), new ArrayList<>());

View File

@@ -74,6 +74,7 @@ public class AutoRotatePreferenceController extends TogglePreferenceController i
@Override
public int getAvailabilityStatus() {
return RotationPolicy.isRotationLockToggleVisible(mContext)
&& !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2022 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.display;
import android.app.settings.SettingsEnums;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.search.SearchIndexableRaw;
import java.util.List;
/** Fragment that shows all the available device state based auto-rotation preferences. */
@SearchIndexable
public class DeviceStateAutoRotateDetailsFragment extends DashboardFragment {
private static final String TAG = "DeviceStateAutoRotateDetailsFragment";
@Override
public int getMetricsCategory() {
return SettingsEnums.DISPLAY_AUTO_ROTATE_SETTINGS;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.device_state_auto_rotate_settings;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
DeviceStateAutoRotationHelper.initControllers(
getLifecycle(),
useAll(DeviceStateAutoRotateSettingController.class)
);
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return DeviceStateAutoRotationHelper.createPreferenceControllers(context);
}
@Override
protected String getLogTag() {
return TAG;
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.device_state_auto_rotate_settings) {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context,
boolean enabled) {
return DeviceStateAutoRotationHelper.getRawDataToIndex(context, enabled);
}
};
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2022 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.display;
import android.content.Context;
import android.text.TextUtils;
import com.android.settings.core.BasePreferenceController;
/**
* The top-level preference controller for device state based auto-rotation settings.
*
* It doesn't do anything on its own besides showing/hiding. The toggling of the settings will
* always be done in the details screen when device state based auto-rotation is enabled.
*/
public class DeviceStateAutoRotateOverviewController extends BasePreferenceController {
/** Preference key for when it is used in "accessibility_system_controls.xml". */
private static final String ACCESSIBILITY_PREF_KEY = "device_state_auto_rotate_accessibility";
public DeviceStateAutoRotateOverviewController(Context context, String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
return isAvailableInternal() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
private boolean isAvailableInternal() {
return isA11yPage()
? DeviceStateAutoRotationHelper.isDeviceStateRotationEnabledForA11y(mContext)
: DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext);
}
private boolean isA11yPage() {
return TextUtils.equals(getPreferenceKey(), ACCESSIBILITY_PREF_KEY);
}
}

View File

@@ -0,0 +1,141 @@
/*
* Copyright (C) 2022 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.display;
import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
import android.app.settings.SettingsEnums;
import android.content.Context;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import com.android.settingslib.search.SearchIndexableRaw;
import java.util.List;
/** Controller for device state based auto rotation preferences. */
public class DeviceStateAutoRotateSettingController extends TogglePreferenceController implements
LifecycleObserver {
private SwitchPreference mPreference;
private final DeviceStateRotationLockSettingsManager mAutoRotateSettingsManager;
private final int mOrder;
private final DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
mDeviceStateRotationLockSettingsListener = () -> updateState(mPreference);
private final int mDeviceState;
private final String mDeviceStateDescription;
private final MetricsFeatureProvider mMetricsFeatureProvider;
public DeviceStateAutoRotateSettingController(Context context, int deviceState,
String deviceStateDescription, int order) {
super(context, getPreferenceKeyForDeviceState(deviceState));
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mDeviceState = deviceState;
mDeviceStateDescription = deviceStateDescription;
mAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(context);
mOrder = order;
}
void init(Lifecycle lifecycle) {
lifecycle.addObserver(this);
}
@OnLifecycleEvent(ON_START)
void onStart() {
mAutoRotateSettingsManager.registerListener(mDeviceStateRotationLockSettingsListener);
}
@OnLifecycleEvent(ON_STOP)
void onStop() {
mAutoRotateSettingsManager.unregisterListener(mDeviceStateRotationLockSettingsListener);
}
@Override
public void displayPreference(PreferenceScreen screen) {
mPreference = new SwitchPreference(mContext);
mPreference.setTitle(mDeviceStateDescription);
mPreference.setKey(getPreferenceKey());
mPreference.setOrder(mOrder);
screen.addPreference(mPreference);
super.displayPreference(screen);
}
@Override
public int getAvailabilityStatus() {
return DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
public String getPreferenceKey() {
return getPreferenceKeyForDeviceState(mDeviceState);
}
private static String getPreferenceKeyForDeviceState(int deviceState) {
return "auto_rotate_device_state_" + deviceState;
}
@Override
public boolean isChecked() {
return !mAutoRotateSettingsManager.isRotationLocked(mDeviceState);
}
@Override
public boolean setChecked(boolean isChecked) {
boolean isRotationLocked = !isChecked;
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ROTATION_LOCK,
isRotationLocked);
mAutoRotateSettingsManager.updateSetting(mDeviceState, isRotationLocked);
return true;
}
@Override
public void updateRawDataToIndex(List<SearchIndexableRaw> rawData) {
SearchIndexableRaw indexable = new SearchIndexableRaw(mContext);
indexable.key = getPreferenceKey();
indexable.title = mDeviceStateDescription;
// Maybe pass screen title as param?
indexable.screenTitle = mContext.getString(R.string.accelerometer_title);
rawData.add(indexable);
}
@Override
public int getSliceHighlightMenuRes() {
return R.string.menu_key_display;
}
@Override
public boolean isSliceable() {
return true; // Maybe set to false if in accessibility settings screen
}
@Override
public boolean isPublicSlice() {
return true;
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) 2022 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.display;
import android.content.Context;
import android.util.Log;
import androidx.lifecycle.Lifecycle;
import com.android.internal.view.RotationPolicy;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager.SettableDeviceState;
import com.android.settingslib.search.SearchIndexableRaw;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
/**
* Helper class with utility methods related to device state auto-rotation that can be used in
* auto-rotation settings fragments and controllers.
*/
public class DeviceStateAutoRotationHelper {
private static final String TAG = "DeviceStateAutoRotHelpr";
static void initControllers(Lifecycle lifecycle,
List<DeviceStateAutoRotateSettingController> controllers) {
for (DeviceStateAutoRotateSettingController controller : controllers) {
controller.init(lifecycle);
}
}
static ImmutableList<AbstractPreferenceController> createPreferenceControllers(
Context context) {
List<SettableDeviceState> settableDeviceStates = DeviceStateRotationLockSettingsManager
.getInstance(context).getSettableDeviceStates();
int numDeviceStates = settableDeviceStates.size();
if (numDeviceStates == 0) {
return ImmutableList.of();
}
String[] deviceStateSettingDescriptions = context.getResources().getStringArray(
R.array.config_settableAutoRotationDeviceStatesDescriptions);
if (numDeviceStates != deviceStateSettingDescriptions.length) {
Log.wtf(TAG,
"Mismatch between number of device states and device states descriptions.");
return ImmutableList.of();
}
ImmutableList.Builder<AbstractPreferenceController> controllers =
ImmutableList.builderWithExpectedSize(numDeviceStates);
for (int i = 0; i < numDeviceStates; i++) {
SettableDeviceState settableDeviceState = settableDeviceStates.get(i);
if (!settableDeviceState.isSettable()) {
continue;
}
// Preferences with a lower order will be showed first. Here we go below 0 to make sure
// we are shown before statically declared preferences in XML.
int order = -numDeviceStates + i;
controllers.add(new DeviceStateAutoRotateSettingController(
context,
settableDeviceState.getDeviceState(),
deviceStateSettingDescriptions[i],
order
));
}
return controllers.build();
}
static List<SearchIndexableRaw> getRawDataToIndex(
Context context, boolean enabled) {
// Check what the "enabled" param is for
List<AbstractPreferenceController> controllers = createPreferenceControllers(context);
List<SearchIndexableRaw> rawData = new ArrayList<>();
for (AbstractPreferenceController controller : controllers) {
((BasePreferenceController) controller).updateRawDataToIndex(rawData);
}
return rawData;
}
/** Returns whether the device state based auto-rotation settings are enabled. */
public static boolean isDeviceStateRotationEnabled(Context context) {
return RotationPolicy.isRotationLockToggleVisible(context)
&& DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(context);
}
/**
* Returns whether the device state based auto-rotation settings are enabled for the
* accessibility settings page.
*/
public static boolean isDeviceStateRotationEnabledForA11y(Context context) {
return RotationPolicy.isRotationSupported(context)
&& DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(context);
}
}

View File

@@ -47,6 +47,7 @@ import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
/**
* SmartAutoRotateController controls whether auto rotation is enabled
@@ -54,6 +55,8 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class SmartAutoRotateController extends TogglePreferenceController implements
Preference.OnPreferenceChangeListener, LifecycleObserver {
protected Preference mPreference;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private final SensorPrivacyManager mPrivacyManager;
private final PowerManager mPowerManager;
@@ -63,7 +66,9 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
updateState(mPreference);
}
};
protected Preference mPreference;
private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager;
private final DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
mDeviceStateRotationLockSettingsListener = () -> updateState(mPreference);
private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
public SmartAutoRotateController(Context context, String preferenceKey) {
@@ -73,6 +78,8 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
mPrivacyManager
.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> updateState(mPreference));
mPowerManager = context.getSystemService(PowerManager.class);
mDeviceStateAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(
context);
}
public void init(Lifecycle lifecycle) {
@@ -89,6 +96,9 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
}
protected boolean isRotationLocked() {
if (DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)) {
return mDeviceStateAutoRotateSettingsManager.isRotationLockedForAllStates();
}
return RotationPolicy.isRotationLocked(mContext);
}
@@ -127,6 +137,8 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
};
}
RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener);
mDeviceStateAutoRotateSettingsManager.registerListener(
mDeviceStateRotationLockSettingsListener);
}
@OnLifecycleEvent(ON_STOP)
@@ -136,6 +148,8 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
RotationPolicy.unregisterRotationPolicyListener(mContext, mRotationPolicyListener);
mRotationPolicyListener = null;
}
mDeviceStateAutoRotateSettingsManager.unregisterListener(
mDeviceStateRotationLockSettingsListener);
}
@Override

View File

@@ -77,6 +77,7 @@ public class SmartAutoRotatePreferenceController extends TogglePreferenceControl
@Override
public int getAvailabilityStatus() {
return RotationPolicy.isRotationLockToggleVisible(mContext)
&& !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}

View File

@@ -34,10 +34,14 @@ import com.android.settings.SettingsActivity;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.widget.FooterPreference;
import java.util.List;
/**
* Preference fragment used for auto rotation
*/
@@ -60,6 +64,15 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment {
public void onAttach(Context context) {
super.onAttach(context);
use(SmartAutoRotateController.class).init(getLifecycle());
DeviceStateAutoRotationHelper.initControllers(
getLifecycle(),
useAll(DeviceStateAutoRotateSettingController.class)
);
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return DeviceStateAutoRotationHelper.createPreferenceControllers(context);
}
@Override
@@ -79,7 +92,9 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment {
@VisibleForTesting
void createHeader(SettingsActivity activity) {
if (isRotationResolverServiceAvailable(activity)) {
boolean deviceStateRotationEnabled =
DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(activity);
if (isRotationResolverServiceAvailable(activity) && !deviceStateRotationEnabled) {
final SettingsMainSwitchBar switchBar = activity.getSwitchBar();
switchBar.setTitle(
getContext().getString(R.string.auto_rotate_settings_primary_switch_title));
@@ -127,5 +142,12 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment {
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.auto_rotate_settings);
new BaseSearchIndexProvider(R.xml.auto_rotate_settings) {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(
Context context, boolean enabled) {
return DeviceStateAutoRotationHelper.getRawDataToIndex(context, enabled);
}
};
}

View File

@@ -26,6 +26,7 @@ import androidx.preference.SwitchPreference;
import com.android.internal.view.RotationPolicy;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
import org.junit.Before;
@@ -50,7 +51,10 @@ public class LockScreenRotationPreferenceControllerTest {
}
@Test
@Config(shadows = {ShadowRotationPolicy.class})
@Config(shadows = {
ShadowRotationPolicy.class,
ShadowDeviceStateRotationLockSettingsManager.class
})
public void getAvailabilityStatus_supportedRotation_shouldReturnAvailable() {
ShadowRotationPolicy.setRotationSupported(true /* supported */);
@@ -59,8 +63,23 @@ public class LockScreenRotationPreferenceControllerTest {
}
@Test
@Config(shadows = {ShadowRotationPolicy.class})
public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() {
@Config(shadows = {
ShadowRotationPolicy.class,
ShadowDeviceStateRotationLockSettingsManager.class
})
public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() {
ShadowRotationPolicy.setRotationSupported(true /* supported */);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
@Config(shadows = {
ShadowRotationPolicy.class,
ShadowDeviceStateRotationLockSettingsManager.class
}) public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() {
ShadowRotationPolicy.setRotationSupported(false /* supported */);
assertThat(mController.getAvailabilityStatus()).isEqualTo(

View File

@@ -143,6 +143,21 @@ public class DashboardFragmentTest {
assertThat(controller1).isSameInstanceAs(retrievedController);
}
@Test
public void useAll_returnsAllControllersOfType() {
final TestPreferenceController controller1 = new TestPreferenceController(mContext);
final TestPreferenceController controller2 = new TestPreferenceController(mContext);
final SubTestPreferenceController controller3 = new SubTestPreferenceController(mContext);
mTestFragment.addPreferenceController(controller1);
mTestFragment.addPreferenceController(controller2);
mTestFragment.addPreferenceController(controller3);
final List<TestPreferenceController> retrievedControllers = mTestFragment.useAll(
TestPreferenceController.class);
assertThat(retrievedControllers).containsExactly(controller1, controller2);
}
@Test
public void displayTilesAsPreference_shouldAddTilesWithIntent() {
when(mFakeFeatureFactory.dashboardFeatureProvider
@@ -360,6 +375,13 @@ public class DashboardFragmentTest {
}
}
public static class SubTestPreferenceController extends TestPreferenceController {
private SubTestPreferenceController(Context context) {
super(context);
}
}
private static class TestFragment extends DashboardFragment {
private final PreferenceManager mPreferenceManager;

View File

@@ -30,6 +30,7 @@ import android.provider.Settings;
import androidx.preference.SwitchPreference;
import com.android.internal.R;
import com.android.internal.view.RotationPolicy;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -64,6 +65,7 @@ public class AutoRotatePreferenceControllerTest {
mPreference = new SwitchPreference(RuntimeEnvironment.application);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
disableDeviceStateRotation();
mController = new AutoRotatePreferenceController(mContext, "auto_rotate");
}
@@ -111,6 +113,26 @@ public class AutoRotatePreferenceControllerTest {
.UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_deviceRotationDisabled_returnsAvailable() {
enableAutoRotationPreference();
disableDeviceStateRotation();
int availability = mController.getAvailabilityStatus();
assertThat(availability).isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_deviceRotationEnabled_returnsUnsupported() {
enableAutoRotationPreference();
enableDeviceStateRotation();
int availability = mController.getAvailabilityStatus();
assertThat(availability).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
public void testIsCheck() {
assertThat(mController.isChecked()).isFalse();
@@ -180,4 +202,15 @@ public class AutoRotatePreferenceControllerTest {
Settings.System.putIntForUser(mContentResolver,
Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT);
}
private void enableDeviceStateRotation() {
when(mContext.getResources().getStringArray(
R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
new String[]{"0:0", "1:1", "2:2"});
}
private void disableDeviceStateRotation() {
when(mContext.getResources().getStringArray(
R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(new String[]{});
}
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2022 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.display;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.res.Resources;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class DeviceStateAutoRotateDetailsFragmentTest {
private final DeviceStateAutoRotateDetailsFragment mFragment =
spy(new DeviceStateAutoRotateDetailsFragment());
private final Context mContext = spy(RuntimeEnvironment.application);
private final Resources mResources = spy(mContext.getResources());
@Before
public void setUp() throws Exception {
when(mContext.getResources()).thenReturn(mResources);
when(mContext.getApplicationContext()).thenReturn(mContext);
when(mFragment.getContext()).thenReturn(mContext);
when(mFragment.getResources()).thenReturn(mResources);
}
@Test
public void getMetricsCategory_returnsAutoRotateSettings() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.DISPLAY_AUTO_ROTATE_SETTINGS);
}
@Test
public void getPreferenceScreenResId_returnsDeviceStateAutoRotationSettings() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
R.xml.device_state_auto_rotate_settings);
}
@Test
public void createPreferenceControllers_settableDeviceStates_returnsDeviceStateControllers() {
enableDeviceStateSettableRotationStates(new String[]{"0:1", "1:1"},
new String[]{"Folded", "Unfolded"});
List<AbstractPreferenceController> preferenceControllers =
mFragment.createPreferenceControllers(mContext);
assertThat(preferenceControllers).hasSize(2);
assertThat(preferenceControllers.get(0)).isInstanceOf(
DeviceStateAutoRotateSettingController.class);
assertThat(preferenceControllers.get(1)).isInstanceOf(
DeviceStateAutoRotateSettingController.class);
}
@Test
public void createPreferenceControllers_noSettableDeviceStates_returnsEmptyList() {
enableDeviceStateSettableRotationStates(new String[]{}, new String[]{});
List<AbstractPreferenceController> preferenceControllers =
mFragment.createPreferenceControllers(mContext);
assertThat(preferenceControllers).isEmpty();
}
private void enableDeviceStateSettableRotationStates(String[] settableStates,
String[] settableStatesDescriptions) {
when(mResources.getStringArray(
com.android.internal.R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
settableStates);
when(mResources.getStringArray(
R.array.config_settableAutoRotationDeviceStatesDescriptions)).thenReturn(
settableStatesDescriptions);
DeviceStateRotationLockSettingsManager.resetInstance();
DeviceStateRotationLockSettingsManager.getInstance(mContext)
.resetStateForTesting(mResources);
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2022 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.display;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
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)
@Config(shadows = {ShadowRotationPolicy.class, ShadowDeviceStateRotationLockSettingsManager.class})
public class DeviceStateAutoRotateOverviewControllerTest {
private final DeviceStateAutoRotateOverviewController mController =
new DeviceStateAutoRotateOverviewController(
RuntimeEnvironment.application, "device_state_auto_rotate");
@Test
public void getAvailabilityStatus_rotationAndDeviceStateRotationEnabled_returnsAvailable() {
ShadowRotationPolicy.setRotationSupported(true);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
int availability = mController.getAvailabilityStatus();
assertThat(availability).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_rotationNotSupported_returnsUnsupportedOnDevice() {
ShadowRotationPolicy.setRotationSupported(false);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
int availability = mController.getAvailabilityStatus();
assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_deviceStateRotationNotSupported_returnsUnsupportedOnDevice() {
ShadowRotationPolicy.setRotationSupported(true);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
int availability = mController.getAvailabilityStatus();
assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) 2022 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.display;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import com.android.settingslib.search.SearchIndexableRaw;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ShadowRotationPolicy.class,
ShadowDeviceStateRotationLockSettingsManager.class
})
public class DeviceStateAutoRotateSettingControllerTest {
private static final int DEFAULT_DEVICE_STATE = 1;
private static final String DEFAULT_DEVICE_STATE_DESCRIPTION = "Device state description";
private static final int DEFAULT_ORDER = -10;
private final Context mContext = RuntimeEnvironment.application;
private final DeviceStateAutoRotateSettingController mController =
new DeviceStateAutoRotateSettingController(mContext, DEFAULT_DEVICE_STATE,
DEFAULT_DEVICE_STATE_DESCRIPTION, DEFAULT_ORDER);
private final DeviceStateRotationLockSettingsManager mAutoRotateSettingsManager =
DeviceStateRotationLockSettingsManager.getInstance(mContext);
@Test
public void displayPreference_addsPreferenceToPreferenceScreen() {
PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
mController.displayPreference(screen);
assertThat(screen.getPreferenceCount()).isEqualTo(1);
Preference preference = screen.getPreference(0);
assertThat(preference.getTitle().toString()).isEqualTo(DEFAULT_DEVICE_STATE_DESCRIPTION);
assertThat(preference.getOrder()).isEqualTo(DEFAULT_ORDER);
assertThat(preference.getKey()).isEqualTo(mController.getPreferenceKey());
}
@Test
public void getAvailabilityStatus_rotationAndDeviceStateRotationEnabled_returnsAvailable() {
ShadowRotationPolicy.setRotationSupported(true);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
int availability = mController.getAvailabilityStatus();
assertThat(availability).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_deviceStateRotationDisabled_returnsUnsupported() {
ShadowRotationPolicy.setRotationSupported(true);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
int availability = mController.getAvailabilityStatus();
assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_rotationDisabled_returnsUnsupported() {
ShadowRotationPolicy.setRotationSupported(false);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
int availability = mController.getAvailabilityStatus();
assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getPreferenceKey_returnsKeyBasedOnDeviceState() {
String key = mController.getPreferenceKey();
String expectedKey = "auto_rotate_device_state_" + DEFAULT_DEVICE_STATE;
assertThat(key).isEqualTo(expectedKey);
}
@Test
public void isChecked_settingForStateIsUnlocked_returnsTrue() {
mAutoRotateSettingsManager.updateSetting(DEFAULT_DEVICE_STATE, /* rotationLocked= */ false);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_settingForStateIsLocked_returnsFalse() {
mAutoRotateSettingsManager.updateSetting(DEFAULT_DEVICE_STATE, /* rotationLocked= */ true);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void setChecked_true_deviceStateSettingIsUnlocked() {
mController.setChecked(true);
boolean rotationLocked = mAutoRotateSettingsManager.isRotationLocked(DEFAULT_DEVICE_STATE);
assertThat(rotationLocked).isFalse();
}
@Test
public void setChecked_false_deviceStateSettingIsLocked() {
mController.setChecked(false);
boolean rotationLocked = mAutoRotateSettingsManager.isRotationLocked(DEFAULT_DEVICE_STATE);
assertThat(rotationLocked).isTrue();
}
@Test
public void updateRawDataToIndex_addsItemToList() {
List<SearchIndexableRaw> rawData = new ArrayList<>();
mController.updateRawDataToIndex(rawData);
assertThat(rawData).hasSize(1);
SearchIndexableRaw item = rawData.get(0);
assertThat(item.key).isEqualTo(mController.getPreferenceKey());
assertThat(item.title).isEqualTo(DEFAULT_DEVICE_STATE_DESCRIPTION);
assertThat(item.screenTitle).isEqualTo(mContext.getString(R.string.accelerometer_title));
}
@Test
public void getSliceHighlightMenuRes_returnsMenuKeyDisplay() {
int sliceHighlightMenuRes = mController.getSliceHighlightMenuRes();
assertThat(sliceHighlightMenuRes).isEqualTo(R.string.menu_key_display);
}
@Test
public void isSliceable_returnsTrue() {
assertThat(mController.isSliceable()).isTrue();
}
@Test
public void isPublicSlice_returnsTrue() {
assertThat(mController.isPublicSlice()).isTrue();
}
}

View File

@@ -39,7 +39,10 @@ import android.provider.Settings;
import androidx.preference.Preference;
import com.android.settings.testutils.ResolveInfoBuilder;
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import org.junit.Before;
import org.junit.Test;
@@ -63,6 +66,8 @@ public class SmartAutoRotateControllerTest {
@Mock
private Preference mPreference;
private ContentResolver mContentResolver;
private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager =
DeviceStateRotationLockSettingsManager.getInstance(RuntimeEnvironment.application);
@Before
public void setUp() {
@@ -122,6 +127,34 @@ public class SmartAutoRotateControllerTest {
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
}
@Test
@Config(shadows = {
ShadowDeviceStateRotationLockSettingsManager.class,
ShadowRotationPolicy.class
})
public void getAvailabilityStatus_deviceStateRotationLocked_returnDisableDependentSetting() {
enableDeviceStateRotation();
lockDeviceStateRotation();
int availabilityStatus = mController.getAvailabilityStatus();
assertThat(availabilityStatus).isEqualTo(DISABLED_DEPENDENT_SETTING);
}
@Test
@Config(shadows = {
ShadowDeviceStateRotationLockSettingsManager.class,
ShadowRotationPolicy.class
})
public void getAvailabilityStatus_deviceStateRotationUnlocked_returnAvailable() {
enableDeviceStateRotation();
unlockDeviceStateRotation();
int availabilityStatus = mController.getAvailabilityStatus();
assertThat(availabilityStatus).isEqualTo(AVAILABLE);
}
private void enableAutoRotation() {
Settings.System.putIntForUser(mContentResolver,
Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT);
@@ -131,4 +164,23 @@ public class SmartAutoRotateControllerTest {
Settings.System.putIntForUser(mContentResolver,
Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT);
}
private void enableDeviceStateRotation() {
ShadowRotationPolicy.setRotationSupported(true);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
}
private void lockDeviceStateRotation() {
mDeviceStateAutoRotateSettingsManager.updateSetting(
/* deviceState= */0, /* rotationLocked= */ true);
mDeviceStateAutoRotateSettingsManager.updateSetting(
/* deviceState= */1, /* rotationLocked= */ true);
}
private void unlockDeviceStateRotation() {
mDeviceStateAutoRotateSettingsManager.updateSetting(
/* deviceState= */0, /* rotationLocked= */ false);
mDeviceStateAutoRotateSettingsManager.updateSetting(
/* deviceState= */1, /* rotationLocked= */ true);
}
}

View File

@@ -40,6 +40,7 @@ import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.ResolveInfoBuilder;
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
import org.junit.Before;
@@ -53,7 +54,10 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowSensorPrivacyManager.class)
@Config(shadows = {
ShadowSensorPrivacyManager.class,
ShadowDeviceStateRotationLockSettingsManager.class
})
public class SmartAutoRotatePreferenceControllerTest {
private static final String PACKAGE_NAME = "package_name";
@@ -95,6 +99,7 @@ public class SmartAutoRotatePreferenceControllerTest {
new SmartAutoRotatePreferenceController(mContext, "smart_auto_rotate"));
when(mController.isCameraLocked()).thenReturn(false);
when(mController.isPowerSaveMode()).thenReturn(false);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
}
@Test
@@ -199,6 +204,16 @@ public class SmartAutoRotatePreferenceControllerTest {
.UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() {
enableAutoRotationPreference();
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
public void isSliceableCorrectKey_returnsTrue() {
final AutoRotatePreferenceController controller =

View File

@@ -18,6 +18,8 @@ package com.android.settings.display;
import static com.android.settings.display.SmartAutoRotatePreferenceFragment.AUTO_ROTATE_SWITCH_PREFERENCE_ID;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -33,6 +35,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.view.View;
import androidx.preference.Preference;
@@ -40,7 +43,11 @@ import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.testutils.ResolveInfoBuilder;
import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import org.junit.Before;
import org.junit.Test;
@@ -49,8 +56,15 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ShadowDeviceStateRotationLockSettingsManager.class,
ShadowRotationPolicy.class
})
public class SmartAutoRotatePreferenceFragmentTest {
private static final String PACKAGE_NAME = "package_name";
@@ -70,19 +84,24 @@ public class SmartAutoRotatePreferenceFragmentTest {
@Mock
private Preference mRotateSwitchPreference;
private Resources mResources;
private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
final Context context = spy(RuntimeEnvironment.application);
mContext = spy(RuntimeEnvironment.application);
ContentResolver mContentResolver = RuntimeEnvironment.application.getContentResolver();
when(context.getPackageManager()).thenReturn(mPackageManager);
when(context.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName();
doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
Manifest.permission.CAMERA, PACKAGE_NAME);
mResources = spy(mContext.getResources());
when(mContext.getResources()).thenReturn(mResources);
final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
resolveInfo.serviceInfo = new ServiceInfo();
when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo);
@@ -90,15 +109,16 @@ public class SmartAutoRotatePreferenceFragmentTest {
mFragment = spy(new SmartAutoRotatePreferenceFragment());
when(mActivity.getPackageManager()).thenReturn(mPackageManager);
when(mFragment.getActivity()).thenReturn(mActivity);
when(mFragment.getContext()).thenReturn(context);
when(mFragment.getContext()).thenReturn(mContext);
doReturn(mView).when(mFragment).getView();
when(mFragment.findPreference(AUTO_ROTATE_SWITCH_PREFERENCE_ID)).thenReturn(
mRotateSwitchPreference);
mSwitchBar = spy(new SettingsMainSwitchBar(context));
mSwitchBar = spy(new SettingsMainSwitchBar(mContext));
when(mActivity.getSwitchBar()).thenReturn(mSwitchBar);
doReturn(mSwitchBar).when(mView).findViewById(R.id.switch_bar);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
}
@@ -110,6 +130,17 @@ public class SmartAutoRotatePreferenceFragmentTest {
verify(mRotateSwitchPreference, times(1)).setVisible(false);
}
@Test
public void createHeader_deviceStateRotationSupported_switchBarIsDisabled() {
ShadowRotationPolicy.setRotationSupported(true);
ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
mFragment.createHeader(mActivity);
verify(mSwitchBar, never()).show();
verify(mRotateSwitchPreference, never()).setVisible(false);
}
@Test
public void createHeader_faceDetectionUnSupported_switchBarIsDisabled() {
doReturn(null).when(mPackageManager).getRotationResolverPackageName();
@@ -120,4 +151,41 @@ public class SmartAutoRotatePreferenceFragmentTest {
verify(mRotateSwitchPreference, never()).setVisible(false);
}
@Test
public void createPreferenceControllers_noSettableDeviceStates_returnsEmptyList() {
enableDeviceStateSettableRotationStates(new String[]{}, new String[]{});
List<AbstractPreferenceController> preferenceControllers =
mFragment.createPreferenceControllers(mContext);
assertThat(preferenceControllers).isEmpty();
}
@Test
public void createPreferenceControllers_settableDeviceStates_returnsDeviceStateControllers() {
enableDeviceStateSettableRotationStates(new String[]{"0:1", "1:1"},
new String[]{"Folded", "Unfolded"});
List<AbstractPreferenceController> preferenceControllers =
mFragment.createPreferenceControllers(mContext);
assertThat(preferenceControllers).hasSize(2);
assertThat(preferenceControllers.get(0)).isInstanceOf(
DeviceStateAutoRotateSettingController.class);
assertThat(preferenceControllers.get(1)).isInstanceOf(
DeviceStateAutoRotateSettingController.class);
}
private void enableDeviceStateSettableRotationStates(String[] settableStates,
String[] settableStatesDescriptions) {
when(mResources.getStringArray(
com.android.internal.R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
settableStates);
when(mResources.getStringArray(
R.array.config_settableAutoRotationDeviceStatesDescriptions)).thenReturn(
settableStatesDescriptions);
DeviceStateRotationLockSettingsManager.resetInstance();
DeviceStateRotationLockSettingsManager.getInstance(mContext)
.resetStateForTesting(mResources);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2022 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.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@Implements(DeviceStateRotationLockSettingsManager.class)
public class ShadowDeviceStateRotationLockSettingsManager {
private static boolean sDeviceStateRotationLockEnabled;
@Implementation
public static boolean isDeviceStateRotationLockEnabled(Context context) {
return sDeviceStateRotationLockEnabled;
}
public static void setDeviceStateRotationLockEnabled(boolean enabled) {
sDeviceStateRotationLockEnabled = enabled;
}
}