Restore long press power behaviour setting

The LPP setting is a bit special - the behaviour is configured by the config.xml and can then be modified via user setting to invoke Assistant if available. When restoring this value we need to be careful to not clobber default config.xml device settings if the user can't change it later. We strongly prefer to rely on config.xml device value in any case.

Bug: 215540406
Test: atest SettingsProvider
Change-Id: I8898a52a5d28f0957f44f3075498b1139c8ce831
This commit is contained in:
Jernej Virag
2022-03-17 16:16:28 +00:00
parent f811f765de
commit 1a85be89c7
3 changed files with 199 additions and 0 deletions

View File

@@ -82,5 +82,6 @@ public class GlobalSettings {
Settings.Global.USER_PREFERRED_REFRESH_RATE,
Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT,
Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH,
Settings.Global.POWER_BUTTON_LONG_PRESS
};
}

View File

@@ -53,6 +53,13 @@ public class SettingsHelper {
private static final String SETTING_ORIGINAL_KEY_SUFFIX = "_original";
private static final float FLOAT_TOLERANCE = 0.01f;
/** See frameworks/base/core/res/res/values/config.xml#config_longPressOnPowerBehavior **/
private static final int LONG_PRESS_POWER_NOTHING = 0;
private static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
private static final int LONG_PRESS_POWER_FOR_ASSISTANT = 5;
/** See frameworks/base/core/res/res/values/config.xml#config_keyChordPowerVolumeUp **/
private static final int KEY_CHORD_POWER_VOLUME_UP_GLOBAL_ACTIONS = 2;
private Context mContext;
private AudioManager mAudioManager;
private TelephonyManager mTelephonyManager;
@@ -190,6 +197,9 @@ public class SettingsHelper {
&& !displayColorModeVendorModeHintsMatch) {
return;
}
} else if (Settings.Global.POWER_BUTTON_LONG_PRESS.equals(name)) {
setLongPressPowerBehavior(cr, value);
return;
}
// Default case: write the restored value to settings
@@ -374,6 +384,67 @@ public class SettingsHelper {
}
}
/**
* Correctly sets long press power button Behavior.
*
* The issue is that setting for LongPressPower button Behavior is not available on all devices
* and actually changes default Behavior of two properties - the long press power button
* and volume up + power button combo. OEM can also reconfigure these Behaviors in config.xml,
* so we need to be careful that we don't irreversibly change power button Behavior when
* restoring. Or switch to a non-default button Behavior.
*/
private void setLongPressPowerBehavior(ContentResolver cr, String value) {
// We will not restore the value if the long press power setting option is unavailable.
if (!mContext.getResources().getBoolean(
com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable)) {
return;
}
int longPressOnPowerBehavior;
try {
longPressOnPowerBehavior = Integer.parseInt(value);
} catch (NumberFormatException e) {
return;
}
if (longPressOnPowerBehavior < LONG_PRESS_POWER_NOTHING
|| longPressOnPowerBehavior > LONG_PRESS_POWER_FOR_ASSISTANT) {
return;
}
// When user enables long press power for Assistant, we also switch the meaning
// of Volume Up + Power key chord to the "Show power menu" option.
// If the user disables long press power for Assistant, we switch back to default OEM
// Behavior configured in config.xml. If the default Behavior IS "LPP for Assistant",
// then we fall back to "Long press for Power Menu" Behavior.
if (longPressOnPowerBehavior == LONG_PRESS_POWER_FOR_ASSISTANT) {
Settings.Global.putInt(cr, Settings.Global.POWER_BUTTON_LONG_PRESS,
LONG_PRESS_POWER_FOR_ASSISTANT);
Settings.Global.putInt(cr, Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
KEY_CHORD_POWER_VOLUME_UP_GLOBAL_ACTIONS);
} else {
// We're restoring "LPP for Assistant Disabled" state, prefer OEM config.xml Behavior
// if possible.
int longPressOnPowerDeviceBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnPowerBehavior);
if (longPressOnPowerDeviceBehavior == LONG_PRESS_POWER_FOR_ASSISTANT) {
// The default on device IS "LPP for Assistant Enabled" so fall back to power menu.
Settings.Global.putInt(cr, Settings.Global.POWER_BUTTON_LONG_PRESS,
LONG_PRESS_POWER_GLOBAL_ACTIONS);
} else {
// The default is non-Assistant Behavior, so restore that default.
Settings.Global.putInt(cr, Settings.Global.POWER_BUTTON_LONG_PRESS,
longPressOnPowerDeviceBehavior);
}
// Clear and restore default power + volume up Behavior as well.
int powerVolumeUpDefaultBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_keyChordPowerVolumeUp);
Settings.Global.putInt(cr, Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
powerVolumeUpDefaultBehavior);
}
}
/* package */ byte[] getLocaleData() {
Configuration conf = mContext.getResources().getConfiguration();
return conf.getLocales().toLanguageTags().getBytes();

View File

@@ -16,6 +16,8 @@
package com.android.providers.settings;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
@@ -27,13 +29,19 @@ import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
import android.net.Uri;
import android.os.LocaleList;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,20 +60,28 @@ public class SettingsHelperTest {
private SettingsHelper mSettingsHelper;
@Mock private Context mContext;
@Mock private Resources mResources;
@Mock private ContentResolver mContentResolver;
@Mock private AudioManager mAudioManager;
@Mock private TelephonyManager mTelephonyManager;
@Before
public void setUp() {
clearLongPressPowerValues();
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(eq(Context.AUDIO_SERVICE))).thenReturn(mAudioManager);
when(mContext.getSystemService(eq(Context.TELEPHONY_SERVICE))).thenReturn(
mTelephonyManager);
when(mContext.getResources()).thenReturn(mResources);
mSettingsHelper = spy(new SettingsHelper(mContext));
}
@After
public void tearDown() {
clearLongPressPowerValues();
}
@Test
public void testOnBackupValue_settingReplaced_returnsRealValue() {
when(mSettingsHelper.isReplacedSystemSetting(eq(SETTING_KEY))).thenReturn(true);
@@ -91,6 +107,110 @@ public class SettingsHelperTest {
verifyZeroInteractions(mContentResolver);
}
@Test
public void testRestoreValue_lppForAssistantEnabled_updatesValue() {
ContentResolver cr =
InstrumentationRegistry.getInstrumentation().getTargetContext()
.getContentResolver();
when(mResources.getBoolean(
R.bool.config_longPressOnPowerForAssistantSettingAvailable)).thenReturn(
true);
mSettingsHelper.restoreValue(mContext, cr, new ContentValues(), Uri.EMPTY,
Settings.Global.POWER_BUTTON_LONG_PRESS, "5", 0);
assertThat(
Settings.Global.getInt(cr, Settings.Global.POWER_BUTTON_LONG_PRESS, -1))
.isEqualTo(5);
assertThat(Settings.Global.getInt(cr, Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
-1)).isEqualTo(2);
}
@Test
public void testRestoreValue_lppForAssistantNotEnabled_updatesValueToDefaultConfig() {
ContentResolver cr =
InstrumentationRegistry.getInstrumentation().getTargetContext()
.getContentResolver();
when(mResources.getBoolean(
R.bool.config_longPressOnPowerForAssistantSettingAvailable)).thenReturn(
true);
when(mResources.getInteger(
R.integer.config_longPressOnPowerBehavior)).thenReturn(
1);
when(mResources.getInteger(
R.integer.config_keyChordPowerVolumeUp)).thenReturn(
1);
mSettingsHelper.restoreValue(mContext, cr, new ContentValues(), Uri.EMPTY,
Settings.Global.POWER_BUTTON_LONG_PRESS, "2", 0);
assertThat(
Settings.Global.getInt(cr, Settings.Global.POWER_BUTTON_LONG_PRESS, -1))
.isEqualTo(1);
assertThat(Settings.Global.getInt(cr, Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
-1)).isEqualTo(1);
}
@Test
public void testRestoreValue_lppForAssistantNotEnabledDefaultConfig_updatesValue() {
ContentResolver cr =
InstrumentationRegistry.getInstrumentation().getTargetContext()
.getContentResolver();
when(mResources.getBoolean(
R.bool.config_longPressOnPowerForAssistantSettingAvailable)).thenReturn(
true);
when(mResources.getInteger(
R.integer.config_longPressOnPowerBehavior)).thenReturn(
5);
when(mResources.getInteger(
R.integer.config_keyChordPowerVolumeUp)).thenReturn(
1);
mSettingsHelper.restoreValue(mContext, cr, new ContentValues(), Uri.EMPTY,
Settings.Global.POWER_BUTTON_LONG_PRESS, "2", 0);
assertThat(
Settings.Global.getInt(cr, Settings.Global.POWER_BUTTON_LONG_PRESS, -1))
.isEqualTo(1);
assertThat(Settings.Global.getInt(cr, Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
-1)).isEqualTo(1);
}
@Test
public void testRestoreValue_lppForAssistantNotAvailable_doesNotRestore() {
ContentResolver cr =
InstrumentationRegistry.getInstrumentation().getTargetContext()
.getContentResolver();
when(mResources.getBoolean(
R.bool.config_longPressOnPowerForAssistantSettingAvailable)).thenReturn(
false);
mSettingsHelper.restoreValue(mContext, cr, new ContentValues(), Uri.EMPTY,
Settings.Global.POWER_BUTTON_LONG_PRESS, "5", 0);
assertThat((Settings.Global.getInt(cr, Settings.Global.POWER_BUTTON_LONG_PRESS,
-1))).isEqualTo(-1);
}
@Test
public void testRestoreValue_lppForAssistantInvalid_doesNotRestore() {
ContentResolver cr =
InstrumentationRegistry.getInstrumentation().getTargetContext()
.getContentResolver();
when(mResources.getBoolean(
R.bool.config_longPressOnPowerForAssistantSettingAvailable)).thenReturn(
false);
mSettingsHelper.restoreValue(mContext, cr, new ContentValues(), Uri.EMPTY,
Settings.Global.POWER_BUTTON_LONG_PRESS, "trees", 0);
assertThat((Settings.Global.getInt(cr, Settings.Global.POWER_BUTTON_LONG_PRESS,
-1))).isEqualTo(-1);
}
@Test
public void testResolveLocales() throws Exception {
// Empty string from backup server
@@ -184,4 +304,11 @@ public class SettingsHelperTest {
LocaleList.forLanguageTags("en-US"), // current
new String[] { "he-IL", "id-ID", "yi" })); // supported
}
private void clearLongPressPowerValues() {
ContentResolver cr = InstrumentationRegistry.getInstrumentation().getTargetContext()
.getContentResolver();
Settings.Global.putString(cr, Settings.Global.POWER_BUTTON_LONG_PRESS, null);
Settings.Global.putString(cr, Settings.Global.KEY_CHORD_POWER_VOLUME_UP, null);
}
}