diff options
| author | 2023-09-06 14:28:46 +0000 | |
|---|---|---|
| committer | 2023-09-06 14:28:46 +0000 | |
| commit | aea7caba23390ea954b34a354bec62298a9e532d (patch) | |
| tree | 0290271f46a589d814655e9e9bc260ff646a5808 | |
| parent | 848b83a3730c5ce6c5b074194372e9adac306076 (diff) | |
| parent | 6106935763ce961a9bb9e7ae2753c5c1678ab77d (diff) | |
Merge "Refine fold setting" into udc-qpr-dev
12 files changed, 357 insertions, 76 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index d66ffcebae5e..0b486c00c2da 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4724,13 +4724,13 @@ public final class Settings { public static final String PEAK_REFRESH_RATE = "peak_refresh_rate"; /** - * Control whether to stay awake on fold + * Control lock behavior on fold * * If this isn't set, the system falls back to a device specific default. * @hide */ @Readable - public static final String STAY_AWAKE_ON_FOLD = "stay_awake_on_fold"; + public static final String FOLD_LOCK_BEHAVIOR = "fold_lock_behavior_setting"; /** * The amount of time in milliseconds before the device goes to sleep or begins diff --git a/core/java/com/android/internal/util/SettingsWrapper.java b/core/java/com/android/internal/util/SettingsWrapper.java new file mode 100644 index 000000000000..8cf6c18adb3a --- /dev/null +++ b/core/java/com/android/internal/util/SettingsWrapper.java @@ -0,0 +1,36 @@ +/* + * 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.internal.util; + +import android.content.ContentResolver; +import android.provider.Settings; + +/** + * A wrapper class for accessing and modifying system settings that would help with testing. + */ +public class SettingsWrapper { + + /** Retrieves the string value of a system setting */ + public String getStringForUser(ContentResolver contentResolver, String name, int userHandle) { + return Settings.System.getStringForUser(contentResolver, name, userHandle); + } + + /** Updates the string value of a system setting */ + public String putStringForUser(ContentResolver contentResolver, String name, int userHandle) { + return Settings.System.getStringForUser(contentResolver, name, userHandle); + } +} diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 478b01cfa385..2618fba800a2 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -925,6 +925,9 @@ without impacting power, performance, and app compatibility (e.g. protected content). --> <bool name="config_reduceBrightColorsAvailable">@bool/config_setColorTransformAccelerated</bool> + <!-- Whether to show Fold lock behavior setting feature in Settings App --> + <bool name="config_fold_lock_behavior">false</bool> + <string-array name="config_reduceBrightColorsCoefficientsNonlinear"> <!-- a-coefficient --> <item>-0.4429953456</item> <!-- b-coefficient --> <item>-0.2434077725</item> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 644597c190dc..c78af86f0f39 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -343,6 +343,7 @@ <java-symbol type="string" name="config_defaultHealthConnectApp" /> <java-symbol type="bool" name="config_sendAudioBecomingNoisy" /> <java-symbol type="bool" name="config_enableScreenshotChord" /> + <java-symbol type="bool" name="config_fold_lock_behavior" /> <java-symbol type="bool" name="config_enableWifiDisplay" /> <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" /> <java-symbol type="bool" name="config_useDevInputEventForAudioJack" /> diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java index 6b0a9060d782..248c60cb4fe9 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java @@ -61,7 +61,7 @@ public class SystemSettings { Settings.System.TTY_MODE, Settings.System.MASTER_MONO, Settings.System.MASTER_BALANCE, - Settings.System.STAY_AWAKE_ON_FOLD, + Settings.System.FOLD_LOCK_BEHAVIOR, Settings.System.SOUND_EFFECTS_ENABLED, Settings.System.HAPTIC_FEEDBACK_ENABLED, Settings.System.POWER_SOUNDS_ENABLED, // moved to global diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java index a08d07e1d778..3688d049d380 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java @@ -134,6 +134,7 @@ public class SystemSettingsValidators { VALIDATORS.put(System.HAPTIC_FEEDBACK_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(System.RINGTONE, URI_VALIDATOR); VALIDATORS.put(System.NOTIFICATION_SOUND, URI_VALIDATOR); + VALIDATORS.put(System.FOLD_LOCK_BEHAVIOR, ANY_STRING_VALIDATOR); VALIDATORS.put(System.ALARM_ALERT, URI_VALIDATOR); VALIDATORS.put(System.TEXT_AUTO_REPLACE, BOOLEAN_VALIDATOR); VALIDATORS.put(System.TEXT_AUTO_CAPS, BOOLEAN_VALIDATOR); @@ -218,7 +219,6 @@ public class SystemSettingsValidators { VALIDATORS.put(System.WIFI_STATIC_DNS1, LENIENT_IP_ADDRESS_VALIDATOR); VALIDATORS.put(System.WIFI_STATIC_DNS2, LENIENT_IP_ADDRESS_VALIDATOR); VALIDATORS.put(System.SHOW_BATTERY_PERCENT, BOOLEAN_VALIDATOR); - VALIDATORS.put(System.STAY_AWAKE_ON_FOLD, BOOLEAN_VALIDATOR); VALIDATORS.put(System.NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR); VALIDATORS.put(System.WEAR_ACCESSIBILITY_GESTURE_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(System.CLOCKWORK_BLUETOOTH_SETTINGS_PREF, BOOLEAN_VALIDATOR); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 6546f6e533c0..53921d4d83b5 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -143,6 +143,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.SettingsWrapper; import com.android.server.AnimationThread; import com.android.server.DisplayThread; import com.android.server.LocalServices; @@ -155,7 +156,7 @@ import com.android.server.display.layout.Layout; import com.android.server.display.mode.DisplayModeDirector; import com.android.server.display.utils.SensorUtils; import com.android.server.input.InputManagerInternal; -import com.android.server.utils.FoldSettingWrapper; +import com.android.server.utils.FoldSettingProvider; import com.android.server.wm.SurfaceAnimationThread; import com.android.server.wm.WindowManagerInternal; @@ -542,9 +543,9 @@ public final class DisplayManagerService extends SystemService { mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper()); mUiHandler = UiThread.getHandler(); mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore); - mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, mDisplayDeviceRepo, - new LogicalDisplayListener(), mSyncRoot, mHandler, - new FoldSettingWrapper(mContext.getContentResolver())); + mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, + new FoldSettingProvider(mContext, new SettingsWrapper()), mDisplayDeviceRepo, + new LogicalDisplayListener(), mSyncRoot, mHandler); mDisplayModeDirector = new DisplayModeDirector(context, mHandler); mBrightnessSynchronizer = new BrightnessSynchronizer(mContext); Resources resources = mContext.getResources(); diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 26f8029cf5ac..f99c05179417 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -42,7 +42,7 @@ import android.view.DisplayInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.layout.DisplayIdProducer; import com.android.server.display.layout.Layout; -import com.android.server.utils.FoldSettingWrapper; +import com.android.server.utils.FoldSettingProvider; import java.io.PrintWriter; import java.util.Arrays; @@ -143,7 +143,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private final Listener mListener; private final DisplayManagerService.SyncRoot mSyncRoot; private final LogicalDisplayMapperHandler mHandler; - private final FoldSettingWrapper mFoldSettingWrapper; + private final FoldSettingProvider mFoldSettingProvider; private final PowerManager mPowerManager; /** @@ -189,25 +189,26 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private boolean mBootCompleted = false; private boolean mInteractive; - LogicalDisplayMapper(@NonNull Context context, @NonNull DisplayDeviceRepository repo, + LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider, + @NonNull DisplayDeviceRepository repo, @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot, - @NonNull Handler handler, FoldSettingWrapper foldSettingWrapper) { - this(context, repo, listener, syncRoot, handler, + @NonNull Handler handler) { + this(context, foldSettingProvider, repo, listener, syncRoot, handler, new DeviceStateToLayoutMap((isDefault) -> isDefault ? DEFAULT_DISPLAY - : sNextNonDefaultDisplayId++), foldSettingWrapper); + : sNextNonDefaultDisplayId++)); } - LogicalDisplayMapper(@NonNull Context context, @NonNull DisplayDeviceRepository repo, + LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider, + @NonNull DisplayDeviceRepository repo, @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot, - @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap, - FoldSettingWrapper foldSettingWrapper) { + @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap) { mSyncRoot = syncRoot; mPowerManager = context.getSystemService(PowerManager.class); mInteractive = mPowerManager.isInteractive(); mHandler = new LogicalDisplayMapperHandler(handler.getLooper()); mDisplayDeviceRepo = repo; mListener = listener; - mFoldSettingWrapper = foldSettingWrapper; + mFoldSettingProvider = foldSettingProvider; mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false); mSupportsConcurrentInternalDisplays = context.getResources().getBoolean( com.android.internal.R.bool.config_supportsConcurrentInternalDisplays); @@ -479,10 +480,13 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { }); } else if (sleepDevice) { // Send the device to sleep when required. + int goToSleepFlag = + mFoldSettingProvider.shouldSleepOnFold() ? 0 + : PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP; mHandler.post(() -> { mPowerManager.goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD, - PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP); + goToSleepFlag); }); } } @@ -556,7 +560,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { && mDeviceStatesOnWhichToSleep.get(pendingState) && !mDeviceStatesOnWhichToSleep.get(currentState) && !isOverrideActive - && isInteractive && isBootCompleted && !mFoldSettingWrapper.shouldStayAwakeOnFold(); + && isInteractive && isBootCompleted + && !mFoldSettingProvider.shouldStayAwakeOnFold(); } private boolean areAllTransitioningDisplaysOffLocked() { diff --git a/services/core/java/com/android/server/utils/FoldSettingProvider.java b/services/core/java/com/android/server/utils/FoldSettingProvider.java new file mode 100644 index 000000000000..d62628b73019 --- /dev/null +++ b/services/core/java/com/android/server/utils/FoldSettingProvider.java @@ -0,0 +1,102 @@ +/* + * 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.server.utils; + +import android.content.ContentResolver; +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.Log; + +import com.android.internal.R; +import com.android.internal.util.SettingsWrapper; + +import java.util.Set; + +/** + * This class provides a convenient way to access the {@link Settings.System#FOLD_LOCK_BEHAVIOR}. + * The {@link Settings.System#FOLD_LOCK_BEHAVIOR} setting controls the behavior of the device when + * it is folded, and provides the user with three different options to choose from. Those are: + * 1. Stay awake on fold: The device will remain unlocked when it is folded. + * 2. Selective stay awake: The device will remain unlocked when it is folded only if there are + * apps with wakelocks running. This is also the set default behavior. + * 3. Sleep on fold: The device will lock when it is folded, regardless of which apps are running + * or whether any wakelocks are held. + * + * Keep the setting values in this class in sync with the values in + * {@link com.android.settings.display.FoldLockBehaviorSettings} + */ +public class FoldSettingProvider { + + 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; + private static final Set<String> SETTING_VALUES = Set.of(SETTING_VALUE_STAY_AWAKE_ON_FOLD, + SETTING_VALUE_SELECTIVE_STAY_AWAKE, SETTING_VALUE_SLEEP_ON_FOLD); + private static final String TAG = "FoldSettingProvider"; + + private final ContentResolver mContentResolver; + private final boolean mIsFoldLockBehaviorAvailable; + private final SettingsWrapper mSettingsWrapper; + + public FoldSettingProvider(Context context, SettingsWrapper settingsWrapper) { + mContentResolver = context.getContentResolver(); + mSettingsWrapper = settingsWrapper; + mIsFoldLockBehaviorAvailable = context.getResources().getBoolean( + R.bool.config_fold_lock_behavior); + } + + /** + * Returns whether the device should remain awake after folding. + */ + public boolean shouldStayAwakeOnFold() { + return getFoldSettingValue().equals(SETTING_VALUE_STAY_AWAKE_ON_FOLD); + } + + /** + * Returns whether the device should selective remain awake after folding. + */ + public boolean shouldSelectiveStayAwakeOnFold() { + return getFoldSettingValue().equals(SETTING_VALUE_SELECTIVE_STAY_AWAKE); + } + + /** + * Returns whether the device should strictly sleep after folding. + */ + public boolean shouldSleepOnFold() { + return getFoldSettingValue().equals(SETTING_VALUE_SLEEP_ON_FOLD); + } + + private String getFoldSettingValue() { + if (!mIsFoldLockBehaviorAvailable) { + return SETTING_VALUE_DEFAULT; + } + String foldSettingValue = mSettingsWrapper.getStringForUser( + mContentResolver, + Settings.System.FOLD_LOCK_BEHAVIOR, + UserHandle.USER_CURRENT); + foldSettingValue = (foldSettingValue != null) ? foldSettingValue : SETTING_VALUE_DEFAULT; + if (!SETTING_VALUES.contains(foldSettingValue)) { + Log.e(TAG, + "getFoldSettingValue: Invalid setting value, returning default setting value"); + foldSettingValue = SETTING_VALUE_DEFAULT; + } + + return foldSettingValue; + } +} diff --git a/services/core/java/com/android/server/utils/FoldSettingWrapper.java b/services/core/java/com/android/server/utils/FoldSettingWrapper.java deleted file mode 100644 index 97a1ac06e24c..000000000000 --- a/services/core/java/com/android/server/utils/FoldSettingWrapper.java +++ /dev/null @@ -1,48 +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.server.utils; - -import android.content.ContentResolver; -import android.provider.Settings; - -/** - * A wrapper class for the {@link Settings.System#STAY_AWAKE_ON_FOLD} setting. - * - * This class provides a convenient way to access the {@link Settings.System#STAY_AWAKE_ON_FOLD} - * setting for testing. - */ -public class FoldSettingWrapper { - private final ContentResolver mContentResolver; - - public FoldSettingWrapper(ContentResolver contentResolver) { - mContentResolver = contentResolver; - } - - /** - * Returns whether the device should remain awake after folding. - */ - public boolean shouldStayAwakeOnFold() { - try { - return (Settings.System.getIntForUser( - mContentResolver, - Settings.System.STAY_AWAKE_ON_FOLD, - 0) == 1); - } catch (Settings.SettingNotFoundException e) { - return false; - } - } -} diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java index 0fe6e64b3b54..13c107d0a91e 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java @@ -42,8 +42,12 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -55,6 +59,7 @@ import android.os.IPowerManager; import android.os.IThermalService; import android.os.PowerManager; import android.os.Process; +import android.os.RemoteException; import android.os.test.TestLooper; import android.view.Display; import android.view.DisplayAddress; @@ -65,7 +70,7 @@ import androidx.test.filters.SmallTest; import com.android.server.display.layout.DisplayIdProducer; import com.android.server.display.layout.Layout; -import com.android.server.utils.FoldSettingWrapper; +import com.android.server.utils.FoldSettingProvider; import org.junit.Before; import org.junit.Test; @@ -87,6 +92,7 @@ public class LogicalDisplayMapperTest { private static int sUniqueTestDisplayId = 0; private static final int DEVICE_STATE_CLOSED = 0; private static final int DEVICE_STATE_OPEN = 2; + private static final int FLAG_GO_TO_SLEEP_ON_FOLD = 0; private static int sNextNonDefaultDisplayId = DEFAULT_DISPLAY + 1; private static final File NON_EXISTING_FILE = new File("/non_existing_folder/should_not_exist"); @@ -101,7 +107,7 @@ public class LogicalDisplayMapperTest { @Mock LogicalDisplayMapper.Listener mListenerMock; @Mock Context mContextMock; - @Mock FoldSettingWrapper mFoldSettingWrapperMock; + @Mock FoldSettingProvider mFoldSettingProviderMock; @Mock Resources mResourcesMock; @Mock IPowerManager mIPowerManagerMock; @Mock IThermalService mIThermalServiceMock; @@ -111,7 +117,7 @@ public class LogicalDisplayMapperTest { @Captor ArgumentCaptor<LogicalDisplay> mDisplayCaptor; @Before - public void setUp() { + public void setUp() throws RemoteException { // Share classloader to allow package private access. System.setProperty("dexmaker.share_classloader", "true"); MockitoAnnotations.initMocks(this); @@ -141,7 +147,9 @@ public class LogicalDisplayMapperTest { when(mContextMock.getSystemServiceName(PowerManager.class)) .thenReturn(Context.POWER_SERVICE); - when(mFoldSettingWrapperMock.shouldStayAwakeOnFold()).thenReturn(false); + when(mFoldSettingProviderMock.shouldStayAwakeOnFold()).thenReturn(false); + when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(false); + when(mIPowerManagerMock.isInteractive()).thenReturn(true); when(mContextMock.getSystemService(PowerManager.class)).thenReturn(mPowerManager); when(mContextMock.getResources()).thenReturn(mResourcesMock); when(mResourcesMock.getBoolean( @@ -156,9 +164,10 @@ public class LogicalDisplayMapperTest { mLooper = new TestLooper(); mHandler = new Handler(mLooper.getLooper()); - mLogicalDisplayMapper = new LogicalDisplayMapper(mContextMock, mDisplayDeviceRepo, + mLogicalDisplayMapper = new LogicalDisplayMapper(mContextMock, mFoldSettingProviderMock, + mDisplayDeviceRepo, mListenerMock, new DisplayManagerService.SyncRoot(), mHandler, - mDeviceStateToLayoutMapSpy, mFoldSettingWrapperMock); + mDeviceStateToLayoutMapSpy); } @@ -574,8 +583,8 @@ public class LogicalDisplayMapperTest { } @Test - public void testDeviceShouldNotSleepWhenFoldSettingTrue() { - when(mFoldSettingWrapperMock.shouldStayAwakeOnFold()).thenReturn(true); + public void testDeviceShouldNotSleepWhenStayAwakeSettingTrue() { + when(mFoldSettingProviderMock.shouldStayAwakeOnFold()).thenReturn(true); assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED, DEVICE_STATE_OPEN, @@ -608,6 +617,26 @@ public class LogicalDisplayMapperTest { } @Test + public void testDeviceShouldPutToSleepWhenSleepSettingTrue() throws RemoteException { + when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(true); + + finishBootAndFoldDevice(); + + verify(mIPowerManagerMock, atLeastOnce()).goToSleep(anyLong(), anyInt(), + eq(FLAG_GO_TO_SLEEP_ON_FOLD)); + } + + @Test + public void testDeviceShouldNotBePutToSleepWhenSleepSettingFalse() throws RemoteException { + when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(false); + + finishBootAndFoldDevice(); + + verify(mIPowerManagerMock, never()).goToSleep(anyLong(), anyInt(), + eq(FLAG_GO_TO_SLEEP_ON_FOLD)); + } + + @Test public void testDeviceStateLocked() { DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800, FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); @@ -859,6 +888,15 @@ public class LogicalDisplayMapperTest { // Helper Methods ///////////////// + private void finishBootAndFoldDevice() { + mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_OPEN, false); + advanceTime(1000); + mLogicalDisplayMapper.onBootCompleted(); + advanceTime(1000); + mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_CLOSED, false); + advanceTime(1000); + } + private void createDefaultDisplay(Layout layout, DisplayDevice device) { createDefaultDisplay(layout, info(device).address); } diff --git a/services/tests/mockingservicestests/src/com/android/server/utils/FoldSettingProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/utils/FoldSettingProviderTest.java new file mode 100644 index 000000000000..3514276ccb5b --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/utils/FoldSettingProviderTest.java @@ -0,0 +1,143 @@ +/* + * 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.server.utils; + +import static com.android.server.utils.FoldSettingProvider.SETTING_VALUE_SLEEP_ON_FOLD; +import static com.android.server.utils.FoldSettingProvider.SETTING_VALUE_STAY_AWAKE_ON_FOLD; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; +import android.os.UserHandle; +import android.provider.Settings; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.internal.R; +import com.android.internal.util.SettingsWrapper; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class FoldSettingProviderTest { + + private static final String SETTING_VALUE_INVALID = "invalid_fold_lock_behavior"; + + @Mock + private Context mContext; + @Mock + private Resources mResources; + @Mock + private SettingsWrapper mSettingsWrapper; + private ContentResolver mContentResolver; + private FoldSettingProvider mFoldSettingProvider; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContentResolver = + InstrumentationRegistry.getInstrumentation().getContext().getContentResolver(); + when(mContext.getContentResolver()).thenReturn(mContentResolver); + when(mContext.getResources()).thenReturn(mResources); + setFoldLockBehaviorAvailability(true); + + mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper); + } + + @Test + public void foldSettingNotAvailable_returnDefaultSetting() { + setFoldLockBehaviorAvailability(false); + setFoldLockBehaviorSettingValue(SETTING_VALUE_STAY_AWAKE_ON_FOLD); + mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper); + + boolean shouldSelectiveStayAwakeOnFold = + mFoldSettingProvider.shouldSelectiveStayAwakeOnFold(); + + assertThat(shouldSelectiveStayAwakeOnFold).isTrue(); + } + + @Test + public void foldSettingNotAvailable_notReturnStayAwakeOnFoldTrue() { + setFoldLockBehaviorAvailability(false); + setFoldLockBehaviorSettingValue(SETTING_VALUE_STAY_AWAKE_ON_FOLD); + mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper); + + boolean shouldStayAwakeOnFold = mFoldSettingProvider.shouldStayAwakeOnFold(); + + assertThat(shouldStayAwakeOnFold).isFalse(); + } + + @Test + public void foldSettingNotAvailable_notReturnSleepOnFoldTrue() { + setFoldLockBehaviorAvailability(false); + setFoldLockBehaviorSettingValue(SETTING_VALUE_SLEEP_ON_FOLD); + mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper); + + boolean shouldSleepOnFold = mFoldSettingProvider.shouldSleepOnFold(); + + assertThat(shouldSleepOnFold).isFalse(); + } + + @Test + public void foldSettingAvailable_returnCorrectFoldSetting() { + setFoldLockBehaviorSettingValue(SETTING_VALUE_STAY_AWAKE_ON_FOLD); + + boolean shouldStayAwakeOnFold = mFoldSettingProvider.shouldStayAwakeOnFold(); + + assertThat(shouldStayAwakeOnFold).isTrue(); + } + + @Test + public void foldSettingInvalid_returnDefaultSetting() { + setFoldLockBehaviorSettingValue(SETTING_VALUE_INVALID); + + boolean shouldSelectiveStayAwakeOnFold = + mFoldSettingProvider.shouldSelectiveStayAwakeOnFold(); + + assertThat(shouldSelectiveStayAwakeOnFold).isTrue(); + } + + @Test + public void foldSettingNotDefined_returnDefaultSetting() { + setFoldLockBehaviorSettingValue(null); + + boolean shouldSelectiveStayAwakeOnFold = + mFoldSettingProvider.shouldSelectiveStayAwakeOnFold(); + + assertThat(shouldSelectiveStayAwakeOnFold).isTrue(); + } + + private void setFoldLockBehaviorAvailability(boolean isFoldLockBehaviorEnabled) { + when(mResources.getBoolean(R.bool.config_fold_lock_behavior)).thenReturn( + isFoldLockBehaviorEnabled); + } + + private void setFoldLockBehaviorSettingValue(String foldLockBehaviorSettingValue) { + when(mSettingsWrapper.getStringForUser(any(), + eq(Settings.System.FOLD_LOCK_BEHAVIOR), + eq(UserHandle.USER_CURRENT))).thenReturn(foldLockBehaviorSettingValue); + } +} |