1 /*
2  * Copyright (C) 2023 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.server.display.feature;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.hardware.display.DisplayManager;
22 import android.provider.DeviceConfig;
23 import android.provider.DeviceConfigInterface;
24 import android.util.Slog;
25 
26 import com.android.server.display.utils.DeviceConfigParsingUtils;
27 
28 import java.util.concurrent.Executor;
29 
30 /**
31  * Helper class to access all DeviceConfig features for display_manager namespace
32  *
33  **/
34 public class DeviceConfigParameterProvider {
35 
36     private static final String TAG = "DisplayFeatureProvider";
37 
38     private final DeviceConfigInterface mDeviceConfig;
39 
DeviceConfigParameterProvider(DeviceConfigInterface deviceConfig)40     public DeviceConfigParameterProvider(DeviceConfigInterface deviceConfig) {
41         mDeviceConfig = deviceConfig;
42     }
43 
44     // feature: hdr_output_control
45     // parameter: enable_hdr_output_control
isHdrOutputControlFeatureEnabled()46     public boolean isHdrOutputControlFeatureEnabled() {
47         return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
48                 DisplayManager.HDR_OUTPUT_CONTROL_FLAG, true);
49     }
50 
51     // feature: flexible_brightness_range_feature
52     // parameter: normal_brightness_mode_controller_enabled
isNormalBrightnessControllerFeatureEnabled()53     public boolean isNormalBrightnessControllerFeatureEnabled() {
54         return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
55                 DisplayManager.DeviceConfig.KEY_USE_NORMAL_BRIGHTNESS_MODE_CONTROLLER, false);
56     }
57 
isDisableScreenWakeLocksWhileCachedFeatureEnabled()58     public boolean isDisableScreenWakeLocksWhileCachedFeatureEnabled() {
59         return mDeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
60                 DisplayManager.DeviceConfig.KEY_DISABLE_SCREEN_WAKE_LOCKS_WHILE_CACHED, true);
61     }
62 
63     // feature: smooth_display_feature
64     // parameter: peak_refresh_rate_default
getPeakRefreshRateDefault()65     public float getPeakRefreshRateDefault() {
66         return mDeviceConfig.getFloat(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
67                 DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_DEFAULT, -1);
68     }
69 
70     // Test parameters
71     // usage e.g.: adb shell device_config put display_manager refresh_rate_in_hbm_sunlight 90
72 
73     // allows to customize power throttling data
getPowerThrottlingData()74     public String getPowerThrottlingData() {
75         return mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
76                 DisplayManager.DeviceConfig.KEY_POWER_THROTTLING_DATA, null);
77     }
78 
79     // allows to customize brightness throttling data
getBrightnessThrottlingData()80     public String getBrightnessThrottlingData() {
81         return mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
82                 DisplayManager.DeviceConfig.KEY_BRIGHTNESS_THROTTLING_DATA, null);
83     }
84 
getRefreshRateInHbmSunlight()85     public int getRefreshRateInHbmSunlight() {
86         return mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
87                 DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT, -1);
88     }
89 
getRefreshRateInHbmHdr()90     public int getRefreshRateInHbmHdr() {
91         return mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
92                 DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR, -1);
93     }
94 
95 
getRefreshRateInHighZone()96     public int getRefreshRateInHighZone() {
97         return mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
98                 DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE, -1);
99     }
100 
getRefreshRateInLowZone()101     public int getRefreshRateInLowZone() {
102         return mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
103                 DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE, -1);
104     }
105 
106     /**
107      * Get the high ambient brightness thresholds for the configured refresh rate zone. The values
108      * are paired with brightness thresholds.
109      *
110      * A negative value means that only the display brightness threshold should be used.
111      *
112      * Return null if no such property or wrong format (not comma separated integers).
113      */
114     @Nullable
getHighAmbientBrightnessThresholds()115     public float[] getHighAmbientBrightnessThresholds() {
116         return DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat(
117                 getIntArrayProperty(DisplayManager.DeviceConfig
118                         .KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS));
119     }
120 
121     /**
122      * Get the high display brightness thresholds for the configured refresh rate zone. The values
123      * are paired with lux thresholds.
124      *
125      * A negative value means that only the ambient threshold should be used.
126      *
127      * Return null if no such property or wrong format (not comma separated integers).
128      */
129     @Nullable
getHighDisplayBrightnessThresholds()130     public float[] getHighDisplayBrightnessThresholds() {
131         return DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat(
132                 getIntArrayProperty(DisplayManager.DeviceConfig
133                         .KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS));
134     }
135 
136     /**
137      * Get the low display brightness thresholds for the configured refresh rate zone. The values
138      * are paired with lux thresholds.
139      *
140      * A negative value means that only the ambient threshold should be used.
141      *
142      * Return null if no such property or wrong format (not comma separated integers).
143      */
144     @Nullable
getLowDisplayBrightnessThresholds()145     public float[] getLowDisplayBrightnessThresholds() {
146         return DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat(
147                 getIntArrayProperty(DisplayManager.DeviceConfig
148                         .KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS));
149     }
150 
151     /**
152      * Get the low ambient brightness thresholds for the configured refresh rate zone. The values
153      * are paired with brightness thresholds.
154      *
155      * A negative value means that only the display brightness threshold should be used.
156      *
157      * Return null if no such property or wrong format (not comma separated integers).
158      */
159     @Nullable
getLowAmbientBrightnessThresholds()160     public float[] getLowAmbientBrightnessThresholds() {
161         return DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat(
162                 getIntArrayProperty(DisplayManager.DeviceConfig
163                         .KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS));
164     }
165 
166     /** add property change listener to DeviceConfig */
addOnPropertiesChangedListener(Executor executor, DeviceConfig.OnPropertiesChangedListener listener)167     public void addOnPropertiesChangedListener(Executor executor,
168             DeviceConfig.OnPropertiesChangedListener listener) {
169         mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
170                 executor, listener);
171     }
172 
173     /** remove property change listener from DeviceConfig */
removeOnPropertiesChangedListener( DeviceConfig.OnPropertiesChangedListener listener)174     public void removeOnPropertiesChangedListener(
175             DeviceConfig.OnPropertiesChangedListener listener) {
176         mDeviceConfig.removeOnPropertiesChangedListener(listener);
177     }
178 
179     @Nullable
getIntArrayProperty(String prop)180     private int[] getIntArrayProperty(String prop) {
181         String strArray = mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, prop,
182                 null);
183 
184         if (strArray != null) {
185             return parseIntArray(strArray);
186         }
187         return null;
188     }
189 
190     @Nullable
parseIntArray(@onNull String strArray)191     private int[] parseIntArray(@NonNull String strArray) {
192         String[] items = strArray.split(",");
193         int[] array = new int[items.length];
194 
195         try {
196             for (int i = 0; i < array.length; i++) {
197                 array[i] = Integer.parseInt(items[i]);
198             }
199         } catch (NumberFormatException e) {
200             Slog.e(TAG, "Incorrect format for array: '" + strArray + "'", e);
201             array = null;
202         }
203 
204         return array;
205     }
206 }
207