summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lucas Dupin <dupin@google.com> 2020-08-20 02:51:24 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-08-20 02:51:24 +0000
commit2c4282de92267c41ace25f7403c45b20699e2894 (patch)
treebdd0b567acb3bcdd20ea56d3581a9e715410ccba
parent7f409aab46e0a4717cbc200d89ba270cb0692b9a (diff)
parent37df22f9a461ab85d8fb8e95b14051b3b8a0faaa (diff)
Merge "Face auth low-light mitigation"
-rw-r--r--packages/SystemUI/res-keyguard/drawable/face_auth_wallpaper.pngbin0 -> 709067 bytes
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessController.kt193
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/FaceAuthScreenBrightnessControllerTest.kt135
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java9
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
new file mode 100644
index 000000000000..b907f4eaf362
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/face_auth_wallpaper.png
Binary files differ
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