• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.config;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.res.Resources;
22 import android.text.TextUtils;
23 
24 import com.android.internal.annotations.VisibleForTesting;
25 import com.android.server.display.feature.DisplayManagerFlags;
26 
27 import java.util.Collections;
28 import java.util.List;
29 
30 /**
31  * Uniquely identifies a Sensor, with the combination of Type and Name.
32  */
33 public class SensorData {
34 
35     public static final String TEMPERATURE_TYPE_DISPLAY = "DISPLAY";
36     public static final String TEMPERATURE_TYPE_SKIN = "SKIN";
37     private static final SensorData UNSPECIFIED_SENSOR_DATA = new SensorData(
38             /* type= */null, /* name= */ null);
39 
40     @Nullable
41     public final String type;
42     @Nullable
43     public final String name;
44     public final float minRefreshRate;
45     public final float maxRefreshRate;
46     public final List<SupportedModeData> supportedModes;
47 
SensorData(@ullable String type, @Nullable String name)48     private SensorData(@Nullable String type, @Nullable String name) {
49         this(type, name, /* minRefreshRate= */ 0f, /* maxRefreshRate= */ Float.POSITIVE_INFINITY,
50                 /* supportedModes= */ List.of());
51     }
52 
53     @VisibleForTesting
SensorData(@ullable String type, @Nullable String name, float minRefreshRate, float maxRefreshRate, List<SupportedModeData> supportedModes)54     SensorData(@Nullable String type, @Nullable String name,
55             float minRefreshRate, float maxRefreshRate, List<SupportedModeData> supportedModes) {
56         this.type = type;
57         this.name = name;
58         this.minRefreshRate = minRefreshRate;
59         this.maxRefreshRate = maxRefreshRate;
60         this.supportedModes = Collections.unmodifiableList(supportedModes);
61     }
62 
63     /**
64      * @return True if the sensor matches both the specified name and type, or one if only one
65      * is specified (not-empty). Always returns false if both parameters are null or empty.
66      */
matches(@ullable String sensorName, @Nullable String sensorType)67     public boolean matches(@Nullable String sensorName, @Nullable String sensorType) {
68         final boolean isNameSpecified = !TextUtils.isEmpty(sensorName);
69         final boolean isTypeSpecified = !TextUtils.isEmpty(sensorType);
70         return (isNameSpecified || isTypeSpecified)
71                 && (!isNameSpecified || sensorName.equals(name))
72                 && (!isTypeSpecified || sensorType.equals(type));
73     }
74 
75     @Override
toString()76     public String toString() {
77         return "SensorData{"
78                 + "type= " + type
79                 + ", name= " + name
80                 + ", refreshRateRange: [" + minRefreshRate + ", " + maxRefreshRate + "]"
81                 + ", supportedModes=" + supportedModes
82                 + '}';
83     }
84 
85     /**
86      * Loads ambient light sensor data from DisplayConfiguration and if missing from resources xml
87      */
loadAmbientLightSensorConfig(DisplayConfiguration config, Resources resources)88     public static SensorData loadAmbientLightSensorConfig(DisplayConfiguration config,
89             Resources resources) {
90         SensorDetails sensorDetails = config.getLightSensor();
91         if (sensorDetails != null) {
92             return loadSensorData(sensorDetails);
93         } else {
94             return loadAmbientLightSensorConfig(resources);
95         }
96     }
97 
98     /**
99      * Loads ambient light sensor data from resources xml
100      */
loadAmbientLightSensorConfig(Resources resources)101     public static SensorData loadAmbientLightSensorConfig(Resources resources) {
102         return new SensorData(
103                 resources.getString(com.android.internal.R.string.config_displayLightSensorType),
104                 /* name= */ "");
105     }
106 
107     /**
108      * Loads screen off brightness sensor data from DisplayConfiguration
109      */
loadScreenOffBrightnessSensorConfig(DisplayConfiguration config)110     public static SensorData loadScreenOffBrightnessSensorConfig(DisplayConfiguration config) {
111         SensorDetails sensorDetails = config.getScreenOffBrightnessSensor();
112         if (sensorDetails != null) {
113             return loadSensorData(sensorDetails);
114         } else {
115             return UNSPECIFIED_SENSOR_DATA;
116         }
117     }
118 
119     /**
120      * Loads proximity sensor data from DisplayConfiguration
121      */
122     @Nullable
loadProxSensorConfig( DisplayManagerFlags flags, DisplayConfiguration config)123     public static SensorData loadProxSensorConfig(
124             DisplayManagerFlags flags, DisplayConfiguration config) {
125         List<SensorDetails> sensorDetailsList = config.getProxSensor();
126         if (sensorDetailsList.isEmpty()) {
127             return UNSPECIFIED_SENSOR_DATA;
128         }
129 
130         SensorData selectedSensor = UNSPECIFIED_SENSOR_DATA;
131         // Prioritize flagged sensors.
132         for (SensorDetails sensorDetails : sensorDetailsList) {
133             String flagStr = sensorDetails.getFeatureFlag();
134             if (flags.isUseFusionProxSensorEnabled() &&
135                 flags.getUseFusionProxSensorFlagName().equals(flagStr)) {
136                 selectedSensor = loadSensorData(sensorDetails);
137                 break;
138             }
139         }
140 
141         // Check for normal un-flagged sensor if a flagged one wasn't found.
142         if (UNSPECIFIED_SENSOR_DATA == selectedSensor) {
143             for (SensorDetails sensorDetails : sensorDetailsList) {
144                 if (sensorDetails.getFeatureFlag() != null) {
145                     continue;
146                 }
147                 selectedSensor = loadSensorData(sensorDetails);
148                 break;
149             }
150         }
151 
152         // Check if we shouldn't use a sensor at all.
153         if (UNSPECIFIED_SENSOR_DATA != selectedSensor) {
154             if ("".equals(selectedSensor.name) && "".equals(selectedSensor.type)) {
155                 // <proxSensor> with empty values to the config means no sensor should be used.
156                 // See also {@link com.android.server.display.utils.SensorUtils}
157                 selectedSensor = null;
158             }
159         }
160 
161         return selectedSensor;
162     }
163 
164     /**
165      * Loads temperature sensor data for no config case. (Type: SKIN, Name: null)
166      */
loadTempSensorUnspecifiedConfig()167     public static SensorData loadTempSensorUnspecifiedConfig() {
168         return new SensorData(TEMPERATURE_TYPE_SKIN,  /* name= */ null);
169     }
170 
171     /**
172      * Loads temperature sensor data from given display config.
173      * If empty or null config given default to (Type: SKIN, Name: null)
174      */
loadTempSensorConfig(DisplayManagerFlags flags, DisplayConfiguration config)175     public static SensorData loadTempSensorConfig(DisplayManagerFlags flags,
176             DisplayConfiguration config) {
177         SensorDetails sensorDetails = config.getTempSensor();
178         if (!flags.isSensorBasedBrightnessThrottlingEnabled() || sensorDetails == null) {
179             return loadTempSensorUnspecifiedConfig();
180         }
181         String name = sensorDetails.getName();
182         String type = sensorDetails.getType();
183         if (TextUtils.isEmpty(type) || TextUtils.isEmpty(name)) {
184             type = TEMPERATURE_TYPE_SKIN;
185             name = null;
186         }
187         return new SensorData(type, name);
188     }
189 
190     /**
191      * Loads sensor unspecified config, this means system should use default sensor.
192      * See also {@link com.android.server.display.utils.SensorUtils}
193      */
194     @NonNull
loadSensorUnspecifiedConfig()195     public static SensorData loadSensorUnspecifiedConfig() {
196         return UNSPECIFIED_SENSOR_DATA;
197     }
198 
loadSensorData(@onNull SensorDetails sensorDetails)199     private static SensorData loadSensorData(@NonNull SensorDetails sensorDetails) {
200         float minRefreshRate = 0f;
201         float maxRefreshRate = Float.POSITIVE_INFINITY;
202         RefreshRateRange rr = sensorDetails.getRefreshRate();
203         if (rr != null) {
204             minRefreshRate = rr.getMinimum().floatValue();
205             maxRefreshRate = rr.getMaximum().floatValue();
206         }
207         List<SupportedModeData> supportedModes = SupportedModeData.load(
208                 sensorDetails.getSupportedModes());
209 
210         return new SensorData(sensorDetails.getType(), sensorDetails.getName(), minRefreshRate,
211                 maxRefreshRate, supportedModes);
212     }
213 
214 }
215