diff options
| author | 2020-08-13 17:37:07 +0000 | |
|---|---|---|
| committer | 2020-08-13 17:37:07 +0000 | |
| commit | 6fbee883ebf06cf58a25a440d53e8ed9f9b6bef0 (patch) | |
| tree | f7480b34fed0c54e201da5f021d022c454ebe132 | |
| parent | 177492451c16dec09cdf7f122a60c6f995e3082b (diff) | |
| parent | 4b416fe4c93ae35734d28aacb02ed045162c50f9 (diff) | |
Merge changes I4a87c587,If43c21bd
* changes:
Implement brightness-aware scrim
Clean up UdfpsController intitialization logic
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; } |