| /* |
| * 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.server.display; |
| |
| import android.os.Environment; |
| import android.util.Slog; |
| |
| import com.android.server.display.config.DisplayConfiguration; |
| import com.android.server.display.config.NitsMap; |
| import com.android.server.display.config.Point; |
| import com.android.server.display.config.XmlParser; |
| |
| import org.xmlpull.v1.XmlPullParserException; |
| |
| import java.io.BufferedInputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.List; |
| |
| import javax.xml.datatype.DatatypeConfigurationException; |
| |
| /** |
| * Reads and stores display-specific configurations. |
| */ |
| public class DisplayDeviceConfig { |
| private static final String TAG = "DisplayDeviceConfig"; |
| |
| public static final float HIGH_BRIGHTNESS_MODE_UNSUPPORTED = Float.NaN; |
| |
| private static final String ETC_DIR = "etc"; |
| private static final String DISPLAY_CONFIG_DIR = "displayconfig"; |
| private static final String CONFIG_FILE_FORMAT = "display_%d.xml"; |
| |
| private float[] mNits; |
| private float[] mBrightness; |
| |
| private DisplayDeviceConfig() { |
| } |
| |
| /** |
| * Creates an instance for the specified display. |
| * |
| * @param physicalDisplayId The display ID for which to load the configuration. |
| * @return A configuration instance for the specified display. |
| */ |
| public static DisplayDeviceConfig create(long physicalDisplayId) { |
| final DisplayDeviceConfig config = new DisplayDeviceConfig(); |
| final String filename = String.format(CONFIG_FILE_FORMAT, physicalDisplayId); |
| |
| config.initFromFile(Environment.buildPath( |
| Environment.getProductDirectory(), ETC_DIR, DISPLAY_CONFIG_DIR, filename)); |
| return config; |
| } |
| |
| /** |
| * Return the brightness mapping nits array if one is defined in the configuration file. |
| * |
| * @return The brightness mapping nits array. |
| */ |
| public float[] getNits() { |
| return mNits; |
| } |
| |
| /** |
| * Return the brightness mapping value array if one is defined in the configuration file. |
| * |
| * @return The brightness mapping value array. |
| */ |
| public float[] getBrightness() { |
| return mBrightness; |
| } |
| |
| private void initFromFile(File configFile) { |
| if (!configFile.exists()) { |
| // Display configuration files aren't required to exist. |
| return; |
| } |
| |
| if (!configFile.isFile()) { |
| Slog.e(TAG, "Display configuration is not a file: " + configFile + ", skipping"); |
| return; |
| } |
| |
| try (InputStream in = new BufferedInputStream(new FileInputStream(configFile))) { |
| final DisplayConfiguration config = XmlParser.read(in); |
| loadBrightnessMap(config); |
| } catch (IOException | DatatypeConfigurationException | XmlPullParserException e) { |
| Slog.e(TAG, "Encountered an error while reading/parsing display config file: " |
| + configFile, e); |
| } |
| } |
| |
| private void loadBrightnessMap(DisplayConfiguration config) { |
| final NitsMap map = config.getScreenBrightnessMap(); |
| final List<Point> points = map.getPoint(); |
| final int size = points.size(); |
| |
| float[] nits = new float[size]; |
| float[] backlight = new float[size]; |
| |
| int i = 0; |
| for (Point point : points) { |
| nits[i] = point.getNits().floatValue(); |
| backlight[i] = point.getValue().floatValue(); |
| if (i > 0) { |
| if (nits[i] < nits[i - 1]) { |
| Slog.e(TAG, "screenBrightnessMap must be non-decreasing, ignoring rest " |
| + " of configuration. Nits: " + nits[i] + " < " + nits[i - 1]); |
| return; |
| } |
| |
| if (backlight[i] < backlight[i - 1]) { |
| Slog.e(TAG, "screenBrightnessMap must be non-decreasing, ignoring rest " |
| + " of configuration. Value: " + backlight[i] + " < " |
| + backlight[i - 1]); |
| return; |
| } |
| } |
| ++i; |
| } |
| mNits = nits; |
| mBrightness = backlight; |
| } |
| } |