Update face scanning anim, fix visibility bugs
- The face scanning view visibility should always be INVISIBLE if the face scanning anim isn't running - The face scanning view height should never take up the entire screen (there was an issue where the face sensor location was being requested before the display resolutiong/scale size was correct, so the face height location was reporting INFINITY instead of the actual location of the face camera sensor) - Face scanning anim needs to handle resolution changes Test: Settings > Display > Screen resolution Test: Check hierarchy viewer for size of the view when the face scanning animation is running, check different orientations Test: Check sysui dumpsys when face scanning animation is NOT showing (view should be visible on reboot) Test: atest ScreenDecorationsTest Bug: 185128224 Fixes: 236193243 Change-Id: I35cd1c607f590fd332bfeac37f220eb11aea320e
This commit is contained in:
@@ -52,15 +52,18 @@ class FaceScanningOverlay(
|
||||
private var cameraProtectionColor = Color.BLACK
|
||||
var faceScanningAnimColor = Utils.getColorAttrDefaultColor(context,
|
||||
com.android.systemui.R.attr.wallpaperTextColorAccent)
|
||||
private var cameraProtectionAnimator: ValueAnimator? = null
|
||||
var hideOverlayRunnable: Runnable? = null
|
||||
|
||||
init {
|
||||
visibility = View.INVISIBLE // only show this view when face scanning is happening
|
||||
}
|
||||
|
||||
override fun setColor(color: Int) {
|
||||
cameraProtectionColor = color
|
||||
invalidate()
|
||||
}
|
||||
|
||||
private var cameraProtectionAnimator: ValueAnimator? = null
|
||||
var hideOverlayRunnable: Runnable? = null
|
||||
|
||||
override fun drawCutoutProtection(canvas: Canvas) {
|
||||
if (rimProgress > HIDDEN_RIM_SCALE && !protectionRect.isEmpty) {
|
||||
val rimPath = Path(protectionPath)
|
||||
@@ -96,6 +99,10 @@ class FaceScanningOverlay(
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateVisOnUpdateCutout(): Boolean {
|
||||
return false // instead, we always update the visibility whenever face scanning starts/ends
|
||||
}
|
||||
|
||||
override fun enableShowProtection(show: Boolean) {
|
||||
val showScanningAnimNow = keyguardUpdateMonitor.isFaceScanning && show
|
||||
if (showScanningAnimNow == showScanningAnim) {
|
||||
|
||||
@@ -493,6 +493,13 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
cutoutView.onDisplayChanged(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayCutoutView overlay = (DisplayCutoutView) getOverlayView(mFaceScanningViewId);
|
||||
if (overlay != null) {
|
||||
// handle display resolution changes
|
||||
overlay.onDisplayChanged(displayId);
|
||||
}
|
||||
|
||||
if (mScreenDecorHwcLayer != null) {
|
||||
mScreenDecorHwcLayer.onDisplayChanged(displayId);
|
||||
}
|
||||
@@ -801,7 +808,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
});
|
||||
}
|
||||
// Use visibility of privacy dot views & face scanning view to determine the overlay's
|
||||
// visibility if the screen decoration SW layer overlay isn't persistenly showing
|
||||
// visibility if the screen decoration SW layer overlay isn't persistently showing
|
||||
// (ie: rounded corners always showing in SW layer)
|
||||
overlay.getRootView().setVisibility(getWindowVisibility(overlay, shouldOptimizeVisibility));
|
||||
}
|
||||
@@ -960,7 +967,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
viewsMayNeedColorUpdate.add(R.id.rounded_corner_bottom_right);
|
||||
viewsMayNeedColorUpdate.add(R.id.display_cutout);
|
||||
}
|
||||
if (mFaceScanningFactory.getHasProviders()) {
|
||||
if (getOverlayView(mFaceScanningViewId) != null) {
|
||||
viewsMayNeedColorUpdate.add(mFaceScanningViewId);
|
||||
}
|
||||
final Integer[] views = new Integer[viewsMayNeedColorUpdate.size()];
|
||||
@@ -1115,14 +1122,12 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
updateOverlayProviderViews();
|
||||
}
|
||||
|
||||
if (mFaceScanningFactory.getHasProviders()) {
|
||||
FaceScanningOverlay faceScanningOverlay =
|
||||
(FaceScanningOverlay) getOverlayView(mFaceScanningViewId);
|
||||
if (faceScanningOverlay != null) {
|
||||
faceScanningOverlay.setFaceScanningAnimColor(
|
||||
Utils.getColorAttrDefaultColor(faceScanningOverlay.getContext(),
|
||||
com.android.systemui.R.attr.wallpaperTextColorAccent));
|
||||
}
|
||||
FaceScanningOverlay faceScanningOverlay =
|
||||
(FaceScanningOverlay) getOverlayView(mFaceScanningViewId);
|
||||
if (faceScanningOverlay != null) {
|
||||
faceScanningOverlay.setFaceScanningAnimColor(
|
||||
Utils.getColorAttrDefaultColor(faceScanningOverlay.getContext(),
|
||||
com.android.systemui.R.attr.wallpaperTextColorAccent));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1342,11 +1347,15 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
} else {
|
||||
newVisible = GONE;
|
||||
}
|
||||
if (newVisible != getVisibility()) {
|
||||
if (updateVisOnUpdateCutout() && newVisible != getVisibility()) {
|
||||
setVisibility(newVisible);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean updateVisOnUpdateCutout() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateBoundingPath() {
|
||||
final Path path = displayInfo.displayCutout.getCutoutPath();
|
||||
if (path != null) {
|
||||
|
||||
@@ -492,6 +492,9 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
|
||||
final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio(
|
||||
mStableDisplaySize.x, mStableDisplaySize.y, displayInfo.getNaturalWidth(),
|
||||
displayInfo.getNaturalHeight());
|
||||
if (scaleFactor == Float.POSITIVE_INFINITY) {
|
||||
return new PointF(mFaceAuthSensorLocation.x, mFaceAuthSensorLocation.y);
|
||||
}
|
||||
return new PointF(mFaceAuthSensorLocation.x * scaleFactor,
|
||||
mFaceAuthSensorLocation.y * scaleFactor);
|
||||
}
|
||||
|
||||
@@ -51,15 +51,17 @@ class FaceScanningProviderFactory @Inject constructor(
|
||||
|
||||
override val hasProviders: Boolean
|
||||
get() {
|
||||
// update display info:
|
||||
if (!featureFlags.isEnabled(Flags.FACE_SCANNING_ANIM) ||
|
||||
authController.faceAuthSensorLocation == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
// update display info
|
||||
display?.getDisplayInfo(displayInfo) ?: run {
|
||||
Log.w(TAG, "display is null, can't update displayInfo")
|
||||
}
|
||||
val hasDisplayCutout = DisplayCutout.getFillBuiltInDisplayCutout(
|
||||
return DisplayCutout.getFillBuiltInDisplayCutout(
|
||||
context.resources, displayInfo.uniqueId)
|
||||
return hasDisplayCutout &&
|
||||
authController.faceAuthSensorLocation != null &&
|
||||
featureFlags.isEnabled(Flags.FACE_SCANNING_ANIM)
|
||||
}
|
||||
|
||||
override val providers: List<DecorProvider>
|
||||
@@ -110,7 +112,10 @@ class FaceScanningOverlayProviderImpl(
|
||||
rotation: Int,
|
||||
displayUniqueId: String?
|
||||
) {
|
||||
// no need to handle rotation changes
|
||||
(view.layoutParams as FrameLayout.LayoutParams).let {
|
||||
updateLayoutParams(it, rotation)
|
||||
view.layoutParams = it
|
||||
}
|
||||
}
|
||||
|
||||
override fun inflateView(
|
||||
@@ -124,17 +129,40 @@ class FaceScanningOverlayProviderImpl(
|
||||
statusBarStateController,
|
||||
keyguardUpdateMonitor)
|
||||
view.id = viewId
|
||||
view.visibility = View.INVISIBLE // only show this view when face scanning is happening
|
||||
var heightLayoutParam = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
authController.faceAuthSensorLocation?.y?.let {
|
||||
heightLayoutParam = (it * 3).toInt()
|
||||
FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT).let {
|
||||
updateLayoutParams(it, rotation)
|
||||
parent.addView(view, it)
|
||||
}
|
||||
parent.addView(view, FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
heightLayoutParam,
|
||||
Gravity.TOP or Gravity.START))
|
||||
return view
|
||||
}
|
||||
|
||||
private fun updateLayoutParams(
|
||||
layoutParams: FrameLayout.LayoutParams,
|
||||
@Surface.Rotation rotation: Int
|
||||
) {
|
||||
layoutParams.let { lp ->
|
||||
lp.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
lp.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
authController.faceAuthSensorLocation?.y?.let { faceAuthSensorHeight ->
|
||||
val faceScanningHeight = (faceAuthSensorHeight * 2).toInt()
|
||||
when (rotation) {
|
||||
Surface.ROTATION_0, Surface.ROTATION_180 ->
|
||||
lp.height = faceScanningHeight
|
||||
Surface.ROTATION_90, Surface.ROTATION_270 ->
|
||||
lp.width = faceScanningHeight
|
||||
}
|
||||
}
|
||||
|
||||
lp.gravity = when (rotation) {
|
||||
Surface.ROTATION_0 -> Gravity.TOP or Gravity.START
|
||||
Surface.ROTATION_90 -> Gravity.LEFT or Gravity.START
|
||||
Surface.ROTATION_180 -> Gravity.BOTTOM or Gravity.END
|
||||
Surface.ROTATION_270 -> Gravity.RIGHT or Gravity.END
|
||||
else -> -1 /* invalid rotation */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun DisplayCutout.getBoundBaseOnCurrentRotation(): List<Int> {
|
||||
|
||||
Reference in New Issue
Block a user