summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Cai <peter@typeblog.net>2019-09-07 03:01:39 (GMT)
committerƁukasz Patron <priv.luk@gmail.com>2019-09-21 12:31:01 (GMT)
commite0a5469cf5a2345fae7e81d16d717d285acd3a6e (patch)
tree4addb67bf0ba37cbda76f3ed94731cac3ce206d8
parent7b13c0f580554853304363f4cd93ee50a192dade (diff)
downloadframeworks_base-e0a5469cf5a2345fae7e81d16d717d285acd3a6e.zip
frameworks_base-e0a5469cf5a2345fae7e81d16d717d285acd3a6e.tar.gz
frameworks_base-e0a5469cf5a2345fae7e81d16d717d285acd3a6e.tar.bz2
FODCircleView: defer removal to next re-layout
* Originally, when hide() is called, it removes the dim layer and then removes the view immediately, then calls the hide event in HAL. This causes severe flickering because the HAL is expected to restore the brightness immediately, but the dim layer will not be removed until the next repaint cycle. * Since it is not easy to listen for a redraw after the view itself has been removed, we can defer removal after the next time onLayout() is called. When tested on my OnePlus 7 Pro, this reduces flickering on successful fp authentication drastically. * There are some cases where show() is called so quickly after hide() that the view hasn't been actually removed due to this change (which is actually another cause of flickering). This is handled by checking the removal flag in show() and removing it immediately if the view is yet to be removed, and also by moving calls to HAL show / hide events to the actual attached / detached event handlers. * For consistency in semantics, also move calls related to the dim layer that were originally in onDraw for similar reasons to the onLayout function. Change-Id: I9b0cfe5c4d572a64b918ce7d3c130a659fd25a30
-rw-r--r--packages/SystemUI/src/com/android/systemui/fingerprint/FODCircleView.java79
1 files changed, 56 insertions, 23 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FODCircleView.java b/packages/SystemUI/src/com/android/systemui/fingerprint/FODCircleView.java
index e8fcc70..356039b 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FODCircleView.java
+++ b/packages/SystemUI/src/com/android/systemui/fingerprint/FODCircleView.java
@@ -75,6 +75,7 @@ public class FODCircleView extends ImageView implements OnTouchListener {
private boolean mIsPulsing;
private boolean mIsScreenOn;
private boolean mIsViewAdded;
+ private boolean mIsRemoving;
private Handler mHandler;
@@ -244,6 +245,20 @@ public class FODCircleView extends ImageView implements OnTouchListener {
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
+
+ if (mIsInsideCircle) {
+ canvas.drawCircle(mWidth / 2, mHeight / 2, (float) (mWidth / 2.0f), mPaintFingerprint);
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ // onLayout is a good time to call the HAL because dim layer
+ // added by setDim() should have come into effect
+ // the HAL is expected (if supported) to set the screen brightness
+ // to maximum / minimum immediately when called
if (mIsInsideCircle) {
if (mIsDreaming) {
setAlpha(1.0f);
@@ -259,7 +274,6 @@ public class FODCircleView extends ImageView implements OnTouchListener {
}
mIsPressed = true;
}
- canvas.drawCircle(mWidth / 2, mHeight / 2, (float) (mWidth / 2.0f), mPaintFingerprint);
} else {
setAlpha(mIsDreaming ? 0.5f : 1.0f);
if (mIsPressed) {
@@ -273,6 +287,11 @@ public class FODCircleView extends ImageView implements OnTouchListener {
}
mIsPressed = false;
}
+
+ if (mIsRemoving) {
+ mIsRemoving = false;
+ mWindowManager.removeView(this);
+ }
}
}
@@ -318,6 +337,33 @@ public class FODCircleView extends ImageView implements OnTouchListener {
}
}
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ if (daemon != null) {
+ try {
+ daemon.onHideFODView();
+ } catch (RemoteException e) {
+ // do nothing
+ }
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ if (daemon != null) {
+ try {
+ daemon.onShowFODView();
+ } catch (RemoteException e) {
+ // do nothing
+ }
+ }
+ }
public synchronized IFingerprintInscreen getFingerprintInScreenDaemon() {
if (mFingerprintInscreenDaemon == null) {
@@ -337,6 +383,12 @@ public class FODCircleView extends ImageView implements OnTouchListener {
}
public void show() {
+ if (mIsRemoving) {
+ // Last removal hasn't been finished yet
+ mIsRemoving = false;
+ mWindowManager.removeView(this);
+ }
+
if (mIsViewAdded) {
return;
}
@@ -367,15 +419,6 @@ public class FODCircleView extends ImageView implements OnTouchListener {
mIsPressed = false;
setDim(false);
-
- IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
- if (daemon != null) {
- try {
- daemon.onShowFODView();
- } catch (RemoteException e) {
- // do nothing
- }
- }
}
public void hide() {
@@ -384,21 +427,11 @@ public class FODCircleView extends ImageView implements OnTouchListener {
}
mIsInsideCircle = false;
-
- mWindowManager.removeView(this);
mIsViewAdded = false;
-
- mIsPressed = false;
+ // Postpone removal to next re-layout to avoid blinking
+ mIsRemoving = true;
setDim(false);
-
- IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
- if (daemon != null) {
- try {
- daemon.onHideFODView();
- } catch (RemoteException e) {
- // do nothing
- }
- }
+ invalidate();
}
private void resetPosition() {