diff options
| author | 2020-08-20 02:51:24 +0000 | |
|---|---|---|
| committer | 2020-08-20 02:51:24 +0000 | |
| commit | 2c4282de92267c41ace25f7403c45b20699e2894 (patch) | |
| tree | bdd0b567acb3bcdd20ea56d3581a9e715410ccba | |
| parent | 7f409aab46e0a4717cbc200d89ba270cb0692b9a (diff) | |
| parent | 37df22f9a461ab85d8fb8e95b14051b3b8a0faaa (diff) | |
Merge "Face auth low-light mitigation"
11 files changed, 444 insertions, 27 deletions
diff --git a/packages/SystemUI/res-keyguard/drawable/face_auth_wallpaper.png b/packages/SystemUI/res-keyguard/drawable/face_auth_wallpaper.png Binary files differnew file mode 100644 index 000000000000..b907f4eaf362 --- /dev/null +++ b/packages/SystemUI/res-keyguard/drawable/face_auth_wallpaper.png diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java index 7fe9faf5258c..e7d2f125935a 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java @@ -41,6 +41,7 @@ import android.hardware.SensorManager; import android.hardware.SensorPrivacyManager; import android.hardware.display.ColorDisplayManager; import android.hardware.display.DisplayManager; +import android.hardware.face.FaceManager; import android.media.AudioManager; import android.media.MediaRouter2Manager; import android.media.session.MediaSessionManager; @@ -168,6 +169,14 @@ public class SystemServicesModule { @Provides @SysUISingleton + @Nullable + static FaceManager provideFaceManager(Context context) { + return context.getSystemService(FaceManager.class); + + } + + @Provides + @SysUISingleton static IPackageManager provideIPackageManager() { return IPackageManager.Stub.asInterface(ServiceManager.getService("package")); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index abfc2ab1c6e8..df81cab29710 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -16,21 +16,14 @@ package com.android.systemui.dagger; -import android.annotation.Nullable; -import android.content.Context; -import android.content.pm.PackageManager; - -import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.BootCompleteCache; import com.android.systemui.BootCompleteCacheImpl; import com.android.systemui.assist.AssistModule; import com.android.systemui.demomode.dagger.DemoModeModule; import com.android.systemui.doze.dagger.DozeComponent; -import com.android.systemui.dump.DumpManager; import com.android.systemui.fragments.FragmentService; import com.android.systemui.log.dagger.LogModule; import com.android.systemui.model.SysUiState; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.Recents; import com.android.systemui.settings.dagger.SettingsModule; import com.android.systemui.stackdivider.Divider; @@ -41,12 +34,10 @@ import com.android.systemui.statusbar.notification.people.PeopleHubModule; import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent; import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent; import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent; -import com.android.systemui.statusbar.phone.KeyguardLiftController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.dagger.StatusBarComponent; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.concurrency.ConcurrencyModule; -import com.android.systemui.util.sensors.AsyncSensorManager; import com.android.systemui.util.sensors.SensorModule; import com.android.systemui.util.settings.SettingsUtilModule; import com.android.systemui.util.time.SystemClock; @@ -87,22 +78,6 @@ public abstract class SystemUIModule { public abstract ContextComponentHelper bindComponentHelper( ContextComponentResolver componentHelper); - @SysUISingleton - @Provides - @Nullable - static KeyguardLiftController provideKeyguardLiftController( - Context context, - StatusBarStateController statusBarStateController, - AsyncSensorManager asyncSensorManager, - KeyguardUpdateMonitor keyguardUpdateMonitor, - DumpManager dumpManager) { - if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) { - return null; - } - return new KeyguardLiftController(statusBarStateController, asyncSensorManager, - keyguardUpdateMonitor, dumpManager); - } - /** */ @Binds public abstract NotificationRowBinder bindNotificationRowBinder( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessController.kt new file mode 100644 index 000000000000..9dcc3bb6fbdc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessController.kt @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2020 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.keyguard + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.ValueAnimator +import android.content.res.Resources +import android.database.ContentObserver +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.hardware.biometrics.BiometricSourceType +import android.os.Handler +import android.provider.Settings.System.SCREEN_BRIGHTNESS_FLOAT +import android.util.MathUtils +import android.view.View +import android.view.WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE +import android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE +import com.android.internal.annotations.VisibleForTesting +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.KeyguardUpdateMonitorCallback +import com.android.systemui.Dumpable +import com.android.systemui.R +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dump.DumpManager +import com.android.systemui.statusbar.NotificationShadeWindowController +import com.android.systemui.util.settings.GlobalSettings +import com.android.systemui.util.settings.SystemSettings +import java.io.FileDescriptor +import java.io.PrintWriter +import java.lang.Float.max +import java.util.concurrent.TimeUnit + +val DEFAULT_ANIMATION_DURATION = TimeUnit.SECONDS.toMillis(4) +val MAX_SCREEN_BRIGHTNESS = 100 // 0..100 +val MAX_SCRIM_OPACTY = 50 // 0..100 +val DEFAULT_USE_FACE_WALLPAPER = false + +/** + * This class is responsible for ramping up the display brightness (and white overlay) in order + * to mitigate low light conditions when running face auth without an IR camera. + */ +@SysUISingleton +open class FaceAuthScreenBrightnessController( + private val notificationShadeWindowController: NotificationShadeWindowController, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val resources: Resources, + private val globalSettings: GlobalSettings, + private val systemSettings: SystemSettings, + private val mainHandler: Handler, + private val dumpManager: DumpManager +) : Dumpable { + + private var userDefinedBrightness: Float = 1f + @VisibleForTesting + var useFaceAuthWallpaper = globalSettings + .getInt("sysui.use_face_auth_wallpaper", if (DEFAULT_USE_FACE_WALLPAPER) 1 else 0) == 1 + private val brightnessAnimationDuration = globalSettings + .getLong("sysui.face_brightness_anim_duration", DEFAULT_ANIMATION_DURATION) + private val maxScreenBrightness = globalSettings + .getInt("sysui.face_max_brightness", MAX_SCREEN_BRIGHTNESS) / 100f + private val maxScrimOpacity = globalSettings + .getInt("sysui.face_max_scrim_opacity", MAX_SCRIM_OPACTY) / 100f + private val keyguardUpdateCallback = object : KeyguardUpdateMonitorCallback() { + override fun onBiometricRunningStateChanged( + running: Boolean, + biometricSourceType: BiometricSourceType? + ) { + if (biometricSourceType != BiometricSourceType.FACE) { + return + } + // TODO enable only when receiving a low-light error + overridingBrightness = running + } + } + private lateinit var whiteOverlay: View + private var brightnessAnimator: ValueAnimator? = null + private var overridingBrightness = false + set(value) { + if (field == value) { + return + } + field = value + brightnessAnimator?.cancel() + + if (!value) { + notificationShadeWindowController.setFaceAuthDisplayBrightness(BRIGHTNESS_OVERRIDE_NONE) + if (whiteOverlay.alpha > 0) { + brightnessAnimator = createAnimator(whiteOverlay.alpha, 0f).apply { + duration = 200 + addUpdateListener { + whiteOverlay.alpha = it.animatedValue as Float + } + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator?) { + whiteOverlay.visibility = View.INVISIBLE + brightnessAnimator = null + } + }) + start() + } + } + return + } + + val targetBrightness = max(maxScreenBrightness, userDefinedBrightness) + whiteOverlay.visibility = View.VISIBLE + brightnessAnimator = createAnimator(0f, 1f).apply { + duration = brightnessAnimationDuration + addUpdateListener { + val progress = it.animatedValue as Float + val brightnessProgress = MathUtils.constrainedMap( + userDefinedBrightness, targetBrightness, 0f, 0.5f, progress) + val scrimProgress = MathUtils.constrainedMap( + 0f, maxScrimOpacity, 0.5f, 1f, progress) + notificationShadeWindowController.setFaceAuthDisplayBrightness(brightnessProgress) + whiteOverlay.alpha = scrimProgress + } + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator?) { + brightnessAnimator = null + } + }) + start() + } + } + + @VisibleForTesting + open fun createAnimator(start: Float, end: Float) = ValueAnimator.ofFloat(start, end) + + /** + * Returns a bitmap that should be used by the lock screen as a wallpaper, if face auth requires + * a secure wallpaper. + */ + var faceAuthWallpaper: Bitmap? = null + get() { + val user = KeyguardUpdateMonitor.getCurrentUser() + if (useFaceAuthWallpaper && keyguardUpdateMonitor.isFaceAuthEnabledForUser(user)) { + val options = BitmapFactory.Options().apply { + inScaled = false + } + return BitmapFactory.decodeResource(resources, R.drawable.face_auth_wallpaper, options) + } + return null + } + private set + + fun attach(overlayView: View) { + whiteOverlay = overlayView + whiteOverlay.focusable = FLAG_NOT_FOCUSABLE + whiteOverlay.background = ColorDrawable(Color.WHITE) + whiteOverlay.isEnabled = false + whiteOverlay.alpha = 0f + whiteOverlay.visibility = View.INVISIBLE + + dumpManager.registerDumpable(this.javaClass.name, this) + keyguardUpdateMonitor.registerCallback(keyguardUpdateCallback) + systemSettings.registerContentObserver(SCREEN_BRIGHTNESS_FLOAT, + object : ContentObserver(mainHandler) { + override fun onChange(selfChange: Boolean) { + userDefinedBrightness = systemSettings.getFloat(SCREEN_BRIGHTNESS_FLOAT) + } + }) + userDefinedBrightness = systemSettings.getFloat(SCREEN_BRIGHTNESS_FLOAT) + } + + override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) { + pw.apply { + println("overridingBrightness: $overridingBrightness") + println("useFaceAuthWallpaper: $useFaceAuthWallpaper") + println("brightnessAnimator: $brightnessAnimator") + println("brightnessAnimationDuration: $brightnessAnimationDuration") + println("maxScreenBrightness: $maxScreenBrightness") + println("userDefinedBrightness: $userDefinedBrightness") + } + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index 7c5dcd8960c4..c9164f0c4459 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -16,8 +16,13 @@ package com.android.systemui.keyguard.dagger; +import android.annotation.Nullable; import android.app.trust.TrustManager; import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.hardware.face.FaceManager; +import android.os.Handler; import android.os.PowerManager; import com.android.internal.widget.LockPatternUtils; @@ -25,16 +30,25 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardViewController; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.DismissCallbackRegistry; +import com.android.systemui.keyguard.FaceAuthScreenBrightnessController; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.NotificationShadeWindowController; +import com.android.systemui.statusbar.phone.KeyguardLiftController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.InjectionInflationController; +import com.android.systemui.util.sensors.AsyncSensorManager; +import com.android.systemui.util.settings.GlobalSettings; +import com.android.systemui.util.settings.SystemSettings; +import java.util.Optional; import java.util.concurrent.Executor; import dagger.Lazy; @@ -82,4 +96,50 @@ public class KeyguardModule { navigationModeController, injectionInflationController); } + + @SysUISingleton + @Provides + @Nullable + static KeyguardLiftController provideKeyguardLiftController( + Context context, + StatusBarStateController statusBarStateController, + AsyncSensorManager asyncSensorManager, + KeyguardUpdateMonitor keyguardUpdateMonitor, + DumpManager dumpManager) { + if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) { + return null; + } + return new KeyguardLiftController(statusBarStateController, asyncSensorManager, + keyguardUpdateMonitor, dumpManager); + } + + @SysUISingleton + @Provides + static Optional<FaceAuthScreenBrightnessController> provideFaceAuthScreenBrightnessController( + Context context, + NotificationShadeWindowController notificationShadeWindowController, + @Main Resources resources, + Handler handler, + @Nullable FaceManager faceManager, + PackageManager packageManager, + KeyguardUpdateMonitor keyguardUpdateMonitor, + GlobalSettings globalSetting, + SystemSettings systemSettings, + DumpManager dumpManager) { + if (faceManager == null || !packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) { + return Optional.empty(); + } + + // Cameras that support "self illumination," via IR for example, don't need low light + // environment mitigation. + boolean needsLowLightMitigation = faceManager.getSensorProperties().stream() + .anyMatch((properties) -> !properties.supportsSelfIllumination); + if (!needsLowLightMitigation) { + return Optional.empty(); + } + + return Optional.of(new FaceAuthScreenBrightnessController( + notificationShadeWindowController, keyguardUpdateMonitor, resources, + globalSetting, systemSettings, handler, dumpManager)); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java index 1fd0b03a77b7..24515f7bc210 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java @@ -164,6 +164,13 @@ public interface NotificationShadeWindowController extends RemoteInputController default void setRequestTopUi(boolean requestTopUi, String componentTag) {} /** + * Under low light conditions, we might want to increase the display brightness on devices that + * don't have an IR camera. + * @param brightness float from 0 to 1 or {@code LayoutParams.BRIGHTNESS_OVERRIDE_NONE} + */ + default void setFaceAuthDisplayBrightness(float brightness) {} + + /** * Custom listener to pipe data back to plugins about whether or not the status bar would be * collapsed if not for the plugin. * TODO: Find cleaner way to do this. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java index a6811c6b8ba4..78fcd82dc1f5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java @@ -45,6 +45,7 @@ import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; +import com.android.systemui.keyguard.FaceAuthScreenBrightnessController; import com.android.systemui.statusbar.NotificationMediaManager; import libcore.io.IoUtils; @@ -52,6 +53,7 @@ import libcore.io.IoUtils; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Objects; +import java.util.Optional; import javax.inject.Inject; @@ -68,6 +70,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen private final WallpaperManager mWallpaperManager; private final KeyguardUpdateMonitor mUpdateMonitor; private final Handler mH; + private final Optional<FaceAuthScreenBrightnessController> mFaceAuthScreenBrightnessController; private boolean mCached; private Bitmap mCache; @@ -83,12 +86,14 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen KeyguardUpdateMonitor keyguardUpdateMonitor, DumpManager dumpManager, NotificationMediaManager mediaManager, + Optional<FaceAuthScreenBrightnessController> faceAuthScreenBrightnessController, @Main Handler mainHandler) { dumpManager.registerDumpable(getClass().getSimpleName(), this); mWallpaperManager = wallpaperManager; mCurrentUserId = ActivityManager.getCurrentUser(); mUpdateMonitor = keyguardUpdateMonitor; mMediaManager = mediaManager; + mFaceAuthScreenBrightnessController = faceAuthScreenBrightnessController; mH = mainHandler; if (iWallpaperManager != null) { @@ -128,6 +133,14 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen return LoaderResult.success(null); } + Bitmap faceAuthWallpaper = null; + if (mFaceAuthScreenBrightnessController.isPresent()) { + faceAuthWallpaper = mFaceAuthScreenBrightnessController.get().getFaceAuthWallpaper(); + if (faceAuthWallpaper != null) { + return LoaderResult.success(faceAuthWallpaper); + } + } + // Prefer the selected user (when specified) over the current user for the FLAG_SET_LOCK // wallpaper. final int lockWallpaperUserId = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java index 3c43a1777171..5abc42613fd1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java @@ -101,6 +101,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW mCallbacks = Lists.newArrayList(); private final SysuiColorExtractor mColorExtractor; + private float mFaceAuthDisplayBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE; @Inject public NotificationShadeWindowControllerImpl(Context context, WindowManager windowManager, @@ -232,6 +233,12 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW mScreenBrightnessDoze = value / 255f; } + @Override + public void setFaceAuthDisplayBrightness(float brightness) { + mFaceAuthDisplayBrightness = brightness; + apply(mCurrentState); + } + private void setKeyguardDark(boolean dark) { int vis = mNotificationShadeView.getSystemUiVisibility(); if (dark) { @@ -436,7 +443,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW if (state.mForceDozeBrightness) { mLpChanged.screenBrightness = mScreenBrightnessDoze; } else { - mLpChanged.screenBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE; + mLpChanged.screenBrightness = mFaceAuthDisplayBrightness; } } @@ -701,6 +708,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW boolean mHeadsUpShowing; boolean mForceCollapsed; boolean mForceDozeBrightness; + int mFaceAuthDisplayBrightness; boolean mForceUserActivity; boolean mLaunchingActivity; boolean mBackdropShowing; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 7ee501c681f9..777bf3f73480 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -50,6 +50,7 @@ import com.android.systemui.SystemUIFactory; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dock.DockManager; import com.android.systemui.keyguard.DismissCallbackRegistry; +import com.android.systemui.keyguard.FaceAuthScreenBrightnessController; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -68,6 +69,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Optional; import javax.inject.Inject; @@ -103,6 +105,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private final ConfigurationController mConfigurationController; private final NavigationModeController mNavigationModeController; private final NotificationShadeWindowController mNotificationShadeWindowController; + private final Optional<FaceAuthScreenBrightnessController> mFaceAuthScreenBrightnessController; private final BouncerExpansionCallback mExpansionCallback = new BouncerExpansionCallback() { @Override public void onFullyShown() { @@ -212,6 +215,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb DockManager dockManager, NotificationShadeWindowController notificationShadeWindowController, KeyguardStateController keyguardStateController, + Optional<FaceAuthScreenBrightnessController> faceAuthScreenBrightnessController, NotificationMediaManager notificationMediaManager) { mContext = context; mViewMediatorCallback = callback; @@ -224,6 +228,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mKeyguardUpdateManager = keyguardUpdateMonitor; mStatusBarStateController = sysuiStatusBarStateController; mDockManager = dockManager; + mFaceAuthScreenBrightnessController = faceAuthScreenBrightnessController; } @Override @@ -248,6 +253,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb notificationPanelViewController.addExpansionListener(this); mBypassController = bypassController; mNotificationContainer = notificationContainer; + mFaceAuthScreenBrightnessController.ifPresent((it) -> { + View overlay = new View(mContext); + container.addView(overlay); + it.attach(overlay); + }); registerListeners(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessControllerTest.kt new file mode 100644 index 000000000000..58cb0324c69a --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessControllerTest.kt @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2020 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.keyguard + +import android.animation.ValueAnimator +import android.content.res.Resources +import android.hardware.biometrics.BiometricSourceType +import android.os.Handler +import android.provider.Settings.System.SCREEN_BRIGHTNESS_FLOAT +import android.testing.AndroidTestingRunner +import android.util.TypedValue +import android.view.View +import androidx.test.filters.SmallTest +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.KeyguardUpdateMonitorCallback +import com.android.systemui.Dumpable +import com.android.systemui.SysuiTestCase +import com.android.systemui.dump.DumpManager +import com.android.systemui.statusbar.NotificationShadeWindowController +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.capture +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.settings.GlobalSettings +import com.android.systemui.util.settings.SystemSettings +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor +import org.mockito.Captor +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.anyString +import org.mockito.Mockito.clearInvocations +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +const val INITIAL_BRIGHTNESS = 0.5f + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class FaceAuthScreenBrightnessControllerTest : SysuiTestCase() { + + @Mock + lateinit var whiteOverlay: View + @Mock + lateinit var dumpManager: DumpManager + @Mock + lateinit var resources: Resources + @Mock + lateinit var mainHandler: Handler + @Mock + lateinit var globalSettings: GlobalSettings + @Mock + lateinit var systemSettings: SystemSettings + @Mock + lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + @Mock + lateinit var notificationShadeWindowController: NotificationShadeWindowController + @Mock + lateinit var animator: ValueAnimator + @Captor + lateinit var keyguardUpdateCallback: ArgumentCaptor<KeyguardUpdateMonitorCallback> + lateinit var faceAuthScreenBrightnessController: FaceAuthScreenBrightnessController + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + faceAuthScreenBrightnessController = object : FaceAuthScreenBrightnessController( + notificationShadeWindowController, keyguardUpdateMonitor, resources, globalSettings, + systemSettings, mainHandler, dumpManager) { + override fun createAnimator(start: Float, end: Float) = animator + } + `when`(systemSettings.getFloat(eq(SCREEN_BRIGHTNESS_FLOAT))).thenReturn(INITIAL_BRIGHTNESS) + faceAuthScreenBrightnessController.attach(whiteOverlay) + verify(keyguardUpdateMonitor).registerCallback(capture(keyguardUpdateCallback)) + } + + @Test + fun init_registersDumpManager() { + verify(dumpManager).registerDumpable(anyString(), any(Dumpable::class.java)) + } + + @Test + fun init_registersKeyguardCallback() { + verify(keyguardUpdateMonitor) + .registerCallback(any(KeyguardUpdateMonitorCallback::class.java)) + } + + @Test + fun onBiometricRunningChanged_animatesBrightness() { + clearInvocations(whiteOverlay) + keyguardUpdateCallback.value + .onBiometricRunningStateChanged(true, BiometricSourceType.FACE) + verify(whiteOverlay).visibility = eq(View.VISIBLE) + verify(animator).start() + } + + @Test + fun faceAuthWallpaper_whenFaceIsDisabledForUser() { + faceAuthScreenBrightnessController.useFaceAuthWallpaper = true + faceAuthScreenBrightnessController.faceAuthWallpaper + verify(resources, never()).openRawResource(anyInt(), any(TypedValue::class.java)) + } + + @Test + fun faceAuthWallpaper_whenFaceFlagIsDisabled() { + faceAuthScreenBrightnessController.useFaceAuthWallpaper = true + faceAuthScreenBrightnessController.faceAuthWallpaper + verify(resources, never()).openRawResource(anyInt(), any(TypedValue::class.java)) + } + + @Test + fun faceAuthWallpaper_whenFaceIsEnabledForUser() { + faceAuthScreenBrightnessController.useFaceAuthWallpaper = true + `when`(keyguardUpdateMonitor.isFaceAuthEnabledForUser(anyInt())).thenReturn(true) + faceAuthScreenBrightnessController.faceAuthWallpaper + verify(resources).openRawResource(anyInt(), any(TypedValue::class.java)) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index ccc307841491..2f4511329041 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -43,6 +43,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.dock.DockManager; import com.android.systemui.keyguard.DismissCallbackRegistry; +import com.android.systemui.keyguard.FaceAuthScreenBrightnessController; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.plugins.FalsingManager; @@ -58,6 +59,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Optional; + @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @@ -89,6 +92,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { private View mNotificationContainer; @Mock private KeyguardBypassController mBypassController; + @Mock + private FaceAuthScreenBrightnessController mFaceAuthScreenBrightnessController; private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @Before @@ -108,6 +113,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { mock(DockManager.class), mock(NotificationShadeWindowController.class), mKeyguardStateController, + mFaceAuthScreenBrightnessController, mock(NotificationMediaManager.class)); mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer, mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry, @@ -274,11 +280,12 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { DockManager dockManager, NotificationShadeWindowController notificationShadeWindowController, KeyguardStateController keyguardStateController, + FaceAuthScreenBrightnessController faceAuthScreenBrightnessController, NotificationMediaManager notificationMediaManager) { super(context, callback, lockPatternUtils, sysuiStatusBarStateController, configurationController, keyguardUpdateMonitor, navigationModeController, dockManager, notificationShadeWindowController, keyguardStateController, - notificationMediaManager); + Optional.of(faceAuthScreenBrightnessController), notificationMediaManager); } @Override |