diff options
3 files changed, 215 insertions, 5 deletions
| diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 55f48e3e367f..f1f03c31f718 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -120,6 +120,7 @@ import android.util.proto.ProtoOutputStream;  import com.android.internal.accessibility.util.AccessibilityUtils;  import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting;  import com.android.internal.content.PackageMonitor;  import com.android.internal.display.RefreshRateSettingsUtils;  import com.android.internal.os.BackgroundThread; @@ -2914,6 +2915,14 @@ public class SettingsProvider extends ContentProvider {          };      } +    @VisibleForTesting +    void injectServices(UserManager userManager, IPackageManager packageManager, +            SystemConfigManager sysConfigManager) { +        mUserManager = userManager; +        mPackageManager = packageManager; +        mSysConfigManager = sysConfigManager; +    } +      private static final class Arguments {          private static final Pattern WHERE_PATTERN_WITH_PARAM_NO_BRACKETS =                  Pattern.compile("[\\s]*name[\\s]*=[\\s]*\\?[\\s]*"); @@ -3080,6 +3089,7 @@ public class SettingsProvider extends ContentProvider {          private static final String SSAID_USER_KEY = "userkey"; +        @GuardedBy("mLock")          private final SparseArray<SettingsState> mSettingsStates = new SparseArray<>();          private GenerationRegistry mGenerationRegistry; @@ -3992,6 +4002,14 @@ public class SettingsProvider extends ContentProvider {              }          } +        @VisibleForTesting +        void injectSettings(SettingsState settings, int type, int userId) { +            int key = makeKey(type, userId); +            synchronized (mLock) { +                mSettingsStates.put(key, settings); +            } +        } +          private final class MyHandler extends Handler {              private static final int MSG_NOTIFY_URI_CHANGED = 1;              private static final int MSG_NOTIFY_DATA_CHANGED = 2; @@ -4023,12 +4041,21 @@ public class SettingsProvider extends ContentProvider {              }          } -        private final class UpgradeController { +        @VisibleForTesting +        final class UpgradeController {              private static final int SETTINGS_VERSION = 226;              private final int mUserId; +            private final Injector mInjector; +              public UpgradeController(int userId) { +                this(/* injector= */ null, userId); +            } + +            @VisibleForTesting +            UpgradeController(Injector injector, int userId) { +                mInjector = injector == null ? new Injector() : injector;                  mUserId = userId;              } @@ -6136,8 +6163,8 @@ public class SettingsProvider extends ContentProvider {                              systemSettings.getSettingLocked(Settings.System.PEAK_REFRESH_RATE);                      final Setting minRefreshRateSetting =                              systemSettings.getSettingLocked(Settings.System.MIN_REFRESH_RATE); -                    float highestRefreshRate = RefreshRateSettingsUtils -                            .findHighestRefreshRateForDefaultDisplay(getContext()); +                    float highestRefreshRate = +                            mInjector.findHighestRefreshRateForDefaultDisplay(getContext());                      if (!peakRefreshRateSetting.isNull()) {                          try { @@ -6318,6 +6345,14 @@ public class SettingsProvider extends ContentProvider {              private long getBitMask(int capability) {                  return 1 << (capability - 1);              } + +            @VisibleForTesting +            static class Injector { +                float findHighestRefreshRateForDefaultDisplay(Context context) { +                    return RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay( +                            context); +                } +            }          }          /** diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index 5cd534e62ea9..bf3afeda448e 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -107,7 +107,7 @@ import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon;   * the same lock to grab the current state to write to disk.   * </p>   */ -final class SettingsState { +public class SettingsState {      private static final boolean DEBUG = false;      private static final boolean DEBUG_PERSISTENCE = false; @@ -1838,7 +1838,7 @@ final class SettingsState {          }      } -    class Setting { +    public class Setting {          private String name;          private String value;          private String defaultValue; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/UpgradeControllerTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/UpgradeControllerTest.java new file mode 100644 index 000000000000..26ff376f828e --- /dev/null +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/UpgradeControllerTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2024 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.providers.settings; + +import static android.provider.Settings.System.MIN_REFRESH_RATE; +import static android.provider.Settings.System.PEAK_REFRESH_RATE; + +import static com.android.providers.settings.SettingsProvider.SETTINGS_TYPE_GLOBAL; +import static com.android.providers.settings.SettingsProvider.SETTINGS_TYPE_SECURE; +import static com.android.providers.settings.SettingsProvider.SETTINGS_TYPE_SYSTEM; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.pm.IPackageManager; +import android.os.Looper; +import android.os.SystemConfigManager; +import android.os.UserHandle; +import android.os.UserManager; + +import androidx.test.core.app.ApplicationProvider; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class UpgradeControllerTest { +    private static final int USER_ID = UserHandle.USER_SYSTEM; +    private static final float HIGHEST_REFRESH_RATE = 130f; + +    private final Context mContext = +            spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); +    private final SettingsProvider.SettingsRegistry.UpgradeController.Injector mInjector = +            new SettingsProvider.SettingsRegistry.UpgradeController.Injector() { +                @Override +                float findHighestRefreshRateForDefaultDisplay(Context context) { +                    return HIGHEST_REFRESH_RATE; +                } +            }; +    private final SettingsProvider mSettingsProvider = new SettingsProvider() { +        @Override +        public boolean onCreate() { +            return true; +        } +    }; +    private final SettingsProvider.SettingsRegistry mSettingsRegistry = +            mSettingsProvider.new SettingsRegistry(Looper.getMainLooper()); +    private final SettingsProvider.SettingsRegistry.UpgradeController mUpgradeController = +            mSettingsRegistry.new UpgradeController(mInjector, USER_ID); + +    @Mock +    private UserManager mUserManager; + +    @Mock +    private IPackageManager mPackageManager; + +    @Mock +    private SystemConfigManager mSysConfigManager; + +    @Mock +    private SettingsState mSystemSettings; + +    @Mock +    private SettingsState mSecureSettings; + +    @Mock +    private SettingsState mGlobalSettings; + +    @Mock +    private SettingsState.Setting mMockSetting; + +    @Mock +    private SettingsState.Setting mPeakRefreshRateSetting; + +    @Mock +    private SettingsState.Setting mMinRefreshRateSetting; + +    @Before +    public void setUp() { +        MockitoAnnotations.initMocks(this); +        mSettingsProvider.attachInfoForTesting(mContext, /* info= */ null); +        mSettingsProvider.injectServices(mUserManager, mPackageManager, mSysConfigManager); +        when(mSystemSettings.getSettingLocked(any())).thenReturn(mMockSetting); +        when(mSecureSettings.getSettingLocked(any())).thenReturn(mMockSetting); +        when(mGlobalSettings.getSettingLocked(any())).thenReturn(mMockSetting); +        when(mMockSetting.isNull()).thenReturn(true); +        when(mMockSetting.getValue()).thenReturn("0"); + +        when(mSystemSettings.getSettingLocked(PEAK_REFRESH_RATE)) +                .thenReturn(mPeakRefreshRateSetting); +        when(mSystemSettings.getSettingLocked(MIN_REFRESH_RATE)) +                .thenReturn(mMinRefreshRateSetting); + +        mSettingsRegistry.injectSettings(mSystemSettings, SETTINGS_TYPE_SYSTEM, USER_ID); +        mSettingsRegistry.injectSettings(mSecureSettings, SETTINGS_TYPE_SECURE, USER_ID); +        mSettingsRegistry.injectSettings(mGlobalSettings, SETTINGS_TYPE_GLOBAL, USER_ID); + +        // Lowest version so that all upgrades are run +        when(mSecureSettings.getVersionLocked()).thenReturn(118); +    } + +    @Test +    public void testUpgrade_refreshRateSettings_defaultValues() { +        when(mPeakRefreshRateSetting.isNull()).thenReturn(true); +        when(mMinRefreshRateSetting.isNull()).thenReturn(true); + +        mUpgradeController.upgradeIfNeededLocked(); + +        // Should remain unchanged +        verify(mSystemSettings, never()).insertSettingLocked(eq(PEAK_REFRESH_RATE), +                /* value= */ any(), /* tag= */ any(), /* makeDefault= */ anyBoolean(), +                /* packageName= */ any()); +        verify(mSystemSettings, never()).insertSettingLocked(eq(MIN_REFRESH_RATE), +                /* value= */ any(), /* tag= */ any(), /* makeDefault= */ anyBoolean(), +                /* packageName= */ any()); +    } + +    @Test +    public void testUpgrade_refreshRateSettings_enabled() { +        when(mPeakRefreshRateSetting.isNull()).thenReturn(false); +        when(mMinRefreshRateSetting.isNull()).thenReturn(false); +        when(mPeakRefreshRateSetting.getValue()).thenReturn(String.valueOf(HIGHEST_REFRESH_RATE)); +        when(mMinRefreshRateSetting.getValue()).thenReturn(String.valueOf(HIGHEST_REFRESH_RATE)); + +        mUpgradeController.upgradeIfNeededLocked(); + +        // Highest refresh rate gets converted to infinity +        verify(mSystemSettings).insertSettingLocked(eq(PEAK_REFRESH_RATE), +                eq(String.valueOf(Float.POSITIVE_INFINITY)), /* tag= */ any(), +                /* makeDefault= */ anyBoolean(), /* packageName= */ any()); +        verify(mSystemSettings).insertSettingLocked(eq(MIN_REFRESH_RATE), +                eq(String.valueOf(Float.POSITIVE_INFINITY)), /* tag= */ any(), +                /* makeDefault= */ anyBoolean(), /* packageName= */ any()); +    } + +    @Test +    public void testUpgrade_refreshRateSettings_disabled() { +        when(mPeakRefreshRateSetting.isNull()).thenReturn(false); +        when(mMinRefreshRateSetting.isNull()).thenReturn(false); +        when(mPeakRefreshRateSetting.getValue()).thenReturn("70f"); +        when(mMinRefreshRateSetting.getValue()).thenReturn("70f"); + +        mUpgradeController.upgradeIfNeededLocked(); + +        // Should remain unchanged +        verify(mSystemSettings, never()).insertSettingLocked(eq(PEAK_REFRESH_RATE), +                /* value= */ any(), /* tag= */ any(), /* makeDefault= */ anyBoolean(), +                /* packageName= */ any()); +        verify(mSystemSettings, never()).insertSettingLocked(eq(MIN_REFRESH_RATE), +                /* value= */ any(), /* tag= */ any(), /* makeDefault= */ anyBoolean(), +                /* packageName= */ any()); +    } +} |