diff --git a/color-check-baseline.xml b/color-check-baseline.xml index 16658f8b3dc..ba4d2f69b1d 100644 --- a/color-check-baseline.xml +++ b/color-check-baseline.xml @@ -3736,7 +3736,7 @@ errorLine1=" android:color="@color/accessibility_feature_background"/>" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> diff --git a/res/drawable/ic_text_and_display.xml b/res/drawable/ic_color_and_motion.xml similarity index 100% rename from res/drawable/ic_text_and_display.xml rename to res/drawable/ic_color_and_motion.xml diff --git a/res/layout/lockscreen_remote_input.xml b/res/layout/lockscreen_remote_input.xml deleted file mode 100644 index 4fa44ce1b2e..00000000000 --- a/res/layout/lockscreen_remote_input.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - diff --git a/res/layout/restricted_dialog_singlechoice.xml b/res/layout/restricted_dialog_singlechoice.xml index a9984a84fc3..9b19884aa9f 100644 --- a/res/layout/restricted_dialog_singlechoice.xml +++ b/res/layout/restricted_dialog_singlechoice.xml @@ -35,14 +35,4 @@ android:drawableStart="?android:attr/listChoiceIndicatorSingle" android:drawablePadding="20dp" android:ellipsize="marquee" /> - diff --git a/res/layout/restricted_preference_dropdown.xml b/res/layout/restricted_preference_dropdown.xml deleted file mode 100644 index 8930e24bb28..00000000000 --- a/res/layout/restricted_preference_dropdown.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/res/layout/restricted_radio_with_summary.xml b/res/layout/restricted_radio_with_summary.xml deleted file mode 100644 index 5e7fcd82fe6..00000000000 --- a/res/layout/restricted_radio_with_summary.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - diff --git a/res/layout/spinner_dropdown_restricted_item.xml b/res/layout/spinner_dropdown_restricted_item.xml deleted file mode 100644 index d95e4be3894..00000000000 --- a/res/layout/spinner_dropdown_restricted_item.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - diff --git a/res/values/config.xml b/res/values/config.xml index 6a7c15b0d01..88e7c7e5ea1 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -567,7 +567,19 @@ 2 3 - + + + + + + false @@ -593,4 +605,5 @@ false + diff --git a/res/values/strings.xml b/res/values/strings.xml index 5472a9d7b45..363c4e9b0f9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5156,8 +5156,8 @@ General Display - - Text and display + + Color and motion Turn screen darker diff --git a/res/xml/accessibility_text_and_display.xml b/res/xml/accessibility_color_and_motion.xml similarity index 62% rename from res/xml/accessibility_text_and_display.xml rename to res/xml/accessibility_color_and_motion.xml index 659acab5846..f251d1e8763 100644 --- a/res/xml/accessibility_text_and_display.xml +++ b/res/xml/accessibility_color_and_motion.xml @@ -17,34 +17,9 @@ - - - - - - + android:title="@string/accessibility_color_and_motion_title"> - - - + android:title="@string/accessibility_text_reading_options_title" /> - - - - + + + + + diff --git a/res/xml/device_state_auto_rotate_settings.xml b/res/xml/device_state_auto_rotate_settings.xml new file mode 100644 index 00000000000..2ddb4c7d9d5 --- /dev/null +++ b/res/xml/device_state_auto_rotate_settings.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml index 328e15cefa5..88f8bf138e7 100644 --- a/res/xml/display_settings.xml +++ b/res/xml/display_settings.xml @@ -103,12 +103,27 @@ + + + + List useAll(Class clazz) { + return (List) mPreferenceControllers.getOrDefault(clazz, Collections.emptyList()); + } + protected void addPreferenceController(AbstractPreferenceController controller) { if (mPreferenceControllers.get(controller.getClass()) == null) { mPreferenceControllers.put(controller.getClass(), new ArrayList<>()); diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java index ceba8beb92b..08e523c8333 100644 --- a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java +++ b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java @@ -48,7 +48,6 @@ public class UnrestrictedDataAccessPreference extends AppSwitchPreference implem ApplicationsState applicationsState, DataSaverBackend dataSaverBackend, DashboardFragment parentFragment) { super(context); - setWidgetLayoutResource(R.layout.restricted_switch_widget); mHelper = new RestrictedPreferenceHelper(context, this, null); mEntry = entry; mDataUsageState = (AppStateDataUsageBridge.DataUsageState) mEntry.extraInfo; @@ -131,10 +130,6 @@ public class UnrestrictedDataAccessPreference extends AppSwitchPreference implem super.onBindViewHolder(holder); mHelper.onBindViewHolder(holder); - holder.findViewById(R.id.restricted_icon).setVisibility( - disabledByAdmin ? View.VISIBLE : View.GONE); - holder.findViewById(android.R.id.switch_widget).setVisibility( - disabledByAdmin ? View.GONE : View.VISIBLE); } @Override diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java index 5dc228644a9..90423fbea7c 100644 --- a/src/com/android/settings/display/AutoRotatePreferenceController.java +++ b/src/com/android/settings/display/AutoRotatePreferenceController.java @@ -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; } diff --git a/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java b/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java new file mode 100644 index 00000000000..fb6d9f4cab0 --- /dev/null +++ b/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java @@ -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 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 getRawDataToIndex(Context context, + boolean enabled) { + return DeviceStateAutoRotationHelper.getRawDataToIndex(context, enabled); + } + }; +} diff --git a/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java b/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java new file mode 100644 index 00000000000..5e49bf3e149 --- /dev/null +++ b/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java @@ -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); + } +} diff --git a/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java b/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java new file mode 100644 index 00000000000..c8f6280fe3b --- /dev/null +++ b/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java @@ -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 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; + } +} diff --git a/src/com/android/settings/display/DeviceStateAutoRotationHelper.java b/src/com/android/settings/display/DeviceStateAutoRotationHelper.java new file mode 100644 index 00000000000..223ef1aa4fa --- /dev/null +++ b/src/com/android/settings/display/DeviceStateAutoRotationHelper.java @@ -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 controllers) { + for (DeviceStateAutoRotateSettingController controller : controllers) { + controller.init(lifecycle); + } + } + + static ImmutableList createPreferenceControllers( + Context context) { + List 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 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 getRawDataToIndex( + Context context, boolean enabled) { + // Check what the "enabled" param is for + List controllers = createPreferenceControllers(context); + List 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); + } +} diff --git a/src/com/android/settings/display/SmartAutoRotateController.java b/src/com/android/settings/display/SmartAutoRotateController.java index 76a222aac75..d29a64e7d88 100644 --- a/src/com/android/settings/display/SmartAutoRotateController.java +++ b/src/com/android/settings/display/SmartAutoRotateController.java @@ -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 diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java index bd8ee84a2d3..d02e3367692 100644 --- a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java +++ b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java @@ -77,6 +77,7 @@ public class SmartAutoRotatePreferenceController extends TogglePreferenceControl @Override public int getAvailabilityStatus() { return RotationPolicy.isRotationLockToggleVisible(mContext) + && !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java index 47373366ebe..9fda03c4d5f 100644 --- a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java +++ b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java @@ -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 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 getRawDataToIndex( + Context context, boolean enabled) { + return DeviceStateAutoRotationHelper.getRawDataToIndex(context, enabled); + } + }; } diff --git a/packages/apps/Settings/src/com/android/settings/dream/OWNERS b/src/com/android/settings/dream/OWNERS similarity index 100% rename from packages/apps/Settings/src/com/android/settings/dream/OWNERS rename to src/com/android/settings/dream/OWNERS diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java index 442af3803c5..5c7c54eda37 100644 --- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java +++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java @@ -97,23 +97,19 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat public PrivateDnsModeDialogPreference(Context context) { super(context); - initialize(); } public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs) { super(context, attrs); - initialize(); } public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - initialize(); } public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - initialize(); } private final AnnotationSpan.LinkInfo mUrlLinkInfo = new AnnotationSpan.LinkInfo( @@ -131,12 +127,6 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat } }); - private void initialize() { - // Add the "Restricted" icon resource so that if the preference is disabled by the - // admin, an information button will be shown. - setWidgetLayoutResource(R.layout.restricted_icon); - } - @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); @@ -146,13 +136,6 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat // by the controller. holder.itemView.setEnabled(true); } - - final View restrictedIcon = holder.findViewById(R.id.restricted_icon); - if (restrictedIcon != null) { - // Show the "Restricted" icon if, and only if, the preference was disabled by - // the admin. - restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE); - } } @Override diff --git a/src/com/android/settings/notification/NotificationLockscreenPreference.java b/src/com/android/settings/notification/NotificationLockscreenPreference.java deleted file mode 100644 index b2360148022..00000000000 --- a/src/com/android/settings/notification/NotificationLockscreenPreference.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2016 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.notification; - -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.Settings; -import android.util.AttributeSet; -import android.view.View; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.ListView; - -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AlertDialog.Builder; - -import com.android.settings.R; -import com.android.settings.RestrictedListPreference; -import com.android.settings.Utils; -import com.android.settingslib.RestrictedLockUtils; - -public class NotificationLockscreenPreference extends RestrictedListPreference { - - private boolean mAllowRemoteInput; - private Listener mListener; - private boolean mShowRemoteInput; - private boolean mRemoteInputCheckBoxEnabled = true; - private int mUserId = UserHandle.myUserId(); - private RestrictedLockUtils.EnforcedAdmin mAdminRestrictingRemoteInput; - - public NotificationLockscreenPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public void setRemoteInputCheckBoxEnabled(boolean enabled) { - mRemoteInputCheckBoxEnabled = enabled; - } - - public void setRemoteInputRestricted(RestrictedLockUtils.EnforcedAdmin admin) { - mAdminRestrictingRemoteInput = admin; - } - - @Override - protected void onClick() { - final Context context = getContext(); - if (!Utils.startQuietModeDialogIfNecessary(context, UserManager.get(context), mUserId)) { - // Call super to create preference dialog only when work mode is on - // startQuietModeDialogIfNecessary will return false if mUserId is not a managed user - super.onClick(); - } - } - - public void setUserId(int userId) { - mUserId = userId; - } - - @Override - protected void onPrepareDialogBuilder(Builder builder, - DialogInterface.OnClickListener innerListener) { - - mListener = new Listener(innerListener); - builder.setSingleChoiceItems(createListAdapter(builder.getContext()), getSelectedValuePos(), - mListener); - mShowRemoteInput = getEntryValues().length == 3; - mAllowRemoteInput = Settings.Secure.getInt(getContext().getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, 0) != 0; - builder.setView(R.layout.lockscreen_remote_input); - } - - @Override - protected void onDialogCreated(Dialog dialog) { - super.onDialogCreated(dialog); - dialog.create(); - CheckBox checkbox = (CheckBox) dialog.findViewById(R.id.lockscreen_remote_input); - checkbox.setChecked(!mAllowRemoteInput); - checkbox.setOnCheckedChangeListener(mListener); - checkbox.setEnabled(mAdminRestrictingRemoteInput == null); - - View restricted = dialog.findViewById(R.id.restricted_lock_icon_remote_input); - restricted.setVisibility(mAdminRestrictingRemoteInput == null ? View.GONE : View.VISIBLE); - - if (mAdminRestrictingRemoteInput != null) { - checkbox.setClickable(false); - dialog.findViewById(com.android.internal.R.id.customPanel) - .setOnClickListener(mListener); - } - } - - @Override - protected void onDialogStateRestored(Dialog dialog, Bundle savedInstanceState) { - super.onDialogStateRestored(dialog, savedInstanceState); - ListView listView = ((AlertDialog) dialog).getListView(); - int selectedPosition = listView.getCheckedItemPosition(); - - View panel = dialog.findViewById(com.android.internal.R.id.customPanel); - panel.setVisibility(checkboxVisibilityForSelectedIndex(selectedPosition, - mShowRemoteInput)); - mListener.setView(panel); - } - - @Override - protected void onDialogClosed(boolean positiveResult) { - super.onDialogClosed(positiveResult); - Settings.Secure.putInt(getContext().getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, mAllowRemoteInput ? 1 : 0); - } - - @Override - protected boolean isAutoClosePreference() { - return false; - } - - private int checkboxVisibilityForSelectedIndex(int selected, - boolean showRemoteAtAll) { - return selected == 1 && showRemoteAtAll && mRemoteInputCheckBoxEnabled ? View.VISIBLE - : View.GONE; - } - - private class Listener implements DialogInterface.OnClickListener, - CompoundButton.OnCheckedChangeListener, View.OnClickListener { - - private final DialogInterface.OnClickListener mInner; - private View mView; - - public Listener(DialogInterface.OnClickListener inner) { - mInner = inner; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - mInner.onClick(dialog, which); - ListView listView = ((AlertDialog) dialog).getListView(); - int selectedPosition = listView.getCheckedItemPosition(); - if (mView != null) { - mView.setVisibility( - checkboxVisibilityForSelectedIndex(selectedPosition, mShowRemoteInput)); - } - } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mAllowRemoteInput = !isChecked; - } - - public void setView(View view) { - mView = view; - } - - @Override - public void onClick(View v) { - if (v.getId() == com.android.internal.R.id.customPanel) { - RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(), - mAdminRestrictingRemoteInput); - } - } - } -} diff --git a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java index 55e8bba0b29..0fd0c0dee22 100644 --- a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java +++ b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java @@ -33,15 +33,17 @@ public class SafetySourceBroadcastReceiver extends BroadcastReceiver { return; } - ImmutableList sourceIds = - ImmutableList.copyOf(intent.getStringArrayExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS)); + String[] sourceIdsExtra = intent.getStringArrayExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS); + if (sourceIdsExtra != null && sourceIdsExtra.length > 0) { + ImmutableList sourceIds = ImmutableList.copyOf(sourceIdsExtra); - if (sourceIds.contains(LockScreenSafetySource.SAFETY_SOURCE_ID)) { - LockScreenSafetySource.sendSafetyData(context); - } + if (sourceIds.contains(LockScreenSafetySource.SAFETY_SOURCE_ID)) { + LockScreenSafetySource.sendSafetyData(context); + } - if (sourceIds.contains(BiometricsSafetySource.SAFETY_SOURCE_ID)) { - BiometricsSafetySource.sendSafetyData(context); + if (sourceIds.contains(BiometricsSafetySource.SAFETY_SOURCE_ID)) { + BiometricsSafetySource.sendSafetyData(context); + } } } } diff --git a/src/com/android/settings/widget/RestrictedAppPreference.java b/src/com/android/settings/widget/RestrictedAppPreference.java index cd953571ab6..f93b935d5b0 100644 --- a/src/com/android/settings/widget/RestrictedAppPreference.java +++ b/src/com/android/settings/widget/RestrictedAppPreference.java @@ -20,12 +20,10 @@ import android.content.Context; import android.os.UserHandle; import android.text.TextUtils; import android.util.AttributeSet; -import android.view.View; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceViewHolder; -import com.android.settings.R; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedPreferenceHelper; import com.android.settingslib.widget.AppPreference; @@ -55,7 +53,6 @@ public class RestrictedAppPreference extends AppPreference { } private void initialize(AttributeSet attrs, String userRestriction) { - setWidgetLayoutResource(R.layout.restricted_icon); mHelper = new RestrictedPreferenceHelper(getContext(), this, attrs); this.userRestriction = userRestriction; } @@ -64,10 +61,6 @@ public class RestrictedAppPreference extends AppPreference { public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); mHelper.onBindViewHolder(holder); - final View restrictedIcon = holder.findViewById(R.id.restricted_icon); - if (restrictedIcon != null) { - restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE); - } } @Override diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java index dd0c20a4765..6f26826d08a 100644 --- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java @@ -100,7 +100,6 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - setIfOnlyAvailableForAdmins(true); mIsUiRestricted = isUiRestricted(); } diff --git a/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java similarity index 89% rename from tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java rename to tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java index 96756ecdd07..0bb227ee9bc 100644 --- a/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java @@ -32,17 +32,17 @@ import org.robolectric.RobolectricTestRunner; import java.util.List; @RunWith(RobolectricTestRunner.class) -public class TextAndDisplayFragmentTest { +public class ColorAndMotionFragmentTest { private Context mContext = ApplicationProvider.getApplicationContext(); @Test public void getNonIndexableKeys_existInXmlLayout() { - final List niks = TextAndDisplayFragment.SEARCH_INDEX_DATA_PROVIDER + final List niks = ColorAndMotionFragment.SEARCH_INDEX_DATA_PROVIDER .getNonIndexableKeys(mContext); final List keys = XmlTestUtils.getKeysFromPreferenceXml(mContext, - R.xml.accessibility_text_and_display); + R.xml.accessibility_color_and_motion); assertThat(keys).containsAtLeastElementsIn(niks); } diff --git a/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java index ef8f569e4fd..f908b8aee61 100644 --- a/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java @@ -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( diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java index 31687c6acfb..6087ef2c2ac 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java @@ -99,6 +99,7 @@ public class AdvancedBluetoothDetailsHeaderControllerTest { mController.mBluetoothAdapter = mBluetoothAdapter; when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice); when(mCachedDevice.getAddress()).thenReturn(MAC_ADDRESS); + when(mCachedDevice.getIdentityAddress()).thenReturn(MAC_ADDRESS); } @Test diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java index 640138816e2..6ecbf2edc9f 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java @@ -155,6 +155,7 @@ public abstract class BluetoothDetailsControllerTestBase { mDevice = mBluetoothAdapter.getRemoteDevice(config.getAddress()); when(mCachedDevice.getDevice()).thenReturn(mDevice); when(mCachedDevice.getAddress()).thenReturn(config.getAddress()); + when(mCachedDevice.getIdentityAddress()).thenReturn(config.getAddress()); } /** diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java index ce41a8d7ca8..fac8b584f0a 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java @@ -89,6 +89,7 @@ public class BluetoothDeviceDetailsFragmentTest { when(fragmentManager.beginTransaction()).thenReturn(mFragmentTransaction); when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS); + when(mCachedDevice.getIdentityAddress()).thenReturn(TEST_ADDRESS); Bundle args = new Bundle(); args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS); mFragment.setArguments(args); diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java index ea841fa35d3..bac868f4585 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java @@ -305,6 +305,7 @@ public class BluetoothPairingDetailTest { when(cachedDevice.isConnected()).thenReturn(true); when(cachedDevice.getDevice()).thenReturn(device2); when(cachedDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS_B); + when(cachedDevice.getIdentityAddress()).thenReturn(TEST_DEVICE_ADDRESS_B); mFragment.onProfileConnectionStateChanged(cachedDevice, BluetoothProfile.A2DP, BluetoothAdapter.STATE_CONNECTED); diff --git a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java index 5c232386121..9c266c1946c 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java @@ -73,6 +73,7 @@ public class ForgetDeviceDialogFragmentTest { FakeFeatureFactory.setupForTest(); String deviceAddress = "55:66:77:88:99:AA"; when(mCachedDevice.getAddress()).thenReturn(deviceAddress); + when(mCachedDevice.getIdentityAddress()).thenReturn(deviceAddress); when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice); when(mCachedDevice.getName()).thenReturn(DEVICE_NAME); mFragment = spy(ForgetDeviceDialogFragment.newInstance(deviceAddress)); diff --git a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java index c8467b2a57e..ad5b70c70ec 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java @@ -62,6 +62,7 @@ public class RemoteDeviceNameDialogFragmentTest { String deviceAddress = "55:66:77:88:99:AA"; when(mCachedDevice.getAddress()).thenReturn(deviceAddress); + when(mCachedDevice.getIdentityAddress()).thenReturn(deviceAddress); mFragment = spy(RemoteDeviceNameDialogFragment.newInstance(mCachedDevice)); doReturn(mCachedDevice).when(mFragment).getDevice(any()); } diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java index fd1c8ff528b..aa5f980f8d0 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java @@ -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 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; diff --git a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java index 1d175def202..54e6b991108 100644 --- a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java @@ -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[]{}); + } } diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java new file mode 100644 index 00000000000..b773657e686 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java @@ -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 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 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); + } +} diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java new file mode 100644 index 00000000000..a5416e70413 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java @@ -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); + } +} diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java new file mode 100644 index 00000000000..28a071aca02 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java @@ -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 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(); + } +} diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java index 778721a163c..4fec38b762d 100644 --- a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java @@ -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); + } } diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java index 068de3472b5..39fdb049228 100644 --- a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java @@ -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 = diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java index 877d2c11e77..942fed6f619 100644 --- a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java @@ -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 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 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); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java new file mode 100644 index 00000000000..72df3cc94b3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java @@ -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; + } +} diff --git a/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java b/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java index 581286bad02..8806e509a94 100644 --- a/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java +++ b/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java @@ -79,6 +79,16 @@ public class SafetySourceBroadcastReceiverTest { verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any()); } + @Test + public void sendSafetyData_whenSafetyCenterIsEnabled_withNullSourceIds_sendsNoData() { + when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true); + Intent intent = new Intent(); + + new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); + + verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any()); + } + @Test public void sendSafetyData_whenSafetyCenterIsEnabled_withNoSourceIds_sendsNoData() { when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);