Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +3 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.window.TaskSnapshot; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.animation.Interpolators; import com.android.wm.shell.transition.Transitions; Loading Loading @@ -372,7 +373,8 @@ public class PipAnimationController { void setAppIconContentOverlay(Context context, Rect bounds, ActivityInfo activityInfo) { reattachContentOverlay( new PipContentOverlay.PipAppIconOverlay(context, bounds, activityInfo)); new PipContentOverlay.PipAppIconOverlay(context, bounds, () -> new IconProvider(context).getIcon(activityInfo))); } private void reattachContentOverlay(PipContentOverlay overlay) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java +9 −28 Original line number Diff line number Diff line Loading @@ -20,9 +20,6 @@ import static android.util.TypedValue.COMPLEX_UNIT_DIP; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; Loading @@ -35,6 +32,8 @@ import android.view.SurfaceControl; import android.view.SurfaceSession; import android.window.TaskSnapshot; import java.util.function.Supplier; /** * Represents the content overlay used during the entering PiP animation. */ Loading Loading @@ -177,7 +176,9 @@ public abstract class PipContentOverlay { /** A {@link PipContentOverlay} shows app icon on solid color background. */ public static final class PipAppIconOverlay extends PipContentOverlay { private static final String TAG = PipAppIconOverlay.class.getSimpleName(); private static final int APP_ICON_SIZE_DP = 48; // Align with the practical / reasonable launcher:iconImageSize as in // vendor/unbundled_google/packages/NexusLauncher/res/xml/device_profiles.xml private static final int APP_ICON_SIZE_DP = 66; private final Context mContext; private final int mAppIconSizePx; Loading @@ -187,14 +188,14 @@ public abstract class PipContentOverlay { private Bitmap mBitmap; public PipAppIconOverlay(Context context, Rect appBounds, ActivityInfo activityInfo) { public PipAppIconOverlay(Context context, Rect appBounds, Supplier<Drawable> iconSupplier) { mContext = context; mAppIconSizePx = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, APP_ICON_SIZE_DP, context.getResources().getDisplayMetrics()); mAppBounds = new Rect(appBounds); mBitmap = Bitmap.createBitmap(appBounds.width(), appBounds.height(), Bitmap.Config.ARGB_8888); prepareAppIconOverlay(activityInfo); prepareAppIconOverlay(iconSupplier); mLeash = new SurfaceControl.Builder(new SurfaceSession()) .setCallsite(TAG) .setName(LAYER_NAME) Loading Loading @@ -237,7 +238,7 @@ public abstract class PipContentOverlay { } } private void prepareAppIconOverlay(ActivityInfo activityInfo) { private void prepareAppIconOverlay(Supplier<Drawable> iconSupplier) { final Canvas canvas = new Canvas(); canvas.setBitmap(mBitmap); final TypedArray ta = mContext.obtainStyledAttributes(new int[] { Loading @@ -251,8 +252,7 @@ public abstract class PipContentOverlay { } finally { ta.recycle(); } final Drawable appIcon = loadActivityInfoIcon(activityInfo, mContext.getResources().getConfiguration().densityDpi); final Drawable appIcon = iconSupplier.get(); final Rect appIconBounds = new Rect( mAppBounds.centerX() - mAppIconSizePx / 2, mAppBounds.centerY() - mAppIconSizePx / 2, Loading @@ -262,24 +262,5 @@ public abstract class PipContentOverlay { appIcon.draw(canvas); mBitmap = mBitmap.copy(Bitmap.Config.HARDWARE, false /* mutable */); } // Copied from com.android.launcher3.icons.IconProvider#loadActivityInfoIcon private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) { final int iconRes = ai.getIconResource(); Drawable icon = null; // Get the preferred density icon from the app's resources if (density != 0 && iconRes != 0) { try { final Resources resources = mContext.getPackageManager() .getResourcesForApplication(ai.applicationInfo); icon = resources.getDrawableForDensity(iconRes, density); } catch (PackageManager.NameNotFoundException | Resources.NotFoundException exc) { } } // Get the default density icon if (icon == null) { icon = ai.loadIcon(mContext.getPackageManager()); } return icon; } } } libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +8 −1 Original line number Diff line number Diff line Loading @@ -803,8 +803,15 @@ public class PipTransition extends PipTransitionController { if (sourceHintRect == null) { // We use content overlay when there is no source rect hint to enter PiP use bounds // animation. // TODO(b/272819817): cleanup the null-check and extra logging. final boolean hasTopActivityInfo = taskInfo.topActivityInfo != null; if (!hasTopActivityInfo) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "%s: TaskInfo.topActivityInfo is null", TAG); } if (SystemProperties.getBoolean( "persist.wm.debug.enable_pip_app_icon_overlay", true)) { "persist.wm.debug.enable_pip_app_icon_overlay", true) && hasTopActivityInfo) { animator.setAppIconContentOverlay( mContext, currentBounds, taskInfo.topActivityInfo); } else { Loading packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java +54 −37 Original line number Diff line number Diff line Loading @@ -96,9 +96,9 @@ public class RotationButtonController { private boolean mHoveringRotationSuggestion; private final AccessibilityManager mAccessibilityManager; private final TaskStackListenerImpl mTaskStackListener; private Consumer<Integer> mRotWatcherListener; private boolean mListenersRegistered = false; private boolean mRotationWatcherRegistered = false; private boolean mIsNavigationBarShowing; @SuppressLint("InlinedApi") private @WindowInsetsController.Behavior Loading Loading @@ -140,22 +140,7 @@ public class RotationButtonController { // We need this to be scheduled as early as possible to beat the redrawing of // window in response to the orientation change. mMainThreadHandler.postAtFrontOfQueue(() -> { // If the screen rotation changes while locked, potentially update lock to flow with // new screen rotation and hide any showing suggestions. boolean rotationLocked = isRotationLocked(); // The isVisible check makes the rotation button disappear when we are not locked // (e.g. for tabletop auto-rotate). if (rotationLocked || mRotationButton.isVisible()) { // Do not allow a change in rotation to set user rotation when docked. if (shouldOverrideUserLockPrefs(rotation) && rotationLocked && !mDocked) { setRotationLockedAtAngle(rotation); } setRotateSuggestionButtonState(false /* visible */, true /* forced */); } if (mRotWatcherListener != null) { mRotWatcherListener.accept(rotation); } onRotationWatcherChanged(rotation); }); } }; Loading Loading @@ -206,8 +191,11 @@ public class RotationButtonController { return mContext; } /** * Called during Taskbar initialization. */ public void init() { registerListeners(); registerListeners(true /* registerRotationWatcher */); if (mContext.getDisplay().getDisplayId() != DEFAULT_DISPLAY) { // Currently there is no accelerometer sensor on non-default display, disable fixed // rotation for non-default display Loading @@ -215,11 +203,14 @@ public class RotationButtonController { } } /** * Called during Taskbar uninitialization. */ public void onDestroy() { unregisterListeners(); } public void registerListeners() { public void registerListeners(boolean registerRotationWatcher) { if (mListenersRegistered || getContext().getPackageManager().hasSystemFeature(FEATURE_PC)) { return; } Loading @@ -229,16 +220,19 @@ public class RotationButtonController { updateDockedState(mContext.registerReceiver(mDockedReceiver, new IntentFilter(Intent.ACTION_DOCK_EVENT))); if (registerRotationWatcher) { try { WindowManagerGlobal.getWindowManagerService() .watchRotation(mRotationWatcher, DEFAULT_DISPLAY); mRotationWatcherRegistered = true; } catch (IllegalArgumentException e) { mListenersRegistered = false; Log.w(TAG, "RegisterListeners for the display failed"); Log.w(TAG, "RegisterListeners for the display failed", e); } catch (RemoteException e) { Log.e(TAG, "RegisterListeners caught a RemoteException", e); return; } } TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener); } Loading @@ -251,18 +245,17 @@ public class RotationButtonController { mListenersRegistered = false; mContext.unregisterReceiver(mDockedReceiver); if (mRotationWatcherRegistered) { try { WindowManagerGlobal.getWindowManagerService().removeRotationWatcher(mRotationWatcher); WindowManagerGlobal.getWindowManagerService().removeRotationWatcher( mRotationWatcher); } catch (RemoteException e) { Log.e(TAG, "UnregisterListeners caught a RemoteException", e); return; } TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener); } public void setRotationCallback(Consumer<Integer> watcher) { mRotWatcherListener = watcher; TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener); } public void setRotationLockedAtAngle(int rotationSuggestion) { Loading Loading @@ -427,6 +420,30 @@ public class RotationButtonController { } } /** * Called when the rotation watcher rotation changes, either from the watcher registered * internally in this class, or a signal propagated from NavBarHelper. */ public void onRotationWatcherChanged(int rotation) { if (!mListenersRegistered) { // Ignore if not registered return; } // If the screen rotation changes while locked, potentially update lock to flow with // new screen rotation and hide any showing suggestions. boolean rotationLocked = isRotationLocked(); // The isVisible check makes the rotation button disappear when we are not locked // (e.g. for tabletop auto-rotate). if (rotationLocked || mRotationButton.isVisible()) { // Do not allow a change in rotation to set user rotation when docked. if (shouldOverrideUserLockPrefs(rotation) && rotationLocked && !mDocked) { setRotationLockedAtAngle(rotation); } setRotateSuggestionButtonState(false /* visible */, true /* forced */); } } public void onDisable2FlagChanged(int state2) { final boolean rotateSuggestionsDisabled = hasDisable2RotateSuggestionFlag(state2); if (rotateSuggestionsDisabled) onRotationSuggestionsDisabled(); Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +22 −12 Original line number Diff line number Diff line Loading @@ -41,8 +41,8 @@ import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_DISMISS_BOUNCER import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.KeyguardStateController Loading @@ -60,7 +60,9 @@ import javax.inject.Provider * The ripple uses the accent color of the current theme. */ @CentralSurfacesScope class AuthRippleController @Inject constructor( class AuthRippleController @Inject constructor( private val centralSurfaces: CentralSurfaces, private val sysuiContext: Context, private val authController: AuthController, Loading @@ -70,18 +72,18 @@ class AuthRippleController @Inject constructor( private val wakefulnessLifecycle: WakefulnessLifecycle, private val commandRegistry: CommandRegistry, private val notificationShadeWindowController: NotificationShadeWindowController, private val bypassController: KeyguardBypassController, private val biometricUnlockController: BiometricUnlockController, private val udfpsControllerProvider: Provider<UdfpsController>, private val statusBarStateController: StatusBarStateController, private val featureFlags: FeatureFlags, private val logger: KeyguardLogger, rippleView: AuthRippleView? ) : ViewController<AuthRippleView>(rippleView), KeyguardStateController.Callback, ) : ViewController<AuthRippleView>(rippleView), KeyguardStateController.Callback, WakefulnessLifecycle.Observer { @VisibleForTesting internal var startLightRevealScrimOnKeyguardFadingAway = false @VisibleForTesting internal var startLightRevealScrimOnKeyguardFadingAway = false var lightRevealScrimAnimator: ValueAnimator? = null var fingerprintSensorLocation: Point? = null private var faceSensorLocation: Point? = null Loading @@ -90,6 +92,16 @@ class AuthRippleController @Inject constructor( private var udfpsController: UdfpsController? = null private var udfpsRadius: Float = -1f private val biometricModeListener = object : BiometricUnlockController.BiometricModeListener { override fun onModeChanged(mode: Int) { // isBiometricUnlock does not cover the scenario when biometrics unlocks // the device while the bouncer is showing. if (biometricUnlockController.isBiometricUnlock || mode == MODE_DISMISS_BOUNCER) { showUnlockRipple(biometricUnlockController.biometricType) } } } override fun onInit() { mView.setAlphaInDuration(sysuiContext.resources.getInteger( R.integer.auth_ripple_alpha_in_duration).toLong()) Loading @@ -106,6 +118,7 @@ class AuthRippleController @Inject constructor( keyguardStateController.addCallback(this) wakefulnessLifecycle.addObserver(this) commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() } biometricUnlockController.addBiometricModeListener(biometricModeListener) } @VisibleForTesting Loading @@ -117,6 +130,7 @@ class AuthRippleController @Inject constructor( keyguardStateController.removeCallback(this) wakefulnessLifecycle.removeObserver(this) commandRegistry.unregisterCommand("auth-ripple") biometricUnlockController.removeBiometricModeListener(biometricModeListener) notificationShadeWindowController.setForcePluginOpen(false, this) } Loading Loading @@ -147,9 +161,6 @@ class AuthRippleController @Inject constructor( showUnlockedRipple() } } else if (biometricSourceType == BiometricSourceType.FACE) { if (!bypassController.canBypass() && !authController.isUdfpsFingerDown) { return } faceSensorLocation?.let { mView.setSensorLocation(it) circleReveal = CircleReveal( Loading Loading @@ -271,7 +282,6 @@ class AuthRippleController @Inject constructor( if (biometricSourceType == BiometricSourceType.FINGERPRINT) { mView.fadeDwellRipple() } showUnlockRipple(biometricSourceType) } override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType) { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +3 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.window.TaskSnapshot; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.animation.Interpolators; import com.android.wm.shell.transition.Transitions; Loading Loading @@ -372,7 +373,8 @@ public class PipAnimationController { void setAppIconContentOverlay(Context context, Rect bounds, ActivityInfo activityInfo) { reattachContentOverlay( new PipContentOverlay.PipAppIconOverlay(context, bounds, activityInfo)); new PipContentOverlay.PipAppIconOverlay(context, bounds, () -> new IconProvider(context).getIcon(activityInfo))); } private void reattachContentOverlay(PipContentOverlay overlay) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java +9 −28 Original line number Diff line number Diff line Loading @@ -20,9 +20,6 @@ import static android.util.TypedValue.COMPLEX_UNIT_DIP; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; Loading @@ -35,6 +32,8 @@ import android.view.SurfaceControl; import android.view.SurfaceSession; import android.window.TaskSnapshot; import java.util.function.Supplier; /** * Represents the content overlay used during the entering PiP animation. */ Loading Loading @@ -177,7 +176,9 @@ public abstract class PipContentOverlay { /** A {@link PipContentOverlay} shows app icon on solid color background. */ public static final class PipAppIconOverlay extends PipContentOverlay { private static final String TAG = PipAppIconOverlay.class.getSimpleName(); private static final int APP_ICON_SIZE_DP = 48; // Align with the practical / reasonable launcher:iconImageSize as in // vendor/unbundled_google/packages/NexusLauncher/res/xml/device_profiles.xml private static final int APP_ICON_SIZE_DP = 66; private final Context mContext; private final int mAppIconSizePx; Loading @@ -187,14 +188,14 @@ public abstract class PipContentOverlay { private Bitmap mBitmap; public PipAppIconOverlay(Context context, Rect appBounds, ActivityInfo activityInfo) { public PipAppIconOverlay(Context context, Rect appBounds, Supplier<Drawable> iconSupplier) { mContext = context; mAppIconSizePx = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, APP_ICON_SIZE_DP, context.getResources().getDisplayMetrics()); mAppBounds = new Rect(appBounds); mBitmap = Bitmap.createBitmap(appBounds.width(), appBounds.height(), Bitmap.Config.ARGB_8888); prepareAppIconOverlay(activityInfo); prepareAppIconOverlay(iconSupplier); mLeash = new SurfaceControl.Builder(new SurfaceSession()) .setCallsite(TAG) .setName(LAYER_NAME) Loading Loading @@ -237,7 +238,7 @@ public abstract class PipContentOverlay { } } private void prepareAppIconOverlay(ActivityInfo activityInfo) { private void prepareAppIconOverlay(Supplier<Drawable> iconSupplier) { final Canvas canvas = new Canvas(); canvas.setBitmap(mBitmap); final TypedArray ta = mContext.obtainStyledAttributes(new int[] { Loading @@ -251,8 +252,7 @@ public abstract class PipContentOverlay { } finally { ta.recycle(); } final Drawable appIcon = loadActivityInfoIcon(activityInfo, mContext.getResources().getConfiguration().densityDpi); final Drawable appIcon = iconSupplier.get(); final Rect appIconBounds = new Rect( mAppBounds.centerX() - mAppIconSizePx / 2, mAppBounds.centerY() - mAppIconSizePx / 2, Loading @@ -262,24 +262,5 @@ public abstract class PipContentOverlay { appIcon.draw(canvas); mBitmap = mBitmap.copy(Bitmap.Config.HARDWARE, false /* mutable */); } // Copied from com.android.launcher3.icons.IconProvider#loadActivityInfoIcon private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) { final int iconRes = ai.getIconResource(); Drawable icon = null; // Get the preferred density icon from the app's resources if (density != 0 && iconRes != 0) { try { final Resources resources = mContext.getPackageManager() .getResourcesForApplication(ai.applicationInfo); icon = resources.getDrawableForDensity(iconRes, density); } catch (PackageManager.NameNotFoundException | Resources.NotFoundException exc) { } } // Get the default density icon if (icon == null) { icon = ai.loadIcon(mContext.getPackageManager()); } return icon; } } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +8 −1 Original line number Diff line number Diff line Loading @@ -803,8 +803,15 @@ public class PipTransition extends PipTransitionController { if (sourceHintRect == null) { // We use content overlay when there is no source rect hint to enter PiP use bounds // animation. // TODO(b/272819817): cleanup the null-check and extra logging. final boolean hasTopActivityInfo = taskInfo.topActivityInfo != null; if (!hasTopActivityInfo) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "%s: TaskInfo.topActivityInfo is null", TAG); } if (SystemProperties.getBoolean( "persist.wm.debug.enable_pip_app_icon_overlay", true)) { "persist.wm.debug.enable_pip_app_icon_overlay", true) && hasTopActivityInfo) { animator.setAppIconContentOverlay( mContext, currentBounds, taskInfo.topActivityInfo); } else { Loading
packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java +54 −37 Original line number Diff line number Diff line Loading @@ -96,9 +96,9 @@ public class RotationButtonController { private boolean mHoveringRotationSuggestion; private final AccessibilityManager mAccessibilityManager; private final TaskStackListenerImpl mTaskStackListener; private Consumer<Integer> mRotWatcherListener; private boolean mListenersRegistered = false; private boolean mRotationWatcherRegistered = false; private boolean mIsNavigationBarShowing; @SuppressLint("InlinedApi") private @WindowInsetsController.Behavior Loading Loading @@ -140,22 +140,7 @@ public class RotationButtonController { // We need this to be scheduled as early as possible to beat the redrawing of // window in response to the orientation change. mMainThreadHandler.postAtFrontOfQueue(() -> { // If the screen rotation changes while locked, potentially update lock to flow with // new screen rotation and hide any showing suggestions. boolean rotationLocked = isRotationLocked(); // The isVisible check makes the rotation button disappear when we are not locked // (e.g. for tabletop auto-rotate). if (rotationLocked || mRotationButton.isVisible()) { // Do not allow a change in rotation to set user rotation when docked. if (shouldOverrideUserLockPrefs(rotation) && rotationLocked && !mDocked) { setRotationLockedAtAngle(rotation); } setRotateSuggestionButtonState(false /* visible */, true /* forced */); } if (mRotWatcherListener != null) { mRotWatcherListener.accept(rotation); } onRotationWatcherChanged(rotation); }); } }; Loading Loading @@ -206,8 +191,11 @@ public class RotationButtonController { return mContext; } /** * Called during Taskbar initialization. */ public void init() { registerListeners(); registerListeners(true /* registerRotationWatcher */); if (mContext.getDisplay().getDisplayId() != DEFAULT_DISPLAY) { // Currently there is no accelerometer sensor on non-default display, disable fixed // rotation for non-default display Loading @@ -215,11 +203,14 @@ public class RotationButtonController { } } /** * Called during Taskbar uninitialization. */ public void onDestroy() { unregisterListeners(); } public void registerListeners() { public void registerListeners(boolean registerRotationWatcher) { if (mListenersRegistered || getContext().getPackageManager().hasSystemFeature(FEATURE_PC)) { return; } Loading @@ -229,16 +220,19 @@ public class RotationButtonController { updateDockedState(mContext.registerReceiver(mDockedReceiver, new IntentFilter(Intent.ACTION_DOCK_EVENT))); if (registerRotationWatcher) { try { WindowManagerGlobal.getWindowManagerService() .watchRotation(mRotationWatcher, DEFAULT_DISPLAY); mRotationWatcherRegistered = true; } catch (IllegalArgumentException e) { mListenersRegistered = false; Log.w(TAG, "RegisterListeners for the display failed"); Log.w(TAG, "RegisterListeners for the display failed", e); } catch (RemoteException e) { Log.e(TAG, "RegisterListeners caught a RemoteException", e); return; } } TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener); } Loading @@ -251,18 +245,17 @@ public class RotationButtonController { mListenersRegistered = false; mContext.unregisterReceiver(mDockedReceiver); if (mRotationWatcherRegistered) { try { WindowManagerGlobal.getWindowManagerService().removeRotationWatcher(mRotationWatcher); WindowManagerGlobal.getWindowManagerService().removeRotationWatcher( mRotationWatcher); } catch (RemoteException e) { Log.e(TAG, "UnregisterListeners caught a RemoteException", e); return; } TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener); } public void setRotationCallback(Consumer<Integer> watcher) { mRotWatcherListener = watcher; TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener); } public void setRotationLockedAtAngle(int rotationSuggestion) { Loading Loading @@ -427,6 +420,30 @@ public class RotationButtonController { } } /** * Called when the rotation watcher rotation changes, either from the watcher registered * internally in this class, or a signal propagated from NavBarHelper. */ public void onRotationWatcherChanged(int rotation) { if (!mListenersRegistered) { // Ignore if not registered return; } // If the screen rotation changes while locked, potentially update lock to flow with // new screen rotation and hide any showing suggestions. boolean rotationLocked = isRotationLocked(); // The isVisible check makes the rotation button disappear when we are not locked // (e.g. for tabletop auto-rotate). if (rotationLocked || mRotationButton.isVisible()) { // Do not allow a change in rotation to set user rotation when docked. if (shouldOverrideUserLockPrefs(rotation) && rotationLocked && !mDocked) { setRotationLockedAtAngle(rotation); } setRotateSuggestionButtonState(false /* visible */, true /* forced */); } } public void onDisable2FlagChanged(int state2) { final boolean rotateSuggestionsDisabled = hasDisable2RotateSuggestionFlag(state2); if (rotateSuggestionsDisabled) onRotationSuggestionsDisabled(); Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +22 −12 Original line number Diff line number Diff line Loading @@ -41,8 +41,8 @@ import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_DISMISS_BOUNCER import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.KeyguardStateController Loading @@ -60,7 +60,9 @@ import javax.inject.Provider * The ripple uses the accent color of the current theme. */ @CentralSurfacesScope class AuthRippleController @Inject constructor( class AuthRippleController @Inject constructor( private val centralSurfaces: CentralSurfaces, private val sysuiContext: Context, private val authController: AuthController, Loading @@ -70,18 +72,18 @@ class AuthRippleController @Inject constructor( private val wakefulnessLifecycle: WakefulnessLifecycle, private val commandRegistry: CommandRegistry, private val notificationShadeWindowController: NotificationShadeWindowController, private val bypassController: KeyguardBypassController, private val biometricUnlockController: BiometricUnlockController, private val udfpsControllerProvider: Provider<UdfpsController>, private val statusBarStateController: StatusBarStateController, private val featureFlags: FeatureFlags, private val logger: KeyguardLogger, rippleView: AuthRippleView? ) : ViewController<AuthRippleView>(rippleView), KeyguardStateController.Callback, ) : ViewController<AuthRippleView>(rippleView), KeyguardStateController.Callback, WakefulnessLifecycle.Observer { @VisibleForTesting internal var startLightRevealScrimOnKeyguardFadingAway = false @VisibleForTesting internal var startLightRevealScrimOnKeyguardFadingAway = false var lightRevealScrimAnimator: ValueAnimator? = null var fingerprintSensorLocation: Point? = null private var faceSensorLocation: Point? = null Loading @@ -90,6 +92,16 @@ class AuthRippleController @Inject constructor( private var udfpsController: UdfpsController? = null private var udfpsRadius: Float = -1f private val biometricModeListener = object : BiometricUnlockController.BiometricModeListener { override fun onModeChanged(mode: Int) { // isBiometricUnlock does not cover the scenario when biometrics unlocks // the device while the bouncer is showing. if (biometricUnlockController.isBiometricUnlock || mode == MODE_DISMISS_BOUNCER) { showUnlockRipple(biometricUnlockController.biometricType) } } } override fun onInit() { mView.setAlphaInDuration(sysuiContext.resources.getInteger( R.integer.auth_ripple_alpha_in_duration).toLong()) Loading @@ -106,6 +118,7 @@ class AuthRippleController @Inject constructor( keyguardStateController.addCallback(this) wakefulnessLifecycle.addObserver(this) commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() } biometricUnlockController.addBiometricModeListener(biometricModeListener) } @VisibleForTesting Loading @@ -117,6 +130,7 @@ class AuthRippleController @Inject constructor( keyguardStateController.removeCallback(this) wakefulnessLifecycle.removeObserver(this) commandRegistry.unregisterCommand("auth-ripple") biometricUnlockController.removeBiometricModeListener(biometricModeListener) notificationShadeWindowController.setForcePluginOpen(false, this) } Loading Loading @@ -147,9 +161,6 @@ class AuthRippleController @Inject constructor( showUnlockedRipple() } } else if (biometricSourceType == BiometricSourceType.FACE) { if (!bypassController.canBypass() && !authController.isUdfpsFingerDown) { return } faceSensorLocation?.let { mView.setSensorLocation(it) circleReveal = CircleReveal( Loading Loading @@ -271,7 +282,6 @@ class AuthRippleController @Inject constructor( if (biometricSourceType == BiometricSourceType.FINGERPRINT) { mView.fadeDwellRipple() } showUnlockRipple(biometricSourceType) } override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType) { Loading