Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62597caf authored by Piotr Wilczyński's avatar Piotr Wilczyński
Browse files

UpgradeControllerTest refresh rate settings

Make SettingsState public and non-final so that it can be mocked.

Bug: 280850428
Flag: TEST_ONLY
Test: atest SettingsProviderTest
Change-Id: Ieed415b0f5762adcfebc2ffc4effea3ef577b77a
parent 88bd95e4
Loading
Loading
Loading
Loading
+38 −3
Original line number Diff line number Diff line
@@ -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);
                }
            }
        }

        /**
+2 −2
Original line number Diff line number Diff line
@@ -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;
+175 −0
Original line number Diff line number Diff line
/*
 * 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());
    }
}