Merge "High Brightness Mode (HBM) Refresh Rate Limiting." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
410dd5be58
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package android.hardware.display;
|
package android.hardware.display;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
@@ -29,6 +30,9 @@ import android.view.DisplayInfo;
|
|||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.view.SurfaceControl.Transaction;
|
import android.view.SurfaceControl.Transaction;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,6 +41,16 @@ import java.util.Objects;
|
|||||||
* @hide Only for use within the system server.
|
* @hide Only for use within the system server.
|
||||||
*/
|
*/
|
||||||
public abstract class DisplayManagerInternal {
|
public abstract class DisplayManagerInternal {
|
||||||
|
|
||||||
|
@IntDef(prefix = {"REFRESH_RATE_LIMIT_"}, value = {
|
||||||
|
REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE
|
||||||
|
})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface RefreshRateLimitType {}
|
||||||
|
|
||||||
|
/** Refresh rate should be limited when High Brightness Mode is active. */
|
||||||
|
public static final int REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the power manager to initialize power management facilities.
|
* Called by the power manager to initialize power management facilities.
|
||||||
*/
|
*/
|
||||||
@@ -296,9 +310,10 @@ public abstract class DisplayManagerInternal {
|
|||||||
public abstract int getRefreshRateSwitchingType();
|
public abstract int getRefreshRateSwitchingType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO: b/191384041 - Replace this with getRefreshRateLimitations()
|
||||||
* Return the refresh rate restriction for the specified display and sensor pairing. If the
|
* Return the refresh rate restriction for the specified display and sensor pairing. If the
|
||||||
* specified sensor is identified as an associated sensor in the specified display's
|
* specified sensor is identified as an associated sensor in the specified display's
|
||||||
* display-device-config file, then return any refresh rate restrictions that it might specify.
|
* display-device-config file, then return any refresh rate restrictions that it might define.
|
||||||
* If no restriction is specified, or the sensor is not associated with the display, then null
|
* If no restriction is specified, or the sensor is not associated with the display, then null
|
||||||
* will be returned.
|
* will be returned.
|
||||||
*
|
*
|
||||||
@@ -312,6 +327,15 @@ public abstract class DisplayManagerInternal {
|
|||||||
public abstract RefreshRateRange getRefreshRateForDisplayAndSensor(
|
public abstract RefreshRateRange getRefreshRateForDisplayAndSensor(
|
||||||
int displayId, String name, String type);
|
int displayId, String name, String type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of various refresh rate limitations for the specified display.
|
||||||
|
*
|
||||||
|
* @param displayId The display to get limitations for.
|
||||||
|
*
|
||||||
|
* @return a list of {@link RefreshRateLimitation}s describing the various limits.
|
||||||
|
*/
|
||||||
|
public abstract List<RefreshRateLimitation> getRefreshRateLimitations(int displayId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the requested power state of the display.
|
* Describes the requested power state of the display.
|
||||||
*
|
*
|
||||||
@@ -613,4 +637,25 @@ public abstract class DisplayManagerInternal {
|
|||||||
return "(" + min + " " + max + ")";
|
return "(" + min + " " + max + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes a limitation on a display's refresh rate. Includes the allowed refresh rate
|
||||||
|
* range as well as information about when it applies, such as high-brightness-mode.
|
||||||
|
*/
|
||||||
|
public static final class RefreshRateLimitation {
|
||||||
|
@RefreshRateLimitType public int type;
|
||||||
|
|
||||||
|
/** The range the that refresh rate should be limited to. */
|
||||||
|
public RefreshRateRange range;
|
||||||
|
|
||||||
|
public RefreshRateLimitation(@RefreshRateLimitType int type, float min, float max) {
|
||||||
|
this.type = type;
|
||||||
|
range = new RefreshRateRange(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RefreshRateLimitation(" + type + ": " + range + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ package com.android.server.display;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.hardware.display.DisplayManagerInternal;
|
||||||
|
import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -86,6 +88,9 @@ public class DisplayDeviceConfig {
|
|||||||
// The details of the proximity sensor associated with this display.
|
// The details of the proximity sensor associated with this display.
|
||||||
private final SensorData mProximitySensor = new SensorData();
|
private final SensorData mProximitySensor = new SensorData();
|
||||||
|
|
||||||
|
private final List<RefreshRateLimitation> mRefreshRateLimitations =
|
||||||
|
new ArrayList<>(2 /*initialCapacity*/);
|
||||||
|
|
||||||
// Nits and backlight values that are loaded from either the display device config file, or
|
// Nits and backlight values that are loaded from either the display device config file, or
|
||||||
// config.xml. These are the raw values and just used for the dumpsys
|
// config.xml. These are the raw values and just used for the dumpsys
|
||||||
private float[] mRawNits;
|
private float[] mRawNits;
|
||||||
@@ -306,6 +311,10 @@ public class DisplayDeviceConfig {
|
|||||||
return hbmData;
|
return hbmData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<RefreshRateLimitation> getRefreshRateLimitations() {
|
||||||
|
return mRefreshRateLimitations;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String str = "DisplayDeviceConfig{"
|
String str = "DisplayDeviceConfig{"
|
||||||
@@ -329,6 +338,7 @@ public class DisplayDeviceConfig {
|
|||||||
+ ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
|
+ ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
|
||||||
+ ", mAmbientLightSensor=" + mAmbientLightSensor
|
+ ", mAmbientLightSensor=" + mAmbientLightSensor
|
||||||
+ ", mProximitySensor=" + mProximitySensor
|
+ ", mProximitySensor=" + mProximitySensor
|
||||||
|
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
|
||||||
+ "}";
|
+ "}";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -647,6 +657,13 @@ public class DisplayDeviceConfig {
|
|||||||
mHbmData.timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000;
|
mHbmData.timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000;
|
||||||
mHbmData.timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000;
|
mHbmData.timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000;
|
||||||
mHbmData.timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000;
|
mHbmData.timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000;
|
||||||
|
final RefreshRateRange rr = hbm.getRefreshRate_all();
|
||||||
|
if (rr != null) {
|
||||||
|
final float min = rr.getMinimum().floatValue();
|
||||||
|
final float max = rr.getMaximum().floatValue();
|
||||||
|
mRefreshRateLimitations.add(new RefreshRateLimitation(
|
||||||
|
DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE, min, max));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import android.hardware.display.DisplayManagerGlobal;
|
|||||||
import android.hardware.display.DisplayManagerInternal;
|
import android.hardware.display.DisplayManagerInternal;
|
||||||
import android.hardware.display.DisplayManagerInternal.DisplayGroupListener;
|
import android.hardware.display.DisplayManagerInternal.DisplayGroupListener;
|
||||||
import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
|
import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
|
||||||
|
import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
|
||||||
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
|
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
|
||||||
import android.hardware.display.DisplayViewport;
|
import android.hardware.display.DisplayViewport;
|
||||||
import android.hardware.display.DisplayedContentSample;
|
import android.hardware.display.DisplayedContentSample;
|
||||||
@@ -130,6 +131,7 @@ import java.io.FileDescriptor;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
@@ -2111,6 +2113,11 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED);
|
DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DisplayDevice getDeviceForDisplayLocked(int displayId) {
|
||||||
|
final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
|
||||||
|
return display == null ? null : display.getPrimaryDisplayDeviceLocked();
|
||||||
|
}
|
||||||
|
|
||||||
private final class DisplayManagerHandler extends Handler {
|
private final class DisplayManagerHandler extends Handler {
|
||||||
public DisplayManagerHandler(Looper looper) {
|
public DisplayManagerHandler(Looper looper) {
|
||||||
super(looper, null, true /*async*/);
|
super(looper, null, true /*async*/);
|
||||||
@@ -3295,6 +3302,19 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RefreshRateLimitation> getRefreshRateLimitations(int displayId) {
|
||||||
|
final DisplayDeviceConfig config;
|
||||||
|
synchronized (mSyncRoot) {
|
||||||
|
final DisplayDevice device = getDeviceForDisplayLocked(displayId);
|
||||||
|
if (device == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
config = device.getDisplayDeviceConfig();
|
||||||
|
}
|
||||||
|
return config.getRefreshRateLimitations();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DesiredDisplayModeSpecsObserver
|
class DesiredDisplayModeSpecsObserver
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.display;
|
package com.android.server.display;
|
||||||
|
|
||||||
|
import static android.hardware.display.DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
@@ -26,8 +28,10 @@ import android.hardware.Sensor;
|
|||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
|
import android.hardware.display.BrightnessInfo;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
import android.hardware.display.DisplayManagerInternal;
|
import android.hardware.display.DisplayManagerInternal;
|
||||||
|
import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
|
||||||
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
|
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
|
||||||
import android.hardware.fingerprint.IUdfpsHbmListener;
|
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -102,6 +106,7 @@ public class DisplayModeDirector {
|
|||||||
private final DisplayObserver mDisplayObserver;
|
private final DisplayObserver mDisplayObserver;
|
||||||
private final UdfpsObserver mUdfpsObserver;
|
private final UdfpsObserver mUdfpsObserver;
|
||||||
private final SensorObserver mSensorObserver;
|
private final SensorObserver mSensorObserver;
|
||||||
|
private final HbmObserver mHbmObserver;
|
||||||
private final DeviceConfigInterface mDeviceConfig;
|
private final DeviceConfigInterface mDeviceConfig;
|
||||||
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
|
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
|
||||||
|
|
||||||
@@ -127,7 +132,7 @@ public class DisplayModeDirector {
|
|||||||
private int mModeSwitchingType = DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS;
|
private int mModeSwitchingType = DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS;
|
||||||
|
|
||||||
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) {
|
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) {
|
||||||
this(context, handler, new RealInjector());
|
this(context, handler, new RealInjector(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler,
|
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler,
|
||||||
@@ -143,11 +148,13 @@ public class DisplayModeDirector {
|
|||||||
mDisplayObserver = new DisplayObserver(context, handler);
|
mDisplayObserver = new DisplayObserver(context, handler);
|
||||||
mBrightnessObserver = new BrightnessObserver(context, handler);
|
mBrightnessObserver = new BrightnessObserver(context, handler);
|
||||||
mUdfpsObserver = new UdfpsObserver();
|
mUdfpsObserver = new UdfpsObserver();
|
||||||
mSensorObserver = new SensorObserver(context, (displayId, priority, vote) -> {
|
final BallotBox ballotBox = (displayId, priority, vote) -> {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
updateVoteLocked(displayId, priority, vote);
|
updateVoteLocked(displayId, priority, vote);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
mSensorObserver = new SensorObserver(context, ballotBox);
|
||||||
|
mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler());
|
||||||
mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
|
mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
|
||||||
mDeviceConfig = injector.getDeviceConfig();
|
mDeviceConfig = injector.getDeviceConfig();
|
||||||
mAlwaysRespectAppRequest = false;
|
mAlwaysRespectAppRequest = false;
|
||||||
@@ -165,6 +172,7 @@ public class DisplayModeDirector {
|
|||||||
mDisplayObserver.observe();
|
mDisplayObserver.observe();
|
||||||
mBrightnessObserver.observe(sensorManager);
|
mBrightnessObserver.observe(sensorManager);
|
||||||
mSensorObserver.observe();
|
mSensorObserver.observe();
|
||||||
|
mHbmObserver.observe();
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// We may have a listener already registered before the call to start, so go ahead and
|
// We may have a listener already registered before the call to start, so go ahead and
|
||||||
// notify them to pick up our newly initialized state.
|
// notify them to pick up our newly initialized state.
|
||||||
@@ -596,6 +604,7 @@ public class DisplayModeDirector {
|
|||||||
mBrightnessObserver.dumpLocked(pw);
|
mBrightnessObserver.dumpLocked(pw);
|
||||||
mUdfpsObserver.dumpLocked(pw);
|
mUdfpsObserver.dumpLocked(pw);
|
||||||
mSensorObserver.dumpLocked(pw);
|
mSensorObserver.dumpLocked(pw);
|
||||||
|
mHbmObserver.dumpLocked(pw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,13 +947,16 @@ public class DisplayModeDirector {
|
|||||||
// user seeing the display flickering when the switches occur.
|
// user seeing the display flickering when the switches occur.
|
||||||
public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 8;
|
public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 8;
|
||||||
|
|
||||||
|
// High-brightness-mode may need a specific range of refresh-rates to function properly.
|
||||||
|
public static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 9;
|
||||||
|
|
||||||
// The proximity sensor needs the refresh rate to be locked in order to function, so this is
|
// The proximity sensor needs the refresh rate to be locked in order to function, so this is
|
||||||
// set to a high priority.
|
// set to a high priority.
|
||||||
public static final int PRIORITY_PROXIMITY = 9;
|
public static final int PRIORITY_PROXIMITY = 10;
|
||||||
|
|
||||||
// The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
|
// The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
|
||||||
// to function, so this needs to be the highest priority of all votes.
|
// to function, so this needs to be the highest priority of all votes.
|
||||||
public static final int PRIORITY_UDFPS = 10;
|
public static final int PRIORITY_UDFPS = 11;
|
||||||
|
|
||||||
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
|
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
|
||||||
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
|
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
|
||||||
@@ -1021,29 +1033,30 @@ public class DisplayModeDirector {
|
|||||||
|
|
||||||
public static String priorityToString(int priority) {
|
public static String priorityToString(int priority) {
|
||||||
switch (priority) {
|
switch (priority) {
|
||||||
|
case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE:
|
||||||
|
return "PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE";
|
||||||
|
case PRIORITY_APP_REQUEST_MAX_REFRESH_RATE:
|
||||||
|
return "PRIORITY_APP_REQUEST_MAX_REFRESH_RATE";
|
||||||
|
case PRIORITY_APP_REQUEST_SIZE:
|
||||||
|
return "PRIORITY_APP_REQUEST_SIZE";
|
||||||
case PRIORITY_DEFAULT_REFRESH_RATE:
|
case PRIORITY_DEFAULT_REFRESH_RATE:
|
||||||
return "PRIORITY_DEFAULT_REFRESH_RATE";
|
return "PRIORITY_DEFAULT_REFRESH_RATE";
|
||||||
case PRIORITY_FLICKER_REFRESH_RATE:
|
case PRIORITY_FLICKER_REFRESH_RATE:
|
||||||
return "PRIORITY_FLICKER_REFRESH_RATE";
|
return "PRIORITY_FLICKER_REFRESH_RATE";
|
||||||
case PRIORITY_FLICKER_REFRESH_RATE_SWITCH:
|
case PRIORITY_FLICKER_REFRESH_RATE_SWITCH:
|
||||||
return "PRIORITY_FLICKER_REFRESH_RATE_SWITCH";
|
return "PRIORITY_FLICKER_REFRESH_RATE_SWITCH";
|
||||||
case PRIORITY_USER_SETTING_MIN_REFRESH_RATE:
|
case PRIORITY_HIGH_BRIGHTNESS_MODE:
|
||||||
return "PRIORITY_USER_SETTING_MIN_REFRESH_RATE";
|
return "PRIORITY_HIGH_BRIGHTNESS_MODE";
|
||||||
case PRIORITY_APP_REQUEST_MAX_REFRESH_RATE:
|
case PRIORITY_PROXIMITY:
|
||||||
return "PRIORITY_APP_REQUEST_MAX_REFRESH_RATE";
|
return "PRIORITY_PROXIMITY";
|
||||||
case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE:
|
|
||||||
return "PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE";
|
|
||||||
case PRIORITY_APP_REQUEST_SIZE:
|
|
||||||
return "PRIORITY_APP_REQUEST_SIZE";
|
|
||||||
case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE:
|
|
||||||
return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
|
|
||||||
case PRIORITY_LOW_POWER_MODE:
|
case PRIORITY_LOW_POWER_MODE:
|
||||||
return "PRIORITY_LOW_POWER_MODE";
|
return "PRIORITY_LOW_POWER_MODE";
|
||||||
case PRIORITY_UDFPS:
|
case PRIORITY_UDFPS:
|
||||||
return "PRIORITY_UDFPS";
|
return "PRIORITY_UDFPS";
|
||||||
case PRIORITY_PROXIMITY:
|
case PRIORITY_USER_SETTING_MIN_REFRESH_RATE:
|
||||||
return "PRIORITY_PROXIMITY";
|
return "PRIORITY_USER_SETTING_MIN_REFRESH_RATE";
|
||||||
|
case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE:
|
||||||
|
return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
|
||||||
default:
|
default:
|
||||||
return Integer.toString(priority);
|
return Integer.toString(priority);
|
||||||
}
|
}
|
||||||
@@ -2155,6 +2168,75 @@ public class DisplayModeDirector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens to DisplayManager for HBM status and applies any refresh-rate restrictions for
|
||||||
|
* HBM that are associated with that display. Restrictions are retrieved from
|
||||||
|
* DisplayManagerInternal but originate in the display-device-config file.
|
||||||
|
*/
|
||||||
|
private static class HbmObserver implements DisplayManager.DisplayListener {
|
||||||
|
private final BallotBox mBallotBox;
|
||||||
|
private final Handler mHandler;
|
||||||
|
private final SparseBooleanArray mHbmEnabled = new SparseBooleanArray();
|
||||||
|
private final Injector mInjector;
|
||||||
|
|
||||||
|
private DisplayManagerInternal mDisplayManagerInternal;
|
||||||
|
|
||||||
|
HbmObserver(Injector injector, BallotBox ballotBox, Handler handler) {
|
||||||
|
mInjector = injector;
|
||||||
|
mBallotBox = ballotBox;
|
||||||
|
mHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void observe() {
|
||||||
|
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
|
||||||
|
mInjector.registerDisplayListener(this, mHandler,
|
||||||
|
DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
|
||||||
|
| DisplayManager.EVENT_FLAG_DISPLAY_REMOVED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisplayAdded(int displayId) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisplayRemoved(int displayId) {
|
||||||
|
mBallotBox.vote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisplayChanged(int displayId) {
|
||||||
|
final BrightnessInfo info = mInjector.getBrightnessInfo(displayId);
|
||||||
|
if (info == null) {
|
||||||
|
// Display no longer there. Assume we'll get an onDisplayRemoved very soon.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final boolean isHbmEnabled =
|
||||||
|
info.highBrightnessMode != BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
|
||||||
|
if (isHbmEnabled == mHbmEnabled.get(displayId)) {
|
||||||
|
// no change, ignore.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vote vote = null;
|
||||||
|
mHbmEnabled.put(displayId, isHbmEnabled);
|
||||||
|
if (isHbmEnabled) {
|
||||||
|
final List<RefreshRateLimitation> limits =
|
||||||
|
mDisplayManagerInternal.getRefreshRateLimitations(displayId);
|
||||||
|
for (int i = 0; limits != null && i < limits.size(); i++) {
|
||||||
|
final RefreshRateLimitation limitation = limits.get(i);
|
||||||
|
if (limitation.type == REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE) {
|
||||||
|
vote = Vote.forRefreshRates(limitation.range.min, limitation.range.max);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mBallotBox.vote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, vote);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpLocked(PrintWriter pw) {
|
||||||
|
pw.println(" HbmObserver");
|
||||||
|
pw.println(" mHbmEnabled: " + mHbmEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
|
private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
|
||||||
public DeviceConfigDisplaySettings() {
|
public DeviceConfigDisplaySettings() {
|
||||||
}
|
}
|
||||||
@@ -2309,10 +2391,21 @@ public class DisplayModeDirector {
|
|||||||
|
|
||||||
void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
|
void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
|
||||||
@NonNull ContentObserver observer);
|
@NonNull ContentObserver observer);
|
||||||
|
|
||||||
|
void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
|
||||||
|
Handler handler, long flags);
|
||||||
|
|
||||||
|
BrightnessInfo getBrightnessInfo(int displayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static class RealInjector implements Injector {
|
static class RealInjector implements Injector {
|
||||||
|
private final Context mContext;
|
||||||
|
private DisplayManager mDisplayManager;
|
||||||
|
|
||||||
|
RealInjector(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -2339,6 +2432,28 @@ public class DisplayModeDirector {
|
|||||||
cr.registerContentObserver(PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/,
|
cr.registerContentObserver(PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/,
|
||||||
observer, UserHandle.USER_SYSTEM);
|
observer, UserHandle.USER_SYSTEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerDisplayListener(DisplayManager.DisplayListener listener,
|
||||||
|
Handler handler, long flags) {
|
||||||
|
getDisplayManager().registerDisplayListener(listener, handler, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BrightnessInfo getBrightnessInfo(int displayId) {
|
||||||
|
final Display display = getDisplayManager().getDisplay(displayId);
|
||||||
|
if (display != null) {
|
||||||
|
return display.getBrightnessInfo();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DisplayManager getDisplayManager() {
|
||||||
|
if (mDisplayManager == null) {
|
||||||
|
mDisplayManager = mContext.getSystemService(DisplayManager.class);
|
||||||
|
}
|
||||||
|
return mDisplayManager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BallotBox {
|
interface BallotBox {
|
||||||
|
|||||||
@@ -77,6 +77,10 @@
|
|||||||
<xs:annotation name="final"/>
|
<xs:annotation name="final"/>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="timing" type="hbmTiming" minOccurs="1" maxOccurs="1"/>
|
<xs:element name="timing" type="hbmTiming" minOccurs="1" maxOccurs="1"/>
|
||||||
|
<xs:element type="refreshRateRange" name="refreshRate" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation name="nullable"/>
|
||||||
|
<xs:annotation name="final"/>
|
||||||
|
</xs:element>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
<xs:attribute name="enabled" type="xs:boolean" use="optional"/>
|
<xs:attribute name="enabled" type="xs:boolean" use="optional"/>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|||||||
@@ -44,10 +44,12 @@ package com.android.server.display.config {
|
|||||||
ctor public HighBrightnessMode();
|
ctor public HighBrightnessMode();
|
||||||
method public boolean getEnabled();
|
method public boolean getEnabled();
|
||||||
method @NonNull public final java.math.BigDecimal getMinimumLux_all();
|
method @NonNull public final java.math.BigDecimal getMinimumLux_all();
|
||||||
|
method @Nullable public final com.android.server.display.config.RefreshRateRange getRefreshRate_all();
|
||||||
method public com.android.server.display.config.HbmTiming getTiming_all();
|
method public com.android.server.display.config.HbmTiming getTiming_all();
|
||||||
method @NonNull public final java.math.BigDecimal getTransitionPoint_all();
|
method @NonNull public final java.math.BigDecimal getTransitionPoint_all();
|
||||||
method public void setEnabled(boolean);
|
method public void setEnabled(boolean);
|
||||||
method public final void setMinimumLux_all(@NonNull java.math.BigDecimal);
|
method public final void setMinimumLux_all(@NonNull java.math.BigDecimal);
|
||||||
|
method public final void setRefreshRate_all(@Nullable com.android.server.display.config.RefreshRateRange);
|
||||||
method public void setTiming_all(com.android.server.display.config.HbmTiming);
|
method public void setTiming_all(com.android.server.display.config.HbmTiming);
|
||||||
method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal);
|
method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,11 @@ import android.database.ContentObserver;
|
|||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
|
import android.hardware.display.BrightnessInfo;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
|
import android.hardware.display.DisplayManager.DisplayListener;
|
||||||
import android.hardware.display.DisplayManagerInternal;
|
import android.hardware.display.DisplayManagerInternal;
|
||||||
|
import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
|
||||||
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
|
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
|
||||||
import android.hardware.fingerprint.IUdfpsHbmListener;
|
import android.hardware.fingerprint.IUdfpsHbmListener;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -120,7 +123,7 @@ public class DisplayModeDirectorTest {
|
|||||||
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
|
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
|
||||||
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext);
|
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext);
|
||||||
when(mContext.getContentResolver()).thenReturn(resolver);
|
when(mContext.getContentResolver()).thenReturn(resolver);
|
||||||
mInjector = new FakesInjector();
|
mInjector = spy(new FakesInjector());
|
||||||
mHandler = new Handler(Looper.getMainLooper());
|
mHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
|
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
|
||||||
@@ -1256,13 +1259,163 @@ public class DisplayModeDirectorTest {
|
|||||||
assertNull(vote);
|
assertNull(vote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHbmVoting_forHdr() {
|
||||||
|
DisplayModeDirector director =
|
||||||
|
createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
|
||||||
|
director.start(createMockSensorManager());
|
||||||
|
|
||||||
|
ArgumentCaptor<DisplayListener> captor =
|
||||||
|
ArgumentCaptor.forClass(DisplayListener.class);
|
||||||
|
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
|
||||||
|
eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
|
||||||
|
| DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
|
||||||
|
DisplayListener listener = captor.getValue();
|
||||||
|
|
||||||
|
// Specify Limitation
|
||||||
|
when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID)).thenReturn(
|
||||||
|
List.of(new RefreshRateLimitation(
|
||||||
|
DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
|
||||||
|
60.f, 60.f)));
|
||||||
|
|
||||||
|
// Verify that there is no HBM vote initially
|
||||||
|
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
|
||||||
|
// Turn on HBM
|
||||||
|
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
|
||||||
|
new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR));
|
||||||
|
listener.onDisplayChanged(DISPLAY_ID);
|
||||||
|
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertVoteForRefreshRate(vote, 60.f);
|
||||||
|
|
||||||
|
// Turn off HBM
|
||||||
|
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
|
||||||
|
new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
|
||||||
|
listener.onDisplayChanged(DISPLAY_ID);
|
||||||
|
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHbmVoting_forSunlight() {
|
||||||
|
DisplayModeDirector director =
|
||||||
|
createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
|
||||||
|
director.start(createMockSensorManager());
|
||||||
|
|
||||||
|
ArgumentCaptor<DisplayListener> captor =
|
||||||
|
ArgumentCaptor.forClass(DisplayListener.class);
|
||||||
|
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
|
||||||
|
eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
|
||||||
|
| DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
|
||||||
|
DisplayListener listener = captor.getValue();
|
||||||
|
|
||||||
|
// Specify Limitation
|
||||||
|
when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID)).thenReturn(
|
||||||
|
List.of(new RefreshRateLimitation(
|
||||||
|
DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
|
||||||
|
60.f, 60.f)));
|
||||||
|
|
||||||
|
// Verify that there is no HBM vote initially
|
||||||
|
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
|
||||||
|
// Turn on HBM
|
||||||
|
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
|
||||||
|
new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
|
||||||
|
listener.onDisplayChanged(DISPLAY_ID);
|
||||||
|
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertVoteForRefreshRate(vote, 60.f);
|
||||||
|
|
||||||
|
// Turn off HBM
|
||||||
|
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
|
||||||
|
new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
|
||||||
|
listener.onDisplayChanged(DISPLAY_ID);
|
||||||
|
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHbmVoting_forSunlight_NoLimitation() {
|
||||||
|
DisplayModeDirector director =
|
||||||
|
createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
|
||||||
|
director.start(createMockSensorManager());
|
||||||
|
|
||||||
|
ArgumentCaptor<DisplayListener> captor =
|
||||||
|
ArgumentCaptor.forClass(DisplayListener.class);
|
||||||
|
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
|
||||||
|
eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
|
||||||
|
| DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
|
||||||
|
DisplayListener listener = captor.getValue();
|
||||||
|
|
||||||
|
// Specify Limitation for different display
|
||||||
|
when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID + 1)).thenReturn(
|
||||||
|
List.of(new RefreshRateLimitation(
|
||||||
|
DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
|
||||||
|
60.f, 60.f)));
|
||||||
|
|
||||||
|
// Verify that there is no HBM vote initially
|
||||||
|
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
|
||||||
|
// Turn on HBM
|
||||||
|
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
|
||||||
|
new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
|
||||||
|
listener.onDisplayChanged(DISPLAY_ID);
|
||||||
|
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
|
||||||
|
// Turn off HBM
|
||||||
|
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
|
||||||
|
new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
|
||||||
|
listener.onDisplayChanged(DISPLAY_ID);
|
||||||
|
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHbmVoting_RemovedDisplay() {
|
||||||
|
DisplayModeDirector director =
|
||||||
|
createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
|
||||||
|
director.start(createMockSensorManager());
|
||||||
|
|
||||||
|
ArgumentCaptor<DisplayListener> captor =
|
||||||
|
ArgumentCaptor.forClass(DisplayListener.class);
|
||||||
|
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
|
||||||
|
eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
|
||||||
|
| DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
|
||||||
|
DisplayListener listener = captor.getValue();
|
||||||
|
|
||||||
|
// Specify Limitation for different display
|
||||||
|
when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID)).thenReturn(
|
||||||
|
List.of(new RefreshRateLimitation(
|
||||||
|
DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
|
||||||
|
60.f, 60.f)));
|
||||||
|
|
||||||
|
// Verify that there is no HBM vote initially
|
||||||
|
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
|
||||||
|
// Turn on HBM
|
||||||
|
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
|
||||||
|
new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
|
||||||
|
listener.onDisplayChanged(DISPLAY_ID);
|
||||||
|
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertVoteForRefreshRate(vote, 60.f);
|
||||||
|
|
||||||
|
// Turn off HBM
|
||||||
|
listener.onDisplayRemoved(DISPLAY_ID);
|
||||||
|
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
|
||||||
|
assertNull(vote);
|
||||||
|
}
|
||||||
|
|
||||||
private void assertVoteForRefreshRate(Vote vote, float refreshRate) {
|
private void assertVoteForRefreshRate(Vote vote, float refreshRate) {
|
||||||
assertThat(vote).isNotNull();
|
assertThat(vote).isNotNull();
|
||||||
final RefreshRateRange expectedRange = new RefreshRateRange(refreshRate, refreshRate);
|
final RefreshRateRange expectedRange = new RefreshRateRange(refreshRate, refreshRate);
|
||||||
assertThat(vote.refreshRateRange).isEqualTo(expectedRange);
|
assertThat(vote.refreshRateRange).isEqualTo(expectedRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FakeDeviceConfig extends FakeDeviceConfigInterface {
|
public static class FakeDeviceConfig extends FakeDeviceConfigInterface {
|
||||||
@Override
|
@Override
|
||||||
public String getProperty(String namespace, String name) {
|
public String getProperty(String namespace, String name) {
|
||||||
Preconditions.checkArgument(DeviceConfig.NAMESPACE_DISPLAY_MANAGER.equals(namespace));
|
Preconditions.checkArgument(DeviceConfig.NAMESPACE_DISPLAY_MANAGER.equals(namespace));
|
||||||
@@ -1403,7 +1556,7 @@ public class DisplayModeDirectorTest {
|
|||||||
mHandler.runWithScissors(() -> { }, 500 /*timeout*/);
|
mHandler.runWithScissors(() -> { }, 500 /*timeout*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class FakesInjector implements DisplayModeDirector.Injector {
|
public static class FakesInjector implements DisplayModeDirector.Injector {
|
||||||
private final FakeDeviceConfig mDeviceConfig;
|
private final FakeDeviceConfig mDeviceConfig;
|
||||||
private ContentObserver mBrightnessObserver;
|
private ContentObserver mBrightnessObserver;
|
||||||
private ContentObserver mPeakRefreshRateObserver;
|
private ContentObserver mPeakRefreshRateObserver;
|
||||||
@@ -1444,6 +1597,14 @@ public class DisplayModeDirectorTest {
|
|||||||
mPeakRefreshRateObserver = observer;
|
mPeakRefreshRateObserver = observer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerDisplayListener(DisplayListener listener, Handler handler, long flag) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BrightnessInfo getBrightnessInfo(int displayId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
void notifyPeakRefreshRateChanged() {
|
void notifyPeakRefreshRateChanged() {
|
||||||
if (mPeakRefreshRateObserver != null) {
|
if (mPeakRefreshRateObserver != null) {
|
||||||
mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/,
|
mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/,
|
||||||
|
|||||||
Reference in New Issue
Block a user