From b1a48df4f71a2445cf3511b63a722c84befaee66 Mon Sep 17 00:00:00 2001 From: Edgar Wang Date: Fri, 7 Jan 2022 21:34:25 +0800 Subject: [PATCH 01/10] Remove restricted icon Bug: 195401182 Test: robotest Change-Id: I6b22b3b9b62812eb08f10492bd2d7908cce89d39 --- res/layout/lockscreen_remote_input.xml | 46 ----- res/layout/restricted_dialog_singlechoice.xml | 10 - res/layout/restricted_preference_dropdown.xml | 31 ---- res/layout/restricted_radio_with_summary.xml | 63 ------- .../spinner_dropdown_restricted_item.xml | 37 ---- .../settings/RestrictedListPreference.java | 9 - .../UnrestrictedDataAccessPreference.java | 5 - .../PrivateDnsModeDialogPreference.java | 17 -- .../NotificationLockscreenPreference.java | 175 ------------------ .../widget/RestrictedAppPreference.java | 7 - 10 files changed, 400 deletions(-) delete mode 100644 res/layout/lockscreen_remote_input.xml delete mode 100644 res/layout/restricted_preference_dropdown.xml delete mode 100644 res/layout/restricted_radio_with_summary.xml delete mode 100644 res/layout/spinner_dropdown_restricted_item.xml delete mode 100644 src/com/android/settings/notification/NotificationLockscreenPreference.java 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/src/com/android/settings/RestrictedListPreference.java b/src/com/android/settings/RestrictedListPreference.java index bd3cd17432f..d75f1b8fae9 100644 --- a/src/com/android/settings/RestrictedListPreference.java +++ b/src/com/android/settings/RestrictedListPreference.java @@ -30,7 +30,6 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; -import android.widget.ImageView; import android.widget.ListAdapter; import android.widget.ListView; @@ -53,7 +52,6 @@ public class RestrictedListPreference extends CustomListPreference { public RestrictedListPreference(Context context, AttributeSet attrs) { super(context, attrs); - setWidgetLayoutResource(R.layout.restricted_icon); mHelper = new RestrictedPreferenceHelper(context, this, attrs); } @@ -67,10 +65,6 @@ public class RestrictedListPreference extends CustomListPreference { 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 @@ -187,11 +181,9 @@ public class RestrictedListPreference extends CustomListPreference { View root = super.getView(position, convertView, parent); CharSequence entry = getItem(position); CheckedTextView text = (CheckedTextView) root.findViewById(R.id.text1); - ImageView padlock = (ImageView) root.findViewById(R.id.restricted_lock_icon); if (isRestrictedForEntry(entry)) { text.setEnabled(false); text.setChecked(false); - padlock.setVisibility(View.VISIBLE); } else { if (mSelectedIndex != -1) { text.setChecked(position == mSelectedIndex); @@ -199,7 +191,6 @@ public class RestrictedListPreference extends CustomListPreference { if (!text.isEnabled()) { text.setEnabled(true); } - padlock.setVisibility(View.GONE); } return root; } diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java index cd26ed16e8f..244ffc69e74 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/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/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 From 84a9b23ba8207d809668fcffd3f6aa6a26509957 Mon Sep 17 00:00:00 2001 From: Chienyuan Date: Tue, 18 Jan 2022 16:46:46 +0800 Subject: [PATCH 02/10] Show identity address in the bluetooth details page Bug: 197044261 Test: build pass Change-Id: Ic1ef1d575f35c4b37d6f9195ec10dd31ed5bdd5b --- .../bluetooth/BluetoothDetailsMacAddressController.java | 9 +++++---- .../AdvancedBluetoothDetailsHeaderControllerTest.java | 1 + .../bluetooth/BluetoothDetailsControllerTestBase.java | 1 + .../bluetooth/BluetoothDeviceDetailsFragmentTest.java | 1 + .../settings/bluetooth/BluetoothPairingDetailTest.java | 1 + .../bluetooth/ForgetDeviceDialogFragmentTest.java | 1 + .../bluetooth/RemoteDeviceNameDialogFragmentTest.java | 1 + 7 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java b/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java index ec3e11fdaa2..d80512ed301 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java @@ -46,21 +46,22 @@ public class BluetoothDetailsMacAddressController extends BluetoothDetailsContro protected void init(PreferenceScreen screen) { mFooterPreference = screen.findPreference(KEY_DEVICE_DETAILS_FOOTER); mFooterPreference.setTitle(mContext.getString( - R.string.bluetooth_device_mac_address, mCachedDevice.getAddress())); + R.string.bluetooth_device_mac_address, mCachedDevice.getIdentityAddress())); } @Override protected void refresh() { if (mCachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { StringBuilder title = new StringBuilder(mContext.getString( - R.string.bluetooth_multuple_devices_mac_address, mCachedDevice.getAddress())); + R.string.bluetooth_multuple_devices_mac_address, + mCachedDevice.getIdentityAddress())); for (CachedBluetoothDevice member: mCachedDevice.getMemberDevice()) { - title.append("\n").append(member.getAddress()); + title.append("\n").append(member.getIdentityAddress()); } mFooterPreference.setTitle(title); } else { mFooterPreference.setTitle(mContext.getString( - R.string.bluetooth_device_mac_address, mCachedDevice.getAddress())); + R.string.bluetooth_device_mac_address, mCachedDevice.getIdentityAddress())); } } 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 b4f4f97f228..245a297b555 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()); } From 8e231a2ce37278f350829647f3dad3b51cd4da61 Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Mon, 14 Feb 2022 09:21:07 +0800 Subject: [PATCH 03/10] =?UTF-8?q?New=20feature=20=E2=80=9CText=20and=20rea?= =?UTF-8?q?ding=20options=E2=80=9D=20for=20SetupWizard,=20Wallpaper,=20and?= =?UTF-8?q?=20Settings=20(17/n).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update the visibility of entries in the Vision Settings 1) Change the visibility Text and Reading Options preference as visible 2) Remove Font and Display size preferences Bug: 211503117 Test: manual test Change-Id: I9c12eaf4d35f98763c165e1d8ad232b378e044e7 --- .../accessibility_settings_for_setup_wizard.xml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/res/xml/accessibility_settings_for_setup_wizard.xml b/res/xml/accessibility_settings_for_setup_wizard.xml index 3272ae54b77..78d8f721f31 100644 --- a/res/xml/accessibility_settings_for_setup_wizard.xml +++ b/res/xml/accessibility_settings_for_setup_wizard.xml @@ -26,23 +26,8 @@ android:key="text_reading_options" android:persistent="false" android:title="@string/accessibility_text_reading_options_title" - settings:isPreferenceVisible="false" settings:keywords="text_reading_options" /> - - - - Date: Mon, 14 Feb 2022 09:36:27 +0800 Subject: [PATCH 04/10] =?UTF-8?q?New=20feature=20=E2=80=9CText=20and=20rea?= =?UTF-8?q?ding=20options=E2=80=9D=20for=20SetupWizard,=20Wallpaper,=20and?= =?UTF-8?q?=20Settings=20(18/n).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update the visibility of Text and Reading Options in the Accessibility Settings Bug: 211503117 Test: manual test Change-Id: Icacdc64bc41a47653a1cc13333ea17a9872dabf2 --- res/xml/accessibility_settings.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml index fcdf47bcb10..8d5ebf6f7ad 100644 --- a/res/xml/accessibility_settings.xml +++ b/res/xml/accessibility_settings.xml @@ -36,14 +36,12 @@ android:persistent="false" android:title="@string/display_category_title"> - + android:title="@string/accessibility_text_reading_options_title" /> Date: Mon, 14 Feb 2022 10:42:08 +0800 Subject: [PATCH 05/10] =?UTF-8?q?New=20feature=20=E2=80=9CText=20and=20rea?= =?UTF-8?q?ding=20options=E2=80=9D=20for=20SetupWizard,=20Wallpaper,=20and?= =?UTF-8?q?=20Settings=20(19/n).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename the strings related to "text and display" to "color and motion" to avoid misunderstanding. Bug: 211503117 Test: manual test Change-Id: Icdca5ee03fb95a8531406a0f6ab07799a9dfb17c --- color-check-baseline.xml | 2 +- ..._text_and_display.xml => ic_color_and_motion.xml} | 0 res/values/strings.xml | 4 ++-- ...isplay.xml => accessibility_color_and_motion.xml} | 4 ++-- res/xml/accessibility_settings.xml | 8 ++++---- ...playFragment.java => ColorAndMotionFragment.java} | 12 ++++++------ ...mentTest.java => ColorAndMotionFragmentTest.java} | 6 +++--- 7 files changed, 18 insertions(+), 18 deletions(-) rename res/drawable/{ic_text_and_display.xml => ic_color_and_motion.xml} (100%) rename res/xml/{accessibility_text_and_display.xml => accessibility_color_and_motion.xml} (97%) rename src/com/android/settings/accessibility/{TextAndDisplayFragment.java => ColorAndMotionFragment.java} (91%) rename tests/robotests/src/com/android/settings/accessibility/{TextAndDisplayFragmentTest.java => ColorAndMotionFragmentTest.java} (89%) 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/values/strings.xml b/res/values/strings.xml index 36e1193e3ed..cade5211ce3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5150,8 +5150,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 97% rename from res/xml/accessibility_text_and_display.xml rename to res/xml/accessibility_color_and_motion.xml index 659acab5846..26448025845 100644 --- a/res/xml/accessibility_text_and_display.xml +++ b/res/xml/accessibility_color_and_motion.xml @@ -17,9 +17,9 @@ + android:title="@string/accessibility_color_and_motion_title"> 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); } From a52a55f39c9a1241d1b8789ec4a58c373e2b4302 Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Mon, 14 Feb 2022 11:07:11 +0800 Subject: [PATCH 06/10] =?UTF-8?q?New=20feature=20=E2=80=9CText=20and=20rea?= =?UTF-8?q?ding=20options=E2=80=9D=20for=20SetupWizard,=20Wallpaper,=20and?= =?UTF-8?q?=20Settings=20(20/n).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove bold text, high contrast text, display size, and font size preferences in the color and motion layout. Bug: 211503117 Test: manual test Change-Id: I0d12bb65871fafc8901d3d1993e9fa85014ed645 --- res/xml/accessibility_color_and_motion.xml | 31 ---------------------- 1 file changed, 31 deletions(-) diff --git a/res/xml/accessibility_color_and_motion.xml b/res/xml/accessibility_color_and_motion.xml index 26448025845..f251d1e8763 100644 --- a/res/xml/accessibility_color_and_motion.xml +++ b/res/xml/accessibility_color_and_motion.xml @@ -21,31 +21,6 @@ android:persistent="false" android:title="@string/accessibility_color_and_motion_title"> - - - - - - - - Date: Mon, 14 Feb 2022 17:08:37 +0800 Subject: [PATCH 07/10] Allow new users to configure WiFi details - Remove the limitation of the Settings UI for Admin user only. - See b/206986392#comment32 for a screenshot. Bug: 206986392 Test: manual test make RunSettingsRoboTests ROBOTEST_FILTER=WifiNetworkDetailsFragmentTest Change-Id: I31971d644cd475123255ffb6c93c16ff171f77ad --- .../settings/wifi/details/WifiNetworkDetailsFragment.java | 1 - 1 file changed, 1 deletion(-) 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(); } From bf6a2c8136294ee732b2ee69a623163c72b482c1 Mon Sep 17 00:00:00 2001 From: Marie Matheson Date: Fri, 11 Feb 2022 19:04:19 +0000 Subject: [PATCH 08/10] Handle null safety source id list in broadcast receiver. Bug: 215515448 Test: atest SettingsUnitTests Change-Id: I5c8b24533c4ce39ff28f533fbfc7e386639f4983 --- .../SafetySourceBroadcastReceiver.java | 16 +++++++++------- .../SafetySourceBroadcastReceiverTest.java | 10 ++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) 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/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); From 55ce0f7cdddcfedbd89960599b5839647c5c32dd Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Mon, 14 Feb 2022 17:01:25 +0000 Subject: [PATCH 09/10] Fix dream settings OWNERS path Change-Id: I4ebcec52d96cee03448a872984036c314c760eaa --- .../apps/Settings/src => src}/com/android/settings/dream/OWNERS | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {packages/apps/Settings/src => src}/com/android/settings/dream/OWNERS (100%) 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 From 78a0e714c4f33283f135fab6717bd65812c4982d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6llner?= Date: Fri, 4 Feb 2022 13:29:37 +0100 Subject: [PATCH 10/10] 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: If254220ca3018bc6ec1c4e3947375733f6816f92 --- res/values/config.xml | 15 +- res/xml/accessibility_system_controls.xml | 13 ++ res/xml/device_state_auto_rotate_settings.xml | 24 +++ res/xml/display_settings.xml | 15 ++ ...ockScreenRotationPreferenceController.java | 5 +- .../settings/dashboard/DashboardFragment.java | 6 + .../AutoRotatePreferenceController.java | 1 + .../DeviceStateAutoRotateDetailsFragment.java | 76 ++++++++ ...viceStateAutoRotateOverviewController.java | 52 ++++++ ...eviceStateAutoRotateSettingController.java | 141 ++++++++++++++ .../DeviceStateAutoRotationHelper.java | 113 +++++++++++ .../display/SmartAutoRotateController.java | 16 +- .../SmartAutoRotatePreferenceController.java | 1 + .../SmartAutoRotatePreferenceFragment.java | 26 ++- ...creenRotationPreferenceControllerTest.java | 25 ++- .../dashboard/DashboardFragmentTest.java | 22 +++ .../AutoRotatePreferenceControllerTest.java | 33 ++++ ...iceStateAutoRotateDetailsFragmentTest.java | 105 +++++++++++ ...StateAutoRotateOverviewControllerTest.java | 70 +++++++ ...eStateAutoRotateSettingControllerTest.java | 175 ++++++++++++++++++ .../SmartAutoRotateControllerTest.java | 52 ++++++ ...artAutoRotatePreferenceControllerTest.java | 17 +- ...SmartAutoRotatePreferenceFragmentTest.java | 78 +++++++- ...eviceStateRotationLockSettingsManager.java | 39 ++++ 24 files changed, 1106 insertions(+), 14 deletions(-) create mode 100644 res/xml/device_state_auto_rotate_settings.xml create mode 100644 src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java create mode 100644 src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java create mode 100644 src/com/android/settings/display/DeviceStateAutoRotateSettingController.java create mode 100644 src/com/android/settings/display/DeviceStateAutoRotationHelper.java create mode 100644 tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java create mode 100644 tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java 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/xml/accessibility_system_controls.xml b/res/xml/accessibility_system_controls.xml index 71e11436445..37c4d679022 100644 --- a/res/xml/accessibility_system_controls.xml +++ b/res/xml/accessibility_system_controls.xml @@ -42,9 +42,22 @@ android:title="@string/accessibility_power_button_ends_call_prerefence_title" settings:controller="com.android.settings.accessibility.PowerButtonEndsCallPreferenceController"/> + + + + + 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/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/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/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; + } +}