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

Commit 8f6ae979 authored by Santos Cordon's avatar Santos Cordon Committed by Android (Google) Code Review
Browse files

Merge "Add display configuration files."

parents f36a23b1 4505e5e6
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -247,6 +247,19 @@ public final class PowerManager {
     */
    public static final int BRIGHTNESS_DEFAULT = -1;

    /**
     * Brightness value for fully off in float.
     * TODO: rename this to BRIGHTNES_OFF and remove the integer-based constant.
     * @hide
     */
    public static final float BRIGHTNESS_OFF_FLOAT = -1.0f;

    /**
     * Invalid brightness value.
     * @hide
     */
    public static final float BRIGHTNESS_INVALID_FLOAT = Float.NaN;

    // Note: Be sure to update android.os.BatteryStats and PowerManager.h
    // if adding or modifying user activity event constants.

+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ java_library_static {
        ":storaged_aidl",
        ":vold_aidl",
        ":platform-compat-config",
        ":display-device-config",
        "java/com/android/server/EventLogTags.logtags",
        "java/com/android/server/am/EventLogTags.logtags",
        "java/com/android/server/wm/EventLogTags.logtags",
+9 −3
Original line number Diff line number Diff line
@@ -109,11 +109,17 @@ public abstract class BrightnessMappingStrategy {
        return levels;
    }

    private static float[] getFloatArray(TypedArray array) {
    /**
     * Extracts a float array from the specified {@link TypedArray}.
     *
     * @param array The array to convert.
     * @return the given array as a float array.
     */
    public static float[] getFloatArray(TypedArray array) {
        final int N = array.length();
        float[] vals = new float[N];
        for (int i = 0; i < N; i++) {
            vals[i] = array.getFloat(i, -1.0f);
            vals[i] = array.getFloat(i, PowerManager.BRIGHTNESS_OFF_FLOAT);
        }
        array.recycle();
        return vals;
@@ -335,7 +341,7 @@ public abstract class BrightnessMappingStrategy {
        }
    }

    protected float normalizeAbsoluteBrightness(int brightness) {
    protected static float normalizeAbsoluteBrightness(int brightness) {
        brightness = MathUtils.constrain(brightness,
                PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
        return (float) brightness / PowerManager.BRIGHTNESS_ON;
+137 −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.server.display;

import android.os.Environment;
import android.util.Slog;

import com.android.server.display.config.DisplayConfiguration;
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";

    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 List<Point> points = config.getScreenBrightnessMap().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;
    }
}
+70 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.os.Trace;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseArray;
import android.util.Spline;
import android.view.Display;
import android.view.DisplayAddress;
import android.view.DisplayCutout;
@@ -37,6 +38,7 @@ import android.view.DisplayEventReceiver;
import android.view.Surface;
import android.view.SurfaceControl;

import com.android.internal.os.BackgroundThread;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.lights.Light;
@@ -187,8 +189,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
        private boolean mGameContentTypeRequested;
        private boolean mSidekickActive;
        private SidekickInternal mSidekickInternal;

        private SurfaceControl.PhysicalDisplayInfo[] mDisplayInfos;
        private Spline mSystemBrightnessToNits;
        private Spline mNitsToHalBrightness;
        private boolean mHalBrightnessSupport;

        LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
                SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
@@ -210,6 +214,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
            mHdrCapabilities = SurfaceControl.getHdrCapabilities(displayToken);
            mAllmSupported = SurfaceControl.getAutoLowLatencyModeSupport(displayToken);
            mGameContentTypeSupported = SurfaceControl.getGameContentTypeSupport(displayToken);
            mHalBrightnessSupport = SurfaceControl.getDisplayBrightnessSupport(displayToken);

            // Defer configuration file loading
            BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage(
                    LocalDisplayDevice::loadDisplayConfigurationBrightnessMapping, this));
        }

        @Override
@@ -338,6 +347,41 @@ final class LocalDisplayAdapter extends DisplayAdapter {
            return true;
        }

        private void loadDisplayConfigurationBrightnessMapping() {
            Spline nitsToHal = null;
            Spline sysToNits = null;

            // Load the mapping from nits to HAL brightness range (display-device-config.xml)
            DisplayDeviceConfig config = DisplayDeviceConfig.create(mPhysicalDisplayId);
            if (config == null) {
                return;
            }
            final float[] halNits = config.getNits();
            final float[] halBrightness = config.getBrightness();
            if (halNits == null || halBrightness == null) {
                return;
            }
            nitsToHal = Spline.createSpline(halNits, halBrightness);

            // Load the mapping from system brightness range to nits (config.xml)
            final Resources res = getOverlayContext().getResources();
            final float[] sysNits = BrightnessMappingStrategy.getFloatArray(res.obtainTypedArray(
                            com.android.internal.R.array.config_screenBrightnessNits));
            final int[] sysBrightness = res.getIntArray(
                    com.android.internal.R.array.config_screenBrightnessBacklight);
            if (sysNits.length == 0 || sysBrightness.length != sysNits.length) {
                return;
            }
            final float[] sysBrightnessFloat = new float[sysBrightness.length];
            for (int i = 0; i < sysBrightness.length; i++) {
                sysBrightnessFloat[i] = sysBrightness[i];
            }
            sysToNits = Spline.createSpline(sysBrightnessFloat, sysNits);

            mNitsToHalBrightness = nitsToHal;
            mSystemBrightnessToNits = sysToNits;
        }

        private boolean updateColorModesLocked(int[] colorModes,
                int activeColorMode) {
            List<Integer> pendingColorModes = new ArrayList<>();
@@ -628,13 +672,37 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
                                + "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
                        try {
                            if (mHalBrightnessSupport) {
                                mBacklight.setBrightnessFloat(
                                        displayBrightnessToHalBrightness(brightness));
                            } else {
                                mBacklight.setBrightness(brightness);
                            }
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "ScreenBrightness", brightness);
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                    }

                    /**
                     * Converts brightness range from the framework's brightness space to the
                     * Hal brightness space if the HAL brightness space has been provided via
                     * a display device configuration file.
                     */
                    private float displayBrightnessToHalBrightness(int brightness) {
                        if (mSystemBrightnessToNits == null || mNitsToHalBrightness == null) {
                            return PowerManager.BRIGHTNESS_INVALID_FLOAT;
                        }

                        if (brightness == 0) {
                            return PowerManager.BRIGHTNESS_OFF_FLOAT;
                        }

                        final float nits = mSystemBrightnessToNits.interpolate(brightness);
                        final float halBrightness = mNitsToHalBrightness.interpolate(nits);
                        return halBrightness;
                    }
                };
            }
            return null;
Loading