diff options
7 files changed, 227 insertions, 14 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt index 3e0fa455d39e..54939fdb78fb 100644 --- a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt +++ b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt @@ -35,6 +35,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.settingslib.Utils import com.android.systemui.animation.Interpolators +import com.android.systemui.log.ScreenDecorationsLogger import com.android.systemui.plugins.statusbar.StatusBarStateController import java.util.concurrent.Executor @@ -47,7 +48,8 @@ class FaceScanningOverlay( pos: Int, val statusBarStateController: StatusBarStateController, val keyguardUpdateMonitor: KeyguardUpdateMonitor, - val mainExecutor: Executor + val mainExecutor: Executor, + val logger: ScreenDecorationsLogger, ) : ScreenDecorations.DisplayCutoutView(context, pos) { private var showScanningAnim = false private val rimPaint = Paint() @@ -55,6 +57,7 @@ class FaceScanningOverlay( private var rimAnimator: AnimatorSet? = null private val rimRect = RectF() private var cameraProtectionColor = Color.BLACK + var faceScanningAnimColor = Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColorAccent) private var cameraProtectionAnimator: ValueAnimator? = null @@ -175,15 +178,22 @@ class FaceScanningOverlay( } if (showScanningAnim) { // Make sure that our measured height encompasses the extra space for the animation - mTotalBounds.union(mBoundingRect) + mTotalBounds.set(mBoundingRect) mTotalBounds.union( rimRect.left.toInt(), rimRect.top.toInt(), rimRect.right.toInt(), rimRect.bottom.toInt()) - setMeasuredDimension( - resolveSizeAndState(mTotalBounds.width(), widthMeasureSpec, 0), - resolveSizeAndState(mTotalBounds.height(), heightMeasureSpec, 0)) + val measuredWidth = resolveSizeAndState(mTotalBounds.width(), widthMeasureSpec, 0) + val measuredHeight = resolveSizeAndState(mTotalBounds.height(), heightMeasureSpec, 0) + logger.boundingRect(rimRect, "onMeasure: Face scanning animation") + logger.boundingRect(mBoundingRect, "onMeasure: Display cutout view bounding rect") + logger.boundingRect(mTotalBounds, "onMeasure: TotalBounds") + logger.onMeasureDimensions(widthMeasureSpec, + heightMeasureSpec, + measuredWidth, + measuredHeight) + setMeasuredDimension(measuredWidth, measuredHeight) } else { setMeasuredDimension( resolveSizeAndState(mBoundingRect.width(), widthMeasureSpec, 0), diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 71f98fa3613a..c1c7f2d892a6 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -64,6 +64,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.settingslib.Utils; +import com.android.systemui.biometrics.AuthController; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.decor.CutoutDecorProviderFactory; @@ -75,6 +76,7 @@ import com.android.systemui.decor.OverlayWindow; import com.android.systemui.decor.PrivacyDotDecorProviderFactory; import com.android.systemui.decor.RoundedCornerDecorProviderFactory; import com.android.systemui.decor.RoundedCornerResDelegate; +import com.android.systemui.log.ScreenDecorationsLogger; import com.android.systemui.qs.SettingObserver; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; @@ -120,6 +122,18 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { R.id.display_cutout_right, R.id.display_cutout_bottom }; + private final ScreenDecorationsLogger mLogger; + + private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() { + @Override + public void onFaceSensorLocationChanged() { + mLogger.onSensorLocationChanged(); + if (mExecutor != null) { + mExecutor.execute( + () -> updateOverlayProviderViews(new Integer[]{mFaceScanningViewId})); + } + } + }; private DisplayTracker mDisplayTracker; @VisibleForTesting @@ -153,6 +167,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { private WindowManager mWindowManager; private int mRotation; private SettingObserver mColorInversionSetting; + @Nullable private DelayableExecutor mExecutor; private Handler mHandler; boolean mPendingConfigChange; @@ -172,6 +187,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { DisplayCutoutView overlay = (DisplayCutoutView) getOverlayView( mFaceScanningViewId); if (overlay != null) { + mLogger.cameraProtectionBoundsForScanningOverlay(bounds); overlay.setProtection(protectionPath, bounds); overlay.enableShowProtection(true); updateOverlayWindowVisibilityIfViewExists( @@ -184,6 +200,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { } if (mScreenDecorHwcLayer != null) { + mLogger.hwcLayerCameraProtectionBounds(bounds); mScreenDecorHwcLayer.setProtection(protectionPath, bounds); mScreenDecorHwcLayer.enableShowProtection(true); return; @@ -197,11 +214,12 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { } ++setProtectionCnt; final DisplayCutoutView dcv = (DisplayCutoutView) view; + mLogger.dcvCameraBounds(id, bounds); dcv.setProtection(protectionPath, bounds); dcv.enableShowProtection(true); } if (setProtectionCnt == 0) { - Log.e(TAG, "CutoutView not initialized showCameraProtection"); + mLogger.cutoutViewNotInitialized(); } } @@ -307,7 +325,9 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { PrivacyDotViewController dotViewController, ThreadFactory threadFactory, PrivacyDotDecorProviderFactory dotFactory, - FaceScanningProviderFactory faceScanningFactory) { + FaceScanningProviderFactory faceScanningFactory, + ScreenDecorationsLogger logger, + AuthController authController) { mContext = context; mMainExecutor = mainExecutor; mSecureSettings = secureSettings; @@ -319,6 +339,8 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { mDotFactory = dotFactory; mFaceScanningFactory = faceScanningFactory; mFaceScanningViewId = com.android.systemui.R.id.face_scanning_anim; + mLogger = logger; + authController.addCallback(mAuthControllerCallback); } @Override @@ -1306,7 +1328,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable { if (showProtection) { // Make sure that our measured height encompasses the protection - mTotalBounds.union(mBoundingRect); + mTotalBounds.set(mBoundingRect); mTotalBounds.union((int) protectionRect.left, (int) protectionRect.top, (int) protectionRect.right, (int) protectionRect.bottom); setMeasuredDimension( diff --git a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt index 976afd457f79..88c0c50d09a5 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt @@ -34,6 +34,7 @@ import com.android.systemui.FaceScanningOverlay import com.android.systemui.biometrics.AuthController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.log.ScreenDecorationsLogger import com.android.systemui.plugins.statusbar.StatusBarStateController import java.util.concurrent.Executor import javax.inject.Inject @@ -45,6 +46,7 @@ class FaceScanningProviderFactory @Inject constructor( private val statusBarStateController: StatusBarStateController, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, @Main private val mainExecutor: Executor, + private val logger: ScreenDecorationsLogger, ) : DecorProviderFactory() { private val display = context.display private val displayInfo = DisplayInfo() @@ -82,7 +84,8 @@ class FaceScanningProviderFactory @Inject constructor( authController, statusBarStateController, keyguardUpdateMonitor, - mainExecutor + mainExecutor, + logger, ) ) } @@ -104,7 +107,8 @@ class FaceScanningOverlayProviderImpl( private val authController: AuthController, private val statusBarStateController: StatusBarStateController, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, - private val mainExecutor: Executor + private val mainExecutor: Executor, + private val logger: ScreenDecorationsLogger, ) : BoundDecorProvider() { override val viewId: Int = com.android.systemui.R.id.face_scanning_anim @@ -136,7 +140,8 @@ class FaceScanningOverlayProviderImpl( alignedBound, statusBarStateController, keyguardUpdateMonitor, - mainExecutor + mainExecutor, + logger, ) view.id = viewId view.setColor(tintColor) @@ -155,8 +160,9 @@ class FaceScanningOverlayProviderImpl( layoutParams.let { lp -> lp.width = ViewGroup.LayoutParams.MATCH_PARENT lp.height = ViewGroup.LayoutParams.MATCH_PARENT + logger.faceSensorLocation(authController.faceSensorLocation) authController.faceSensorLocation?.y?.let { faceAuthSensorHeight -> - val faceScanningHeight = (faceAuthSensorHeight * 2).toInt() + val faceScanningHeight = (faceAuthSensorHeight * 2) when (rotation) { Surface.ROTATION_0, Surface.ROTATION_180 -> lp.height = faceScanningHeight diff --git a/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt b/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt new file mode 100644 index 000000000000..5acaa46c25d6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log + +import android.graphics.Point +import android.graphics.Rect +import android.graphics.RectF +import androidx.core.graphics.toRectF +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.dagger.ScreenDecorationsLog +import com.android.systemui.plugins.log.LogBuffer +import com.android.systemui.plugins.log.LogLevel.DEBUG +import com.android.systemui.plugins.log.LogLevel.ERROR +import javax.inject.Inject + +private const val TAG = "ScreenDecorationsLog" + +/** + * Helper class for logging for [com.android.systemui.ScreenDecorations] + * + * To enable logcat echoing for an entire buffer: + * + * ``` + * adb shell settings put global systemui/buffer/ScreenDecorationsLog <logLevel> + * + * ``` + */ +@SysUISingleton +class ScreenDecorationsLogger +@Inject +constructor( + @ScreenDecorationsLog private val logBuffer: LogBuffer, +) { + fun cameraProtectionBoundsForScanningOverlay(bounds: Rect) { + logBuffer.log( + TAG, + DEBUG, + { str1 = bounds.toShortString() }, + { "Face scanning overlay present camera protection bounds: $str1" } + ) + } + + fun hwcLayerCameraProtectionBounds(bounds: Rect) { + logBuffer.log( + TAG, + DEBUG, + { str1 = bounds.toShortString() }, + { "Hwc layer present camera protection bounds: $str1" } + ) + } + + fun dcvCameraBounds(id: Int, bounds: Rect) { + logBuffer.log( + TAG, + DEBUG, + { + str1 = bounds.toShortString() + int1 = id + }, + { "DisplayCutoutView id=$int1 present, camera protection bounds: $str1" } + ) + } + + fun cutoutViewNotInitialized() { + logBuffer.log(TAG, ERROR, "CutoutView not initialized showCameraProtection") + } + + fun boundingRect(boundingRectangle: RectF, context: String) { + logBuffer.log( + TAG, + DEBUG, + { + str1 = context + str2 = boundingRectangle.toShortString() + }, + { "Bounding rect $str1 : $str2" } + ) + } + + fun boundingRect(boundingRectangle: Rect, context: String) { + boundingRect(boundingRectangle.toRectF(), context) + } + + fun onMeasureDimensions( + widthMeasureSpec: Int, + heightMeasureSpec: Int, + measuredWidth: Int, + measuredHeight: Int + ) { + logBuffer.log( + TAG, + DEBUG, + { + long1 = widthMeasureSpec.toLong() + long2 = heightMeasureSpec.toLong() + int1 = measuredWidth + int2 = measuredHeight + }, + { + "Face scanning animation: widthMeasureSpec: $long1 measuredWidth: $int1, " + + "heightMeasureSpec: $long2 measuredHeight: $int2" + } + ) + } + + fun faceSensorLocation(faceSensorLocation: Point?) { + logBuffer.log( + TAG, + DEBUG, + { + int1 = faceSensorLocation?.y?.times(2) ?: 0 + str1 = "$faceSensorLocation" + }, + { "Reinflating view: Face sensor location: $str1, faceScanningHeight: $int1" } + ) + } + + fun onSensorLocationChanged() { + logBuffer.log(TAG, DEBUG, "AuthControllerCallback in ScreenDecorations triggered") + } +} diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index 6c6f7e9744fe..41774800c527 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -350,6 +350,16 @@ public class LogModule { } /** + * Provides a {@link LogBuffer} for use by {@link com.android.systemui.ScreenDecorations}. + */ + @Provides + @SysUISingleton + @ScreenDecorationsLog + public static LogBuffer provideScreenDecorationsLog(LogBufferFactory factory) { + return factory.create("ScreenDecorationsLog", 200); + } + + /** * Provides a {@link LogBuffer} for bluetooth-related logs. */ @Provides diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/ScreenDecorationsLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/ScreenDecorationsLog.kt new file mode 100644 index 000000000000..de2a8b679aec --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/ScreenDecorationsLog.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.dagger + +import javax.inject.Qualifier + +/** A [com.android.systemui.log.LogBuffer] for ScreenDecorations added by SysUI. */ +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +annotation class ScreenDecorationsLog diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index e918c1cc9b10..fc111485971c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -21,6 +21,7 @@ import static android.view.DisplayCutout.BOUNDS_POSITION_TOP; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.systemui.dump.LogBufferHelperKt.logcatLogBuffer; import static com.google.common.truth.Truth.assertThat; @@ -88,6 +89,7 @@ import com.android.systemui.decor.OverlayWindow; import com.android.systemui.decor.PrivacyDotCornerDecorProviderImpl; import com.android.systemui.decor.PrivacyDotDecorProviderFactory; import com.android.systemui.decor.RoundedCornerResDelegate; +import com.android.systemui.log.ScreenDecorationsLogger; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.settings.UserTracker; @@ -219,11 +221,14 @@ public class ScreenDecorationsTest extends SysuiTestCase { mAuthController, mStatusBarStateController, mKeyguardUpdateMonitor, - mExecutor)); + mExecutor, + new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")))); mScreenDecorations = spy(new ScreenDecorations(mContext, mExecutor, mSecureSettings, mTunerService, mUserTracker, mDisplayTracker, mDotViewController, mThreadFactory, - mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory) { + mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory, + new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")), + mAuthController) { @Override public void start() { super.start(); |