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

Commit f8808293 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Merge "Add Smooth Display option to developer in Settings" into rvc-dev...

Merge "Merge "Add Smooth Display option to developer in Settings" into rvc-dev am: f9a02151 am: 156d912c" into rvc-d1-dev-plus-aosp am: efa8cb62 am: 2a33b85f

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/11544217

Change-Id: I5f66d25e41a8c484f65861109482b0c9e56b249c
parents 9252edeb 2a33b85f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2752,6 +2752,10 @@
    <string name="peak_refresh_rate_title">Smooth Display</string>
    <!-- Display settings screen, peak refresh rate settings summary [CHAR LIMIT=NONE] -->
    <string name="peak_refresh_rate_summary">Automatically raises the refresh rate from 60 to 90 Hz for some content. Increases battery usage.</string>
    <!-- Display developer settings: Force to the highest refresh rate [CHAR LIMIT=NONE] -->
    <string name="force_high_refresh_rate_toggle">Smooth Display</string>
    <!-- Display developer settings: Force to the highest refresh rate description [CHAR LIMIT=NONE]-->
    <string name="force_high_refresh_rate_desc">Highest refresh rate for improved touch responsiveness &amp; animation quality. Increases battery usage.</string>
    <!-- Display settings screen, setting option name to enable adaptive sleep [CHAR LIMIT=30] -->
    <string name="adaptive_sleep_title">Screen attention</string>
    <!-- Setting option summary when adaptive sleep is on [CHAR LIMIT=NONE] -->
+5 −0
Original line number Diff line number Diff line
@@ -256,6 +256,11 @@
            android:title="@string/overlay_settings_title"
            android:summary="@string/overlay_settings_summary" />

        <SwitchPreference
            android:key="pref_key_peak_refresh_rate"
            android:title="@string/force_high_refresh_rate_toggle"
            android:summary="@string/force_high_refresh_rate_desc" />

    </PreferenceCategory>

    <PreferenceCategory
+1 −0
Original line number Diff line number Diff line
@@ -459,6 +459,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
        controllers.add(new SelectDebugAppPreferenceController(context, fragment));
        controllers.add(new WaitForDebuggerPreferenceController(context));
        controllers.add(new EnableGpuDebugLayersPreferenceController(context));
        controllers.add(new ForcePeakRefreshRatePreferenceController(context));
        controllers.add(new EnableVerboseVendorLoggingPreferenceController(context));
        controllers.add(new VerifyAppsOverUsbPreferenceController(context));
        controllers.add(new ArtVerifierPreferenceController(context));
+132 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.development;

import android.content.Context;
import android.hardware.display.DisplayManager;
import android.provider.Settings;
import android.util.Log;
import android.view.Display;

import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;

import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;

public class ForcePeakRefreshRatePreferenceController extends DeveloperOptionsPreferenceController
        implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {

    @VisibleForTesting
    static float DEFAULT_REFRESH_RATE = 60f;

    @VisibleForTesting
    static float NO_CONFIG = 0f;

    @VisibleForTesting
    float mPeakRefreshRate;

    private static final String TAG = "ForcePeakRefreshRateCtr";
    private static final String PREFERENCE_KEY = "pref_key_peak_refresh_rate";

    public ForcePeakRefreshRatePreferenceController(Context context) {
        super(context);

        final DisplayManager dm = context.getSystemService(DisplayManager.class);
        final Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);

        if (display == null) {
            Log.w(TAG, "No valid default display device");
            mPeakRefreshRate = DEFAULT_REFRESH_RATE;
        } else {
            mPeakRefreshRate = findPeakRefreshRate(display.getSupportedModes());
        }

        Log.d(TAG, "DEFAULT_REFRESH_RATE : " + DEFAULT_REFRESH_RATE
            + " mPeakRefreshRate : " + mPeakRefreshRate);
    }

    @Override
    public String getPreferenceKey() {
        return PREFERENCE_KEY;
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = screen.findPreference(getPreferenceKey());
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        final boolean isEnabled = (Boolean) newValue;
        forcePeakRefreshRate(isEnabled);

        return true;
    }

    @Override
    public void updateState(Preference preference) {
        ((SwitchPreference) mPreference).setChecked(isForcePeakRefreshRateEnabled());
    }

    @Override
    public boolean isAvailable() {
        if (mContext.getResources().getBoolean(R.bool.config_show_smooth_display)) {
            return mPeakRefreshRate > DEFAULT_REFRESH_RATE;
        } else {
            return false;
        }
    }

    @Override
    protected void onDeveloperOptionsSwitchDisabled() {
        super.onDeveloperOptionsSwitchDisabled();
        Settings.System.putFloat(mContext.getContentResolver(),
            Settings.System.MIN_REFRESH_RATE, NO_CONFIG);

        ((SwitchPreference) mPreference).setChecked(false);
    }

    @VisibleForTesting
    void forcePeakRefreshRate(boolean enable) {
        final float peakRefreshRate = enable ? mPeakRefreshRate : NO_CONFIG;
        Settings.System.putFloat(mContext.getContentResolver(),
            Settings.System.MIN_REFRESH_RATE, peakRefreshRate);
    }

    boolean isForcePeakRefreshRateEnabled() {
        final float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
            Settings.System.MIN_REFRESH_RATE, NO_CONFIG);

        return peakRefreshRate >= mPeakRefreshRate;
    }

    private float findPeakRefreshRate(Display.Mode[] modes) {
        float peakRefreshRate = DEFAULT_REFRESH_RATE;
        for (Display.Mode mode : modes) {
            if (Math.round(mode.getRefreshRate()) > DEFAULT_REFRESH_RATE) {
                peakRefreshRate = mode.getRefreshRate();
            }
        }

        return peakRefreshRate;
    }
}
+133 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.development;

import static com.android.settings.development.ForcePeakRefreshRatePreferenceController.DEFAULT_REFRESH_RATE;
import static com.android.settings.development.ForcePeakRefreshRatePreferenceController.NO_CONFIG;
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.provider.Settings;

import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

import android.util.Log;

@RunWith(RobolectricTestRunner.class)
public class ForcePeakRefreshRatePreferenceControllerTest {

    @Mock
    private SwitchPreference mPreference;
    @Mock
    private PreferenceScreen mScreen;

    private Context mContext;
    private ForcePeakRefreshRatePreferenceController mController;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = RuntimeEnvironment.application;
        mController = new ForcePeakRefreshRatePreferenceController(mContext);
        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
        when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
        mController.displayPreference(mScreen);
    }

    @Test
    public void onPreferenceChange_preferenceChecked_shouldEnableForcePeak() {
        mController.mPeakRefreshRate = 88f;

        mController.onPreferenceChange(mPreference, true);

        assertThat(Settings.System.getFloat(mContext.getContentResolver(),
                Settings.System.MIN_REFRESH_RATE, NO_CONFIG)).isEqualTo(88f);
    }

    @Test
    public void onPreferenceChange_preferenceUnchecked_shouldDisableForcePeak() {
        mController.mPeakRefreshRate = 88f;

        mController.onPreferenceChange(mPreference, false);

        assertThat(Settings.System.getFloat(mContext.getContentResolver(),
                Settings.System.MIN_REFRESH_RATE, NO_CONFIG)).isEqualTo(NO_CONFIG);
    }

    @Test
    public void updateState_enableForcePeak_shouldCheckedToggle() {
        mController.mPeakRefreshRate = 88f;
        mController.forcePeakRefreshRate(true);

        mController.updateState(mPreference);

        verify(mPreference).setChecked(true);
    }

    @Test
    public void updateState_disableForcePeak_shouldUncheckedToggle() {
        mController.mPeakRefreshRate = 88f;
        mController.forcePeakRefreshRate(false);

        mController.updateState(mPreference);

        verify(mPreference).setChecked(false);
    }

    @Test
    @Config(qualifiers = "mcc999")
    public void isAvailable_withConfigNoShow_returnUnsupported() {
        assertThat(mController.isAvailable()).isFalse();
    }

    @Test
    public void isAvailable_refreshRateLargerThanDefault_returnTrue() {
        mController.mPeakRefreshRate = DEFAULT_REFRESH_RATE + 1;

        assertThat(mController.isAvailable()).isTrue();
    }

    @Test
    public void getAvailabilityStatus_refreshRateEqualToDefault_returnFalse() {
        mController.mPeakRefreshRate = DEFAULT_REFRESH_RATE;

        assertThat(mController.isAvailable()).isFalse();
    }

    @Test
    public void onDeveloperOptionsDisabled_shouldDisablePreference() {
        mController.onDeveloperOptionsSwitchDisabled();

        assertThat(Settings.System.getFloat(mContext.getContentResolver(),
                Settings.System.MIN_REFRESH_RATE, -1f)).isEqualTo(NO_CONFIG);
        assertThat(mPreference.isChecked()).isFalse();
        assertThat(mPreference.isEnabled()).isFalse();
    }
}