diff --git a/res/values/config.xml b/res/values/config.xml index 687fa1596bc..17c33989502 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -548,9 +548,6 @@ false - - false - true diff --git a/res/values/strings.xml b/res/values/strings.xml index 26738d6deb4..07d05f9cf5d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -80,6 +80,19 @@ Make larger + + Always + + Front display turns on when you fold your device + + Only games, videos, and more + + Front display turns on for apps that stop your screen going idle + + Never + + Front display locks when you fold your device + Use auto-rotate @@ -2379,10 +2392,8 @@ Display white balance - - Stay unlocked on fold - - Keep front display unlocked when folded until screen timeout + + Continue using apps on fold Smooth Display @@ -7056,7 +7067,7 @@ screen pinning work challenge, work, profile work profile, managed profile, unify, unification, work, profile - + awake, sleep, do not lock, stay unlocked on fold, folding, closing, fold, close, screen off gestures diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml index f94ba70a701..c5e559cd8a7 100644 --- a/res/xml/display_settings.xml +++ b/res/xml/display_settings.xml @@ -48,12 +48,12 @@ settings:keywords="@string/keywords_ambient_display_screen" settings:controller="com.android.settings.security.screenlock.LockScreenPreferenceController"/> - + + + diff --git a/src/com/android/settings/display/FoldLockBehaviorPreferenceController.java b/src/com/android/settings/display/FoldLockBehaviorPreferenceController.java new file mode 100644 index 00000000000..88e78e80a95 --- /dev/null +++ b/src/com/android/settings/display/FoldLockBehaviorPreferenceController.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2023 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 android.provider.Settings.System.FOLD_LOCK_BEHAVIOR; + +import static com.android.settings.display.FoldLockBehaviorSettings.SETTING_VALUES; +import static com.android.settings.display.FoldLockBehaviorSettings.SETTING_VALUE_SELECTIVE_STAY_AWAKE; +import static com.android.settings.display.FoldLockBehaviorSettings.SETTING_VALUE_SLEEP_ON_FOLD; +import static com.android.settings.display.FoldLockBehaviorSettings.SETTING_VALUE_STAY_AWAKE_ON_FOLD; + +import android.content.Context; +import android.content.res.Resources; +import android.os.UserHandle; +import android.provider.Settings; + +import androidx.preference.Preference; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; + +import java.util.HashMap; +import java.util.Map; + +/** + * A preference controller for the @link android.provider.Settings.System#FOLD_LOCK_BEHAVIOR + * setting. + * + * This preference controller allows users to control whether or not the device + * stays awake when it is folded. + */ +public class FoldLockBehaviorPreferenceController extends BasePreferenceController { + + private final Resources mResources; + + private static Map KEY_TO_TEXT = new HashMap<>(); + + public FoldLockBehaviorPreferenceController(Context context, String key) { + this(context, key, context.getResources()); + } + + public FoldLockBehaviorPreferenceController(Context context, String key, Resources resources) { + super(context, key); + mResources = resources; + KEY_TO_TEXT.put(SETTING_VALUE_STAY_AWAKE_ON_FOLD, + resourceToString(R.string.stay_awake_on_fold_title)); + KEY_TO_TEXT.put(SETTING_VALUE_SELECTIVE_STAY_AWAKE, + resourceToString(R.string.selective_stay_awake_title)); + KEY_TO_TEXT.put(SETTING_VALUE_SLEEP_ON_FOLD, + resourceToString(R.string.sleep_on_fold_title)); + } + + @Override + public int getAvailabilityStatus() { + return mResources.getBoolean(com.android.internal.R.bool.config_fold_lock_behavior) + ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } + + @Override + public void updateState(Preference preference) { + String summary = KEY_TO_TEXT.get(getFoldSettingValue()); + preference.setSummary(summary); + } + + private String getFoldSettingValue() { + String foldSettingValue = Settings.System.getStringForUser(mContext.getContentResolver(), + FOLD_LOCK_BEHAVIOR, UserHandle.USER_CURRENT); + return (foldSettingValue != null && SETTING_VALUES.contains(foldSettingValue)) + ? foldSettingValue : SETTING_VALUE_SELECTIVE_STAY_AWAKE; + } + + @Override + public int getSliceHighlightMenuRes() { + return R.string.menu_key_display; + } + + private String resourceToString(int resource) { + return mContext.getText(resource).toString(); + } + +} diff --git a/src/com/android/settings/display/FoldLockBehaviorSettings.java b/src/com/android/settings/display/FoldLockBehaviorSettings.java new file mode 100644 index 00000000000..beda52e8696 --- /dev/null +++ b/src/com/android/settings/display/FoldLockBehaviorSettings.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2023 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 android.provider.Settings.System.FOLD_LOCK_BEHAVIOR; + +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.Log; + +import com.android.settings.R; +import com.android.settings.support.actionbar.HelpResourceProvider; +import com.android.settings.utils.CandidateInfoExtra; +import com.android.settings.widget.RadioButtonPickerFragment; +import com.android.settingslib.widget.CandidateInfo; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Fragment that is used to control fold setting. + * + * Keep the setting values in this class in sync with the values in + * {@link com.android.server.utils.FoldSettingProvider} + */ +public class FoldLockBehaviorSettings extends RadioButtonPickerFragment implements + HelpResourceProvider { + + public static final String SETTING_VALUE_STAY_AWAKE_ON_FOLD = "stay_awake_on_fold_key"; + public static final String SETTING_VALUE_SELECTIVE_STAY_AWAKE = "selective_stay_awake_key"; + public static final String SETTING_VALUE_SLEEP_ON_FOLD = "sleep_on_fold_key"; + private static final String SETTING_VALUE_DEFAULT = SETTING_VALUE_SELECTIVE_STAY_AWAKE; + public static final String TAG = "FoldLockBehaviorSetting"; + public static final HashSet SETTING_VALUES = new HashSet<>( + Set.of(SETTING_VALUE_STAY_AWAKE_ON_FOLD, SETTING_VALUE_SELECTIVE_STAY_AWAKE, + SETTING_VALUE_SLEEP_ON_FOLD)); + + private Context mContext; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Override + protected List getCandidates() { + List candidates = new ArrayList<>(); + candidates.add(new CandidateInfoExtra( + resourceToString(R.string.stay_awake_on_fold_title), + resourceToString(R.string.stay_awake_on_fold_summary), + SETTING_VALUE_STAY_AWAKE_ON_FOLD, /* enabled */ true)); + candidates.add(new CandidateInfoExtra( + resourceToString(R.string.selective_stay_awake_title), + resourceToString(R.string.selective_stay_awake_summary), + SETTING_VALUE_SELECTIVE_STAY_AWAKE, /* enabled */ true)); + candidates.add(new CandidateInfoExtra( + resourceToString(R.string.sleep_on_fold_title), + resourceToString(R.string.sleep_on_fold_summary), + SETTING_VALUE_SLEEP_ON_FOLD, /* enabled */ true)); + return candidates; + } + + @Override + public void bindPreferenceExtra(SelectorWithWidgetPreference pref, + String key, CandidateInfo info, String defaultKey, String systemDefaultKey) { + if (!(info instanceof CandidateInfoExtra)) { + return; + } + + pref.setSummary(((CandidateInfoExtra) info).loadSummary()); + } + + @Override + protected String getDefaultKey() { + String foldSettingValue = getCurrentFoldSettingValue(); + foldSettingValue = (foldSettingValue != null) ? foldSettingValue : SETTING_VALUE_DEFAULT; + if (!SETTING_VALUES.contains(foldSettingValue)) { + Log.e(TAG, + "getDefaultKey: Invalid setting value, returning default setting value"); + foldSettingValue = SETTING_VALUE_DEFAULT; + } + + return foldSettingValue; + } + + @Override + protected boolean setDefaultKey(String key) { + if (!SETTING_VALUES.contains(key)) { + Log.e(TAG, "setDefaultKey: Can not set invalid key: " + key); + key = SETTING_VALUE_SELECTIVE_STAY_AWAKE; + } + setCurrentFoldSettingValue(key); + return true; + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.FOLD_LOCK_BEHAVIOR; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.fold_lock_behavior_settings; + } + + private String getCurrentFoldSettingValue() { + return Settings.System.getStringForUser(mContext.getContentResolver(), + FOLD_LOCK_BEHAVIOR, + UserHandle.USER_CURRENT); + } + + private void setCurrentFoldSettingValue(String key) { + Settings.System.putStringForUser(mContext.getContentResolver(), + FOLD_LOCK_BEHAVIOR, + key, + UserHandle.USER_CURRENT); + } + + private String resourceToString(int resource) { + return mContext.getText(resource).toString(); + } +} diff --git a/src/com/android/settings/display/StayAwakeOnFoldPreferenceController.java b/src/com/android/settings/display/StayAwakeOnFoldPreferenceController.java deleted file mode 100644 index 9df48f377ad..00000000000 --- a/src/com/android/settings/display/StayAwakeOnFoldPreferenceController.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2023 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.content.res.Resources; -import android.provider.Settings; - -import com.android.settings.R; -import com.android.settings.core.TogglePreferenceController; - -/** - * A preference controller for the "Stay unlocked on fold" setting. - * - * This preference controller allows users to control whether or not the device - * stays awake when it is folded. When this setting is enabled, the device will - * stay awake even if the device is folded. - * - * @link android.provider.Settings.System#STAY_AWAKE_ON_FOLD - */ -public class StayAwakeOnFoldPreferenceController extends TogglePreferenceController { - - private final Resources mResources; - - public StayAwakeOnFoldPreferenceController(Context context, String key) { - this(context, key, context.getResources()); - } - - public StayAwakeOnFoldPreferenceController(Context context, String key, Resources resources) { - super(context, key); - mResources = resources; - } - - @Override - public int getAvailabilityStatus() { - return mResources.getBoolean(R.bool.config_stay_awake_on_fold) ? AVAILABLE - : UNSUPPORTED_ON_DEVICE; - } - - @Override - public boolean isChecked() { - return Settings.System.getInt( - mContext.getContentResolver(), - Settings.System.STAY_AWAKE_ON_FOLD, - 0) == 1; - } - - @Override - public boolean setChecked(boolean isChecked) { - final int stayUnlockedOnFold = isChecked ? 1 : 0; - - return Settings.System.putInt(mContext.getContentResolver(), - Settings.System.STAY_AWAKE_ON_FOLD, stayUnlockedOnFold); - } - - @Override - public int getSliceHighlightMenuRes() { - return R.string.menu_key_display; - } - -} diff --git a/tests/robotests/src/com/android/settings/display/FoldLockBehaviorPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/FoldLockBehaviorPreferenceControllerTest.java new file mode 100644 index 00000000000..2510bf141a2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/FoldLockBehaviorPreferenceControllerTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023 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 static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.res.Resources; + +import com.android.internal.R; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class FoldLockBehaviorPreferenceControllerTest { + + @Mock + private Resources mResources; + private Context mContext; + private FoldLockBehaviorPreferenceController mController; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mResources = Mockito.mock(Resources.class); + mController = new FoldLockBehaviorPreferenceController(mContext, "key", mResources); + } + + @Test + public void getAvailabilityStatus_withConfigNoShow_returnUnsupported() { + when(mResources.getBoolean(R.bool.config_fold_lock_behavior)).thenReturn(false); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } + + @Test + public void getAvailabilityStatus_withConfigNoShow_returnAvailable() { + when(mResources.getBoolean(R.bool.config_fold_lock_behavior)).thenReturn(true); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } +} diff --git a/tests/robotests/src/com/android/settings/display/FoldLockBehaviorSettingsTest.java b/tests/robotests/src/com/android/settings/display/FoldLockBehaviorSettingsTest.java new file mode 100644 index 00000000000..37b9391a443 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/FoldLockBehaviorSettingsTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2023 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 android.provider.Settings.System.FOLD_LOCK_BEHAVIOR; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class FoldLockBehaviorSettingsTest { + + private Context mContext; + private FoldLockBehaviorSettings mSetting; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mSetting = new FoldLockBehaviorSettings(); + mSetting.onAttach(mContext); + } + + @Test + public void getDefaultKey_returnFoldSetting() { + setFoldSetting("stay_awake_on_fold_key"); + + String key = mSetting.getDefaultKey(); + + assertThat(key).isEqualTo("stay_awake_on_fold_key"); + } + + @Test + public void setDefaultKey_returnFoldSetting() { + mSetting.setDefaultKey("stay_awake_on_fold_key"); + + String key = getFoldSettingValue(); + + assertThat(key).isEqualTo("stay_awake_on_fold_key"); + } + + @Test + public void setInvalidDefaultKey_returnDefaultFoldSetting() { + setFoldSetting("invalid_fold_lock_behavior_key"); + + String key = mSetting.getDefaultKey(); + + assertThat(key).isEqualTo("selective_stay_awake_key"); + } + + private void setFoldSetting(String selectedSetting) { + Settings.System.putStringForUser(mContext.getContentResolver(), + FOLD_LOCK_BEHAVIOR, selectedSetting, UserHandle.USER_CURRENT); + } + + private String getFoldSettingValue() { + return Settings.System.getStringForUser(mContext.getContentResolver(), + FOLD_LOCK_BEHAVIOR, UserHandle.USER_CURRENT); + } +} diff --git a/tests/robotests/src/com/android/settings/display/StayAwakeOnFoldPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/StayAwakeOnFoldPreferenceControllerTest.java deleted file mode 100644 index c9948183bba..00000000000 --- a/tests/robotests/src/com/android/settings/display/StayAwakeOnFoldPreferenceControllerTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2023 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 static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.res.Resources; -import android.provider.Settings; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class StayAwakeOnFoldPreferenceControllerTest { - - @Mock - private Resources mResources; - private Context mContext; - private StayAwakeOnFoldPreferenceController mController; - - @Before - public void setUp() { - mContext = RuntimeEnvironment.application; - mResources = Mockito.mock(Resources.class); - mController = new StayAwakeOnFoldPreferenceController(mContext, "key", mResources); - } - - @Test - public void getAvailabilityStatus_withConfigNoShow_returnUnsupported() { - when(mResources.getBoolean(R.bool.config_stay_awake_on_fold)).thenReturn(false); - - assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); - } - - @Test - public void getAvailabilityStatus_withConfigNoShow_returnAvailable() { - when(mResources.getBoolean(R.bool.config_stay_awake_on_fold)).thenReturn(true); - - assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); - } - - @Test - public void setChecked_enableStayAwakeOnFold_setChecked() { - mController.setChecked(true); - - assertThat(isStayAwakeOnFoldEnabled()) - .isTrue(); - } - - @Test - public void setChecked_disableStayAwakeOnFold_setUnchecked() { - mController.setChecked(false); - - assertThat(isStayAwakeOnFoldEnabled()) - .isFalse(); - } - - @Test - public void isChecked_enableStayAwakeOnFold_returnTrue() { - enableStayAwakeOnFoldPreference(); - - assertThat(mController.isChecked()).isTrue(); - } - - @Test - public void isChecked_disableStayAwakeOnFold_returnFalse() { - disableStayAwakeOnFoldPreference(); - - assertThat(mController.isChecked()).isFalse(); - } - - private void enableStayAwakeOnFoldPreference() { - Settings.System.putInt( - mContext.getContentResolver(), - Settings.System.STAY_AWAKE_ON_FOLD, - 1); - } - - private void disableStayAwakeOnFoldPreference() { - Settings.System.putInt( - mContext.getContentResolver(), - Settings.System.STAY_AWAKE_ON_FOLD, - 0); - } - - private boolean isStayAwakeOnFoldEnabled() { - return (Settings.System.getInt( - mContext.getContentResolver(), - Settings.System.STAY_AWAKE_ON_FOLD, - 0) == 1); - } -}