Loading packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +3 −11 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.hardware.face.FaceManager import android.hardware.face.FaceSensorProperties import android.hardware.face.FaceSensorPropertiesInternal import android.os.CancellationSignal import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId.fakeInstanceId Loading @@ -54,7 +53,6 @@ import com.android.systemui.deviceentry.shared.model.FaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.FaceDetectionStatus import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus import com.android.systemui.display.data.repository.display import com.android.systemui.display.data.repository.displayRepository import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FakeFeatureFlags Loading Loading @@ -697,9 +695,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { ) runCurrent() displayRepository.emit(setOf(display(0, 0, Display.DEFAULT_DISPLAY, Display.STATE_OFF))) displayRepository.emitDisplayChangeEvent(Display.DEFAULT_DISPLAY) displayRepository.setDefaultDisplayOff(true) runCurrent() assertThat(canFaceAuthRun()).isTrue() Loading @@ -717,10 +713,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { ) runCurrent() displayRepository.emit( setOf(display(0, 0, Display.DEFAULT_DISPLAY, Display.STATE_OFF)) ) displayRepository.emitDisplayChangeEvent(Display.DEFAULT_DISPLAY) displayRepository.setDefaultDisplayOff(true) } } Loading Loading @@ -1167,8 +1160,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { faceLockoutResetCallback.value.onLockoutReset(0) bouncerRepository.setAlternateVisible(true) keyguardRepository.setKeyguardShowing(true) displayRepository.emit(setOf(display(0, 0, Display.DEFAULT_DISPLAY, Display.STATE_ON))) displayRepository.emitDisplayChangeEvent(Display.DEFAULT_DISPLAY) displayRepository.setDefaultDisplayOff(false) keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN, Loading packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +12 −4 Original line number Diff line number Diff line Loading @@ -401,8 +401,6 @@ public class ScreenDecorations implements mExecutor = mThreadFactory.buildDelayableExecutorOnHandler(mHandler); mExecutor.execute(this::startOnScreenDecorationsThread); mDotViewController.setUiExecutor(mExecutor); mJavaAdapter.alwaysCollectFlow(mFacePropertyRepository.getSensorLocation(), this::onFaceSensorLocationChanged); mCommandRegistry.registerCommand(ScreenDecorCommand.SCREEN_DECOR_CMD_NAME, () -> new ScreenDecorCommand(mScreenDecorCommandCallback)); } Loading Loading @@ -579,6 +577,8 @@ public class ScreenDecorations implements }; mDisplayTracker.addDisplayChangeCallback(mDisplayListener, new HandlerExecutor(mHandler)); updateConfiguration(); mJavaAdapter.alwaysCollectFlow(mFacePropertyRepository.getSensorLocation(), this::onFaceSensorLocationChanged); Trace.endSection(); } Loading Loading @@ -1320,10 +1320,18 @@ public class ScreenDecorations implements @VisibleForTesting void onFaceSensorLocationChanged(Point location) { mLogger.onSensorLocationChanged(); if (mExecutor != null) { mExecutor.execute( () -> updateOverlayProviderViews( new Integer[]{mFaceScanningViewId})); () -> { if (getOverlayView(mFaceScanningViewId) == null) { // face sensor location was just initialized setupDecorations(); } else { updateOverlayProviderViews(new Integer[]{mFaceScanningViewId}); } } ); } } Loading packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt +1 −14 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.biometrics.domain.interactor import android.content.Context import android.content.res.Configuration import android.view.Display import com.android.systemui.biometrics.data.repository.DisplayStateRepository import com.android.systemui.biometrics.shared.model.DisplayRotation import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging Loading @@ -28,7 +27,6 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.display.data.repository.DisplayRepository import com.android.systemui.unfold.compat.ScreenSizeFoldProvider import com.android.systemui.unfold.updates.FoldProvider import com.android.systemui.util.kotlin.sample import java.util.concurrent.Executor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope Loading @@ -36,8 +34,6 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** Aggregates display state information. */ Loading Loading @@ -129,16 +125,7 @@ constructor( screenSizeFoldProvider.onConfigurationChange(newConfig) } private val defaultDisplay = displayRepository.displays.map { displays -> displays.firstOrNull { it.displayId == Display.DEFAULT_DISPLAY } } override val isDefaultDisplayOff = displayRepository.displayChangeEvent .filter { it == Display.DEFAULT_DISPLAY } .sample(defaultDisplay) .map { it?.state == Display.STATE_OFF } override val isDefaultDisplayOff = displayRepository.defaultDisplayOff override val isLargeScreen: Flow<Boolean> = displayStateRepository.isLargeScreen Loading packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt +9 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map Loading @@ -67,6 +68,9 @@ interface DisplayRepository { */ val pendingDisplay: Flow<PendingDisplay?> /** Whether the default display is currently off. */ val defaultDisplayOff: Flow<Boolean> /** Represents a connected display that has not been enabled yet. */ interface PendingDisplay { /** Id of the pending display. */ Loading Loading @@ -290,6 +294,11 @@ constructor( } .debugLog("pendingDisplay") override val defaultDisplayOff: Flow<Boolean> = displays .map { displays -> displays.firstOrNull { it.displayId == Display.DEFAULT_DISPLAY } } .map { it?.state == Display.STATE_OFF } private fun <T> Flow<T>.debugLog(flowName: String): Flow<T> { return if (DEBUG) { traceEach(flowName, logcat = true, traceEmissionCount = true) Loading packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -1273,6 +1273,28 @@ public class ScreenDecorationsTest extends SysuiTestCase { any()); } @Test public void delayedFaceSensorLocationChangesAddsFaceScanningOverlay() { setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */, null /* roundedTopDrawable */, null /* roundedBottomDrawable */, 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */); mScreenDecorations.start(); verifyFaceScanningViewExists(false); // face scanning view not added yet // WHEN the sensor location is updated mFaceScanningProviders = new ArrayList<>(); mFaceScanningProviders.add(mFaceScanningDecorProvider); when(mFaceScanningProviderFactory.getProviders()).thenReturn(mFaceScanningProviders); when(mFaceScanningProviderFactory.getHasProviders()).thenReturn(true); final Point location = new Point(); mFakeFacePropertyRepository.setSensorLocation(location); mScreenDecorations.onFaceSensorLocationChanged(location); mExecutor.runAllReady(); // THEN the face scanning view is added verifyFaceScanningViewExists(true); } @Test public void testPrivacyDotShowingListenerWorkWellWithNullParameter() { mPrivacyDotShowingListener.onPrivacyDotShown(null); Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +3 −11 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.hardware.face.FaceManager import android.hardware.face.FaceSensorProperties import android.hardware.face.FaceSensorPropertiesInternal import android.os.CancellationSignal import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId.fakeInstanceId Loading @@ -54,7 +53,6 @@ import com.android.systemui.deviceentry.shared.model.FaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.FaceDetectionStatus import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus import com.android.systemui.display.data.repository.display import com.android.systemui.display.data.repository.displayRepository import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FakeFeatureFlags Loading Loading @@ -697,9 +695,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { ) runCurrent() displayRepository.emit(setOf(display(0, 0, Display.DEFAULT_DISPLAY, Display.STATE_OFF))) displayRepository.emitDisplayChangeEvent(Display.DEFAULT_DISPLAY) displayRepository.setDefaultDisplayOff(true) runCurrent() assertThat(canFaceAuthRun()).isTrue() Loading @@ -717,10 +713,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { ) runCurrent() displayRepository.emit( setOf(display(0, 0, Display.DEFAULT_DISPLAY, Display.STATE_OFF)) ) displayRepository.emitDisplayChangeEvent(Display.DEFAULT_DISPLAY) displayRepository.setDefaultDisplayOff(true) } } Loading Loading @@ -1167,8 +1160,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { faceLockoutResetCallback.value.onLockoutReset(0) bouncerRepository.setAlternateVisible(true) keyguardRepository.setKeyguardShowing(true) displayRepository.emit(setOf(display(0, 0, Display.DEFAULT_DISPLAY, Display.STATE_ON))) displayRepository.emitDisplayChangeEvent(Display.DEFAULT_DISPLAY) displayRepository.setDefaultDisplayOff(false) keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN, Loading
packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +12 −4 Original line number Diff line number Diff line Loading @@ -401,8 +401,6 @@ public class ScreenDecorations implements mExecutor = mThreadFactory.buildDelayableExecutorOnHandler(mHandler); mExecutor.execute(this::startOnScreenDecorationsThread); mDotViewController.setUiExecutor(mExecutor); mJavaAdapter.alwaysCollectFlow(mFacePropertyRepository.getSensorLocation(), this::onFaceSensorLocationChanged); mCommandRegistry.registerCommand(ScreenDecorCommand.SCREEN_DECOR_CMD_NAME, () -> new ScreenDecorCommand(mScreenDecorCommandCallback)); } Loading Loading @@ -579,6 +577,8 @@ public class ScreenDecorations implements }; mDisplayTracker.addDisplayChangeCallback(mDisplayListener, new HandlerExecutor(mHandler)); updateConfiguration(); mJavaAdapter.alwaysCollectFlow(mFacePropertyRepository.getSensorLocation(), this::onFaceSensorLocationChanged); Trace.endSection(); } Loading Loading @@ -1320,10 +1320,18 @@ public class ScreenDecorations implements @VisibleForTesting void onFaceSensorLocationChanged(Point location) { mLogger.onSensorLocationChanged(); if (mExecutor != null) { mExecutor.execute( () -> updateOverlayProviderViews( new Integer[]{mFaceScanningViewId})); () -> { if (getOverlayView(mFaceScanningViewId) == null) { // face sensor location was just initialized setupDecorations(); } else { updateOverlayProviderViews(new Integer[]{mFaceScanningViewId}); } } ); } } Loading
packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt +1 −14 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.biometrics.domain.interactor import android.content.Context import android.content.res.Configuration import android.view.Display import com.android.systemui.biometrics.data.repository.DisplayStateRepository import com.android.systemui.biometrics.shared.model.DisplayRotation import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging Loading @@ -28,7 +27,6 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.display.data.repository.DisplayRepository import com.android.systemui.unfold.compat.ScreenSizeFoldProvider import com.android.systemui.unfold.updates.FoldProvider import com.android.systemui.util.kotlin.sample import java.util.concurrent.Executor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope Loading @@ -36,8 +34,6 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** Aggregates display state information. */ Loading Loading @@ -129,16 +125,7 @@ constructor( screenSizeFoldProvider.onConfigurationChange(newConfig) } private val defaultDisplay = displayRepository.displays.map { displays -> displays.firstOrNull { it.displayId == Display.DEFAULT_DISPLAY } } override val isDefaultDisplayOff = displayRepository.displayChangeEvent .filter { it == Display.DEFAULT_DISPLAY } .sample(defaultDisplay) .map { it?.state == Display.STATE_OFF } override val isDefaultDisplayOff = displayRepository.defaultDisplayOff override val isLargeScreen: Flow<Boolean> = displayStateRepository.isLargeScreen Loading
packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt +9 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map Loading @@ -67,6 +68,9 @@ interface DisplayRepository { */ val pendingDisplay: Flow<PendingDisplay?> /** Whether the default display is currently off. */ val defaultDisplayOff: Flow<Boolean> /** Represents a connected display that has not been enabled yet. */ interface PendingDisplay { /** Id of the pending display. */ Loading Loading @@ -290,6 +294,11 @@ constructor( } .debugLog("pendingDisplay") override val defaultDisplayOff: Flow<Boolean> = displays .map { displays -> displays.firstOrNull { it.displayId == Display.DEFAULT_DISPLAY } } .map { it?.state == Display.STATE_OFF } private fun <T> Flow<T>.debugLog(flowName: String): Flow<T> { return if (DEBUG) { traceEach(flowName, logcat = true, traceEmissionCount = true) Loading
packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -1273,6 +1273,28 @@ public class ScreenDecorationsTest extends SysuiTestCase { any()); } @Test public void delayedFaceSensorLocationChangesAddsFaceScanningOverlay() { setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */, null /* roundedTopDrawable */, null /* roundedBottomDrawable */, 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */); mScreenDecorations.start(); verifyFaceScanningViewExists(false); // face scanning view not added yet // WHEN the sensor location is updated mFaceScanningProviders = new ArrayList<>(); mFaceScanningProviders.add(mFaceScanningDecorProvider); when(mFaceScanningProviderFactory.getProviders()).thenReturn(mFaceScanningProviders); when(mFaceScanningProviderFactory.getHasProviders()).thenReturn(true); final Point location = new Point(); mFakeFacePropertyRepository.setSensorLocation(location); mScreenDecorations.onFaceSensorLocationChanged(location); mExecutor.runAllReady(); // THEN the face scanning view is added verifyFaceScanningViewExists(true); } @Test public void testPrivacyDotShowingListenerWorkWellWithNullParameter() { mPrivacyDotShowingListener.onPrivacyDotShown(null); Loading