1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.development;
18 
19 import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
20 import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateAmongAllDisplays;
21 import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay;
22 
23 import android.content.Context;
24 import android.provider.Settings;
25 import android.util.Log;
26 
27 import androidx.annotation.VisibleForTesting;
28 import androidx.preference.Preference;
29 import androidx.preference.PreferenceScreen;
30 import androidx.preference.TwoStatePreference;
31 
32 import com.android.server.display.feature.flags.Flags;
33 import com.android.settings.R;
34 import com.android.settings.core.PreferenceControllerMixin;
35 import com.android.settingslib.development.DeveloperOptionsPreferenceController;
36 
37 public class ForcePeakRefreshRatePreferenceController extends DeveloperOptionsPreferenceController
38         implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
39 
40     @VisibleForTesting
41     static float NO_CONFIG = 0f;
42 
43     @VisibleForTesting
44     float mPeakRefreshRate;
45 
46     private static final String TAG = "ForcePeakRefreshRateCtr";
47     private static final String PREFERENCE_KEY = "pref_key_peak_refresh_rate";
48 
ForcePeakRefreshRatePreferenceController(Context context)49     public ForcePeakRefreshRatePreferenceController(Context context) {
50         super(context);
51         mPeakRefreshRate = Flags.backUpSmoothDisplayAndForcePeakRefreshRate()
52                 ? findHighestRefreshRateAmongAllDisplays(context)
53                 : findHighestRefreshRateForDefaultDisplay(context);
54         Log.d(TAG, "DEFAULT_REFRESH_RATE : " + DEFAULT_REFRESH_RATE
55             + " mPeakRefreshRate : " + mPeakRefreshRate);
56     }
57 
58     @Override
getPreferenceKey()59     public String getPreferenceKey() {
60         return PREFERENCE_KEY;
61     }
62 
63     @Override
displayPreference(PreferenceScreen screen)64     public void displayPreference(PreferenceScreen screen) {
65         super.displayPreference(screen);
66         mPreference = screen.findPreference(getPreferenceKey());
67     }
68 
69     @Override
onPreferenceChange(Preference preference, Object newValue)70     public boolean onPreferenceChange(Preference preference, Object newValue) {
71         final boolean isEnabled = (Boolean) newValue;
72         forcePeakRefreshRate(isEnabled);
73 
74         return true;
75     }
76 
77     @Override
updateState(Preference preference)78     public void updateState(Preference preference) {
79         ((TwoStatePreference) mPreference).setChecked(isForcePeakRefreshRateEnabled());
80     }
81 
82     @Override
isAvailable()83     public boolean isAvailable() {
84         if (mContext.getResources().getBoolean(R.bool.config_show_smooth_display)) {
85             return mPeakRefreshRate > DEFAULT_REFRESH_RATE;
86         } else {
87             return false;
88         }
89     }
90 
91     @Override
onDeveloperOptionsSwitchDisabled()92     protected void onDeveloperOptionsSwitchDisabled() {
93         super.onDeveloperOptionsSwitchDisabled();
94         Settings.System.putFloat(mContext.getContentResolver(),
95             Settings.System.MIN_REFRESH_RATE, NO_CONFIG);
96 
97         ((TwoStatePreference) mPreference).setChecked(false);
98     }
99 
100     @VisibleForTesting
forcePeakRefreshRate(boolean enable)101     void forcePeakRefreshRate(boolean enable) {
102         final float valueIfEnabled = Flags.backUpSmoothDisplayAndForcePeakRefreshRate()
103                 ? Float.POSITIVE_INFINITY : mPeakRefreshRate;
104         final float peakRefreshRate = enable ? valueIfEnabled : NO_CONFIG;
105         Settings.System.putFloat(mContext.getContentResolver(),
106             Settings.System.MIN_REFRESH_RATE, peakRefreshRate);
107     }
108 
isForcePeakRefreshRateEnabled()109     boolean isForcePeakRefreshRateEnabled() {
110         final float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
111             Settings.System.MIN_REFRESH_RATE, NO_CONFIG);
112 
113         return Math.round(peakRefreshRate) == Math.round(mPeakRefreshRate)
114                 || Float.isInfinite(peakRefreshRate);
115     }
116 }
117