Refine fold setting

Current fold setting has a toggle button which can enable the “Stay unlocked on fold” setting.
Create a new page for fold setting which will allow us to choose something from three options.(https://screenshot.googleplex.com/6W65aTYtigGpr3v)
 *Always - Front display turns on when you fold your device [Currently available setting]
 *Only games, videos, and more - Front display turns on for apps that stop your screen going idle [Default]
 *Never - Front display locks when you fold your device [New option for user]

Test: atest FoldLockBehaviorSettingsTest FoldLockBehaviorPreferenceControllerTest
*Manual
  Flash the build with these changes
  Manually select options one by one
  Observe the behavior

Fixes: 294194379
Change-Id: Ie5b4e1d7560ed645ec2ca5f49cc9715b17d21367
This commit is contained in:
dshivangi
2023-08-03 19:49:54 +00:00
committed by Shivangi Dubey
parent b675bb6d3a
commit dc485887cc
10 changed files with 427 additions and 208 deletions

View File

@@ -545,9 +545,6 @@
<!-- Whether to show Smooth Display feature in Settings Options -->
<bool name="config_show_smooth_display">false</bool>
<!-- Whether to show Stay awake on fold feature in Settings Options -->
<bool name="config_stay_awake_on_fold">false</bool>
<!-- Whether to show emergency settings in top-level Settings -->
<bool name="config_show_emergency_settings">true</bool>

View File

@@ -80,6 +80,19 @@
<!-- Description for the button that makes interface elements larger. [CHAR_LIMIT=NONE] -->
<string name="font_size_make_larger_desc">Make larger</string>
<!-- Title for stay awake on fold radio button. [CHAR_LIMIT=NONE] -->
<string name="stay_awake_on_fold_title">Always</string>
<!-- Summary for stay awake on fold radio button. [CHAR_LIMIT=NONE] -->
<string name="stay_awake_on_fold_summary">Front display turns on when you fold your device</string>
<!-- Title for selective stay awake radio button. [CHAR_LIMIT=NONE] -->
<string name="selective_stay_awake_title">Only games, videos, and more</string>
<!-- Summary for selective stay awake radio button. [CHAR_LIMIT=NONE] -->
<string name="selective_stay_awake_summary">Front display turns on for apps that stop your screen going idle</string>
<!-- Title for sleep on fold radio button. [CHAR_LIMIT=NONE] -->
<string name="sleep_on_fold_title">Never</string>
<!-- Summary for sleep on fold radio button. [CHAR_LIMIT=NONE] -->
<string name="sleep_on_fold_summary">Front display locks when you fold your device</string>
<!-- Auto rotate switchbar title. [CHAR_LIMIT=NONE] -->
<string name="auto_rotate_settings_primary_switch_title">Use auto-rotate</string>
@@ -2466,10 +2479,8 @@
<string name="display_white_balance_title">Display white balance</string>
<!-- Display settings screen, display white balance settings summary [CHAR LIMIT=NONE] -->
<string name="display_white_balance_summary"></string>
<!-- Display settings screen, setting name to enable staying awake on fold [CHAR LIMIT=30] -->
<string name="stay_awake_on_fold_title">Stay unlocked on fold</string>
<!-- Display settings screen, setting summary to enable staying awake on fold [CHAR LIMIT=NONE] -->
<string name="stay_awake_on_fold_summary">Keep front display unlocked when folded until screen timeout</string>
<!-- Display settings screen, setting option name to change Fold setting -->
<string name="fold_lock_behavior_title">Continue using apps on fold</string>
<!-- Display settings screen, peak refresh rate settings title [CHAR LIMIT=30] -->
<string name="peak_refresh_rate_title">Smooth Display</string>
<!-- Display settings screen, peak refresh rate settings summary [CHAR LIMIT=NONE] -->
@@ -7163,7 +7174,7 @@
<string name="keywords_app_pinning">screen pinning</string>
<string name="keywords_profile_challenge">work challenge, work, profile</string>
<string name="keywords_unification">work profile, managed profile, unify, unification, work, profile</string>
<string name="keywords_stay_awake_on_lock">
<string name="keywords_fold_lock_behavior">
awake, sleep, do not lock, stay unlocked on fold, folding, closing, fold, close, screen off
</string>
<string name="keywords_gesture">gestures</string>

View File

@@ -48,12 +48,12 @@
settings:keywords="@string/keywords_ambient_display_screen"
settings:controller="com.android.settings.security.screenlock.LockScreenPreferenceController"/>
<SwitchPreference
android:key="stay_awake_on_fold"
android:title="@string/stay_awake_on_fold_title"
android:summary="@string/stay_awake_on_fold_summary"
settings:keywords="@string/keywords_stay_awake_on_lock"
settings:controller="com.android.settings.display.StayAwakeOnFoldPreferenceController"/>
<com.android.settingslib.RestrictedPreference
android:fragment="com.android.settings.display.FoldLockBehaviorSettings"
android:key="fold_lock_behavior"
android:title="@string/fold_lock_behavior_title"
settings:controller="com.android.settings.display.FoldLockBehaviorPreferenceController"
settings:keywords="@string/keywords_fold_lock_behavior" />
<com.android.settingslib.RestrictedPreference
android:key="screen_timeout"

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/fold_lock_behavior_title"/>

View File

@@ -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<String, String> 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();
}
}

View File

@@ -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<String> 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<? extends CandidateInfo> getCandidates() {
List<CandidateInfoExtra> 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();
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}