summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ilya Matyukhin <ilyamaty@google.com> 2020-08-13 17:37:07 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-08-13 17:37:07 +0000
commit6fbee883ebf06cf58a25a440d53e8ed9f9b6bef0 (patch)
treef7480b34fed0c54e201da5f021d022c454ebe132
parent177492451c16dec09cdf7f122a60c6f995e3082b (diff)
parent4b416fe4c93ae35734d28aacb02ed045162c50f9 (diff)
Merge changes I4a87c587,If43c21bd
* changes: Implement brightness-aware scrim Clean up UdfpsController intitialization logic
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java192
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java6
3 files changed, 155 insertions, 45 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 361ea674cead..ade106fb2223 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -280,7 +280,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
fpm.getSensorProperties();
for (FingerprintSensorProperties props : fingerprintSensorProperties) {
if (props.sensorType == FingerprintSensorProperties.TYPE_UDFPS) {
- mUdfpsController = new UdfpsController(mContext, mWindowManager);
+ mUdfpsController = new UdfpsController(mContext);
break;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 739c2b155444..e3126b89fe78 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -17,21 +17,27 @@
package com.android.systemui.biometrics;
import android.annotation.SuppressLint;
+import android.content.ContentResolver;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.IFingerprintService;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Handler;
import android.os.Looper;
-import android.os.RemoteException;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.Log;
+import android.util.MathUtils;
+import android.util.Spline;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.LinearLayout;
+import com.android.internal.BrightnessSynchronizer;
import com.android.systemui.R;
import java.io.FileWriter;
@@ -43,17 +49,31 @@ import java.io.IOException;
*/
class UdfpsController {
private static final String TAG = "UdfpsController";
+ // Gamma approximation for the sRGB color space.
+ private static final float DISPLAY_GAMMA = 2.2f;
- private final Context mContext;
private final FingerprintManager mFingerprintManager;
private final WindowManager mWindowManager;
+ private final ContentResolver mContentResolver;
private final Handler mHandler;
-
- private UdfpsView mView;
- private WindowManager.LayoutParams mLayoutParams;
- private String mHbmPath;
- private String mHbmEnableCommand;
- private String mHbmDisableCommand;
+ private final UdfpsView mView;
+ private final WindowManager.LayoutParams mLayoutParams;
+ // Debugfs path to control the high-brightness mode.
+ private final String mHbmPath;
+ private final String mHbmEnableCommand;
+ private final String mHbmDisableCommand;
+ // Brightness in nits in the high-brightness mode.
+ private final float mHbmNits;
+ // A spline mapping from the device's backlight value, normalized to the range [0, 1.0], to a
+ // brightness in nits.
+ private final Spline mBacklightToNitsSpline;
+ // A spline mapping from a value in nits to a backlight value of a hypothetical panel whose
+ // maximum backlight value corresponds to our panel's high-brightness mode.
+ // The output is normalized to the range [0, 1.0].
+ private Spline mNitsToHbmBacklightSpline;
+ // Default non-HBM backlight value normalized to the range [0, 1.0]. Used as a fallback when the
+ // actual brightness value cannot be retrieved.
+ private final float mDefaultBrightness;
private boolean mIsOverlayShowing;
public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
@@ -70,22 +90,23 @@ class UdfpsController {
@SuppressLint("ClickableViewAccessibility")
private final UdfpsView.OnTouchListener mOnTouchListener = (v, event) -> {
+ UdfpsView view = (UdfpsView) v;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
- boolean isValidTouch = mView.isValidTouch(event.getX(), event.getY(),
+ boolean isValidTouch = view.isValidTouch(event.getX(), event.getY(),
event.getPressure());
- if (!mView.isFingerDown() && isValidTouch) {
+ if (!view.isFingerDown() && isValidTouch) {
onFingerDown((int) event.getX(), (int) event.getY(), event.getTouchMinor(),
event.getTouchMajor());
- } else if (mView.isFingerDown() && !isValidTouch) {
+ } else if (view.isFingerDown() && !isValidTouch) {
onFingerUp();
}
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- if (mView.isFingerDown()) {
+ if (view.isFingerDown()) {
onFingerUp();
}
return true;
@@ -95,43 +116,51 @@ class UdfpsController {
}
};
- UdfpsController(Context context, WindowManager windowManager) {
- mContext = context;
+ UdfpsController(Context context) {
mFingerprintManager = context.getSystemService(FingerprintManager.class);
- mWindowManager = windowManager;
+ mWindowManager = context.getSystemService(WindowManager.class);
+ mContentResolver = context.getContentResolver();
mHandler = new Handler(Looper.getMainLooper());
- start();
- }
-
- private void start() {
- Log.v(TAG, "start");
-
- Point displaySize = new Point();
- mWindowManager.getDefaultDisplay().getRealSize(displaySize);
- // TODO(b/160025856): move to the "dump" method.
- Log.v(TAG, "UdfpsController | display size: " + displaySize.x + "x"
- + displaySize.y);
-
- mLayoutParams = new WindowManager.LayoutParams(
- displaySize.x,
- displaySize.y,
- // TODO(b/152419866): Use the UDFPS window type when it becomes available.
- WindowManager.LayoutParams.TYPE_BOOT_PROGRESS,
- WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
- PixelFormat.TRANSLUCENT);
- mLayoutParams.setTitle(TAG);
- mLayoutParams.windowAnimations = 0;
- LinearLayout layout = new LinearLayout(mContext);
+ mLayoutParams = createLayoutParams(context);
+ LinearLayout layout = new LinearLayout(context);
layout.setLayoutParams(mLayoutParams);
- mView = (UdfpsView) LayoutInflater.from(mContext).inflate(R.layout.udfps_view, layout,
+ mView = (UdfpsView) LayoutInflater.from(context).inflate(R.layout.udfps_view, layout,
false);
mView.setOnTouchListener(mOnTouchListener);
- mHbmPath = mContext.getResources().getString(R.string.udfps_hbm_sysfs_path);
- mHbmEnableCommand = mContext.getResources().getString(R.string.udfps_hbm_enable_command);
- mHbmDisableCommand = mContext.getResources().getString(R.string.udfps_hbm_disable_command);
+ mHbmPath = context.getResources().getString(R.string.udfps_hbm_sysfs_path);
+ mHbmEnableCommand = context.getResources().getString(R.string.udfps_hbm_enable_command);
+ mHbmDisableCommand = context.getResources().getString(R.string.udfps_hbm_disable_command);
+
+ // This range only consists of the minimum and maximum values, which only cover
+ // non-high-brightness mode.
+ float[] nitsRange = toFloatArray(context.getResources().obtainTypedArray(
+ com.android.internal.R.array.config_screenBrightnessNits));
+
+ // The last value of this range corresponds to the high-brightness mode.
+ float[] nitsAutoBrightnessValues = toFloatArray(context.getResources().obtainTypedArray(
+ com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
+
+ mHbmNits = nitsAutoBrightnessValues[nitsAutoBrightnessValues.length - 1];
+ float[] hbmNitsRange = {nitsRange[0], mHbmNits};
+
+ // This range only consists of the minimum and maximum backlight values, which only apply
+ // in non-high-brightness mode.
+ float[] normalizedBacklightRange = normalizeBacklightRange(
+ context.getResources().getIntArray(
+ com.android.internal.R.array.config_screenBrightnessBacklight));
+
+ mBacklightToNitsSpline = Spline.createSpline(normalizedBacklightRange, nitsRange);
+ mNitsToHbmBacklightSpline = Spline.createSpline(hbmNitsRange, normalizedBacklightRange);
+ mDefaultBrightness = obtainDefaultBrightness(context);
+
+ // TODO(b/160025856): move to the "dump" method.
+ Log.v(TAG, String.format("ctor | mNitsRange: [%f, %f]", nitsRange[0], nitsRange[1]));
+ Log.v(TAG, String.format("ctor | mHbmNitsRange: [%f, %f]", hbmNitsRange[0],
+ hbmNitsRange[1]));
+ Log.v(TAG, String.format("ctor | mNormalizedBacklightRange: [%f, %f]",
+ normalizedBacklightRange[0], normalizedBacklightRange[1]));
mFingerprintManager.setUdfpsOverlayController(new UdfpsOverlayController());
mIsOverlayShowing = false;
@@ -162,7 +191,34 @@ class UdfpsController {
});
}
+ // Returns a value in the range of [0, 255].
+ private int computeScrimOpacity() {
+ // Backlight setting can be NaN, -1.0f, and [0.0f, 1.0f].
+ float backlightSetting = Settings.System.getFloatForUser(mContentResolver,
+ Settings.System.SCREEN_BRIGHTNESS_FLOAT, mDefaultBrightness,
+ UserHandle.USER_CURRENT);
+
+ // Constrain the backlight setting to [0.0f, 1.0f].
+ float backlightValue = MathUtils.constrain(backlightSetting,
+ PowerManager.BRIGHTNESS_MIN,
+ PowerManager.BRIGHTNESS_MAX);
+
+ // Interpolate the backlight value to nits.
+ float nits = mBacklightToNitsSpline.interpolate(backlightValue);
+
+ // Interpolate nits to a backlight value for a panel with enabled HBM.
+ float interpolatedHbmBacklightValue = mNitsToHbmBacklightSpline.interpolate(nits);
+
+ float gammaCorrectedHbmBacklightValue = (float) Math.pow(interpolatedHbmBacklightValue,
+ 1.0f / DISPLAY_GAMMA);
+ float scrimOpacity = PowerManager.BRIGHTNESS_MAX - gammaCorrectedHbmBacklightValue;
+
+ // Interpolate the opacity value from [0.0f, 1.0f] to [0, 255].
+ return BrightnessSynchronizer.brightnessFloatToInt(scrimOpacity);
+ }
+
private void onFingerDown(int x, int y, float minor, float major) {
+ mView.setScrimAlpha(computeScrimOpacity());
try {
FileWriter fw = new FileWriter(mHbmPath);
fw.write(mHbmEnableCommand);
@@ -185,4 +241,54 @@ class UdfpsController {
Log.e(TAG, "onFingerUp | failed to disable HBM: " + e.getMessage());
}
}
+
+ private static WindowManager.LayoutParams createLayoutParams(Context context) {
+ Point displaySize = new Point();
+ context.getDisplay().getRealSize(displaySize);
+ // TODO(b/160025856): move to the "dump" method.
+ Log.v(TAG, "createLayoutParams | display size: " + displaySize.x + "x"
+ + displaySize.y);
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ displaySize.x,
+ displaySize.y,
+ // TODO(b/152419866): Use the UDFPS window type when it becomes available.
+ WindowManager.LayoutParams.TYPE_BOOT_PROGRESS,
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+ PixelFormat.TRANSLUCENT);
+ lp.setTitle(TAG);
+ lp.windowAnimations = 0;
+ return lp;
+ }
+
+ private static float obtainDefaultBrightness(Context context) {
+ PowerManager powerManager = context.getSystemService(PowerManager.class);
+ if (powerManager == null) {
+ Log.e(TAG, "PowerManager is unavailable. Can't obtain default brightness.");
+ return 0f;
+ }
+ return MathUtils.constrain(powerManager.getBrightnessConstraint(
+ PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT), PowerManager.BRIGHTNESS_MIN,
+ PowerManager.BRIGHTNESS_MAX);
+ }
+
+ private static float[] toFloatArray(TypedArray array) {
+ final int n = array.length();
+ float[] vals = new float[n];
+ for (int i = 0; i < n; i++) {
+ vals[i] = array.getFloat(i, PowerManager.BRIGHTNESS_OFF_FLOAT);
+ }
+ array.recycle();
+ return vals;
+ }
+
+ private static float[] normalizeBacklightRange(int[] backlight) {
+ final int n = backlight.length;
+ float[] normalizedBacklight = new float[n];
+ for (int i = 0; i < n; i++) {
+ normalizedBacklight[i] = BrightnessSynchronizer.brightnessIntToFloat(backlight[i]);
+ }
+ return normalizedBacklight;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index 8190550a74fc..d4e86d5dd234 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -79,7 +79,7 @@ public class UdfpsView extends View {
mScrimRect = new Rect();
mScrimPaint = new Paint(0 /* flags */);
- mScrimPaint.setARGB(110 /* a */, 0 /* r */, 0 /* g */, 0 /* b */);
+ mScrimPaint.setColor(Color.BLACK);
mSensorRect = new RectF();
mSensorPaint = new Paint(0 /* flags */);
@@ -136,6 +136,10 @@ public class UdfpsView extends View {
&& y < (mSensorY + mSensorRadius * mSensorTouchAreaCoefficient);
}
+ void setScrimAlpha(int alpha) {
+ mScrimPaint.setAlpha(alpha);
+ }
+
boolean isFingerDown() {
return mIsFingerDown;
}