Merge "KeyguardViewMediator refactor"

This commit is contained in:
TreeHugger Robot
2022-01-05 20:33:13 +00:00
committed by Android (Google) Code Review
13 changed files with 334 additions and 234 deletions

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2022 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.keyguard.mediator
import android.os.Trace
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.ScreenLifecycle
import com.android.systemui.util.concurrency.Execution
import com.android.systemui.util.concurrency.PendingTasksContainer
import com.android.systemui.unfold.SysUIUnfoldComponent
import com.android.systemui.util.kotlin.getOrNull
import java.util.Optional
import javax.inject.Inject
/**
* Coordinates screen on/turning on animations for the KeyguardViewMediator. Specifically for
* screen on events, this will invoke the onDrawn Runnable after all tasks have completed. This
* should route back to the KeyguardService, which informs the system_server that keyguard has
* drawn.
*/
@SysUISingleton
class ScreenOnCoordinator @Inject constructor(
screenLifecycle: ScreenLifecycle,
unfoldComponent: Optional<SysUIUnfoldComponent>,
private val execution: Execution
) : ScreenLifecycle.Observer {
private val unfoldLightRevealAnimation = unfoldComponent.map(
SysUIUnfoldComponent::getUnfoldLightRevealOverlayAnimation).getOrNull()
private val foldAodAnimationController = unfoldComponent.map(
SysUIUnfoldComponent::getFoldAodAnimationController).getOrNull()
private val pendingTasks = PendingTasksContainer()
private var wakeAndUnlockingTask: Runnable? = null
var wakeAndUnlocking = false
set(value) {
if (!value && field) {
// When updating the value back to false, mark the task complete in order to
// callback onDrawn
wakeAndUnlockingTask?.run()
wakeAndUnlockingTask = null
}
field = value
}
init {
screenLifecycle.addObserver(this)
}
/**
* When turning on, registers tasks that may need to run before invoking [onDrawn].
*/
override fun onScreenTurningOn(onDrawn: Runnable) {
execution.assertIsMainThread()
Trace.beginSection("ScreenOnCoordinator#onScreenTurningOn")
pendingTasks.reset()
unfoldLightRevealAnimation?.onScreenTurningOn(pendingTasks.registerTask("unfold-reveal"))
foldAodAnimationController?.onScreenTurningOn(pendingTasks.registerTask("fold-to-aod"))
if (wakeAndUnlocking) {
wakeAndUnlockingTask = pendingTasks.registerTask("wake-and-unlocking")
}
pendingTasks.onTasksComplete { onDrawn.run() }
Trace.endSection()
}
override fun onScreenTurnedOn() {
execution.assertIsMainThread()
foldAodAnimationController?.onScreenTurnedOn()
pendingTasks.reset()
}
override fun onScreenTurnedOff() {
wakeAndUnlockingTask = null
}
}

View File

@@ -19,7 +19,10 @@ package com.android.systemui.keyguard;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.systemui.dagger.SysUISingleton;
import javax.inject.Inject;
@@ -39,6 +42,7 @@ public class KeyguardLifecyclesDispatcher {
static final int FINISHED_WAKING_UP = 5;
static final int STARTED_GOING_TO_SLEEP = 6;
static final int FINISHED_GOING_TO_SLEEP = 7;
private static final String TAG = "KeyguardLifecyclesDispatcher";
private final ScreenLifecycle mScreenLifecycle;
private final WakefulnessLifecycle mWakefulnessLifecycle;
@@ -65,12 +69,38 @@ public class KeyguardLifecyclesDispatcher {
message.sendToTarget();
}
/**
* @param what Message to send.
* @param object Object to send with the message
*/
void dispatch(int what, Object object) {
mHandler.obtainMessage(what, object).sendToTarget();
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
final Object obj = msg.obj;
switch (msg.what) {
case SCREEN_TURNING_ON:
mScreenLifecycle.dispatchScreenTurningOn();
// Ensure the drawn callback is only ever called once
mScreenLifecycle.dispatchScreenTurningOn(new Runnable() {
boolean mInvoked;
@Override
public void run() {
if (obj == null) return;
if (!mInvoked) {
mInvoked = true;
try {
((IKeyguardDrawnCallback) obj).onDrawn();
} catch (RemoteException e) {
Log.w(TAG, "Exception calling onDrawn():", e);
}
} else {
Log.w(TAG, "KeyguardDrawnCallback#onDrawn() invoked > 1 times");
}
}
});
break;
case SCREEN_TURNED_ON:
mScreenLifecycle.dispatchScreenTurnedOn();

View File

@@ -500,8 +500,8 @@ public class KeyguardService extends Service {
public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
checkPermission();
mKeyguardViewMediator.onScreenTurningOn(callback);
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON);
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON,
callback);
Trace.endSection();
}
@@ -509,7 +509,6 @@ public class KeyguardService extends Service {
public void onScreenTurnedOn() {
Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
checkPermission();
mKeyguardViewMediator.onScreenTurnedOn();
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
Trace.endSection();
}

View File

@@ -87,7 +87,6 @@ import androidx.annotation.Nullable;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.jank.InteractionJankMonitor.Configuration;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardStateCallback;
import com.android.internal.util.LatencyTracker;
@@ -99,6 +98,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.ViewMediatorCallback;
import com.android.keyguard.mediator.ScreenOnCoordinator;
import com.android.systemui.CoreStartable;
import com.android.systemui.Dumpable;
import com.android.systemui.animation.Interpolators;
@@ -122,15 +122,11 @@ import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.unfold.FoldAodAnimationController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation;
import com.android.systemui.util.DeviceConfigProxy;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Optional;
import java.util.concurrent.Executor;
import dagger.Lazy;
@@ -199,7 +195,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
private static final int RESET = 3;
private static final int VERIFY_UNLOCK = 4;
private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 5;
private static final int NOTIFY_SCREEN_TURNING_ON = 6;
private static final int KEYGUARD_DONE = 7;
private static final int KEYGUARD_DONE_DRAWING = 8;
private static final int SET_OCCLUDED = 9;
@@ -208,8 +203,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
private static final int START_KEYGUARD_EXIT_ANIM = 12;
private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 13;
private static final int NOTIFY_STARTED_WAKING_UP = 14;
private static final int NOTIFY_SCREEN_TURNED_ON = 15;
private static final int NOTIFY_SCREEN_TURNED_OFF = 16;
private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 17;
private static final int SYSTEM_READY = 18;
private static final int CANCEL_KEYGUARD_EXIT_ANIM = 19;
@@ -433,8 +426,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
private boolean mShowHomeOverLockscreen;
private boolean mInGestureNavigationMode;
private boolean mWakeAndUnlocking;
private Runnable mWakeAndUnlockingDrawnCallback;
private CharSequence mCustomMessage;
/**
@@ -811,14 +802,11 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
private DeviceConfigProxy mDeviceConfig;
private DozeParameters mDozeParameters;
private final Optional<UnfoldLightRevealOverlayAnimation> mUnfoldLightRevealAnimation;
private final Optional<FoldAodAnimationController> mFoldAodAnimationController;
private final PendingDrawnTasksContainer mPendingDrawnTasks = new PendingDrawnTasksContainer();
private final KeyguardStateController mKeyguardStateController;
private final Lazy<KeyguardUnlockAnimationController> mKeyguardUnlockAnimationControllerLazy;
private final InteractionJankMonitor mInteractionJankMonitor;
private boolean mWallpaperSupportsAmbientMode;
private ScreenOnCoordinator mScreenOnCoordinator;
/**
* Injected constructor. See {@link KeyguardModule}.
@@ -838,12 +826,12 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
NavigationModeController navigationModeController,
KeyguardDisplayManager keyguardDisplayManager,
DozeParameters dozeParameters,
Optional<SysUIUnfoldComponent> unfoldComponent,
SysuiStatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationControllerLazy,
ScreenOffAnimationController screenOffAnimationController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
ScreenOnCoordinator screenOnCoordinator,
InteractionJankMonitor interactionJankMonitor) {
super(context);
mFalsingCollector = falsingCollector;
@@ -860,6 +848,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mKeyguardDisplayManager = keyguardDisplayManager;
dumpManager.registerDumpable(getClass().getName(), this);
mDeviceConfig = deviceConfig;
mScreenOnCoordinator = screenOnCoordinator;
mShowHomeOverLockscreen = mDeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_SYSTEMUI,
NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN,
@@ -874,11 +863,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}));
mDozeParameters = dozeParameters;
mUnfoldLightRevealAnimation = unfoldComponent
.map(SysUIUnfoldComponent::getUnfoldLightRevealOverlayAnimation);
mFoldAodAnimationController = unfoldComponent
.map(SysUIUnfoldComponent::getFoldAodAnimationController);
mStatusBarStateController = statusBarStateController;
statusBarStateController.addCallback(this);
@@ -1071,7 +1055,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
synchronized (this) {
mDeviceInteractive = false;
mGoingToSleep = false;
mWakeAndUnlocking = false;
mScreenOnCoordinator.setWakeAndUnlocking(false);
mAnimatingScreenOff = mDozeParameters.shouldAnimateDozingChange();
resetKeyguardDonePendingLocked();
@@ -1249,20 +1233,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
Trace.endSection();
}
public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
Trace.beginSection("KeyguardViewMediator#onScreenTurningOn");
notifyScreenOn(callback);
Trace.endSection();
}
public void onScreenTurnedOn() {
Trace.beginSection("KeyguardViewMediator#onScreenTurnedOn");
notifyScreenTurnedOn();
Trace.endSection();
}
public void onScreenTurnedOff() {
notifyScreenTurnedOff();
mUpdateMonitor.dispatchScreenTurnedOff();
}
@@ -1654,24 +1625,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mHandler.sendEmptyMessage(NOTIFY_STARTED_WAKING_UP);
}
private void notifyScreenOn(IKeyguardDrawnCallback callback) {
if (DEBUG) Log.d(TAG, "notifyScreenOn");
Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNING_ON, callback);
mHandler.sendMessage(msg);
}
private void notifyScreenTurnedOn() {
if (DEBUG) Log.d(TAG, "notifyScreenTurnedOn");
Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNED_ON);
mHandler.sendMessage(msg);
}
private void notifyScreenTurnedOff() {
if (DEBUG) Log.d(TAG, "notifyScreenTurnedOff");
Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNED_OFF);
mHandler.sendMessage(msg);
}
/**
* Send message to keyguard telling it to show itself
* @see #handleShow
@@ -1832,21 +1785,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
case NOTIFY_FINISHED_GOING_TO_SLEEP:
handleNotifyFinishedGoingToSleep();
break;
case NOTIFY_SCREEN_TURNING_ON:
Trace.beginSection(
"KeyguardViewMediator#handleMessage NOTIFY_SCREEN_TURNING_ON");
handleNotifyScreenTurningOn((IKeyguardDrawnCallback) msg.obj);
Trace.endSection();
break;
case NOTIFY_SCREEN_TURNED_ON:
Trace.beginSection(
"KeyguardViewMediator#handleMessage NOTIFY_SCREEN_TURNED_ON");
handleNotifyScreenTurnedOn();
Trace.endSection();
break;
case NOTIFY_SCREEN_TURNED_OFF:
handleNotifyScreenTurnedOff();
break;
case NOTIFY_STARTED_WAKING_UP:
Trace.beginSection(
"KeyguardViewMediator#handleMessage NOTIFY_STARTED_WAKING_UP");
@@ -2075,7 +2013,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mHiding = false;
mKeyguardExitAnimationRunner = null;
mWakeAndUnlocking = false;
mScreenOnCoordinator.setWakeAndUnlocking(false);
mPendingLock = false;
setShowingLocked(true);
mKeyguardViewControllerLazy.get().show(options);
@@ -2107,12 +2045,14 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
int flags = 0;
if (mKeyguardViewControllerLazy.get().shouldDisableWindowAnimationsForUnlock()
|| mWakeAndUnlocking && !mWallpaperSupportsAmbientMode) {
|| mScreenOnCoordinator.getWakeAndUnlocking()
&& !mWallpaperSupportsAmbientMode) {
flags |= WindowManagerPolicyConstants
.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
}
if (mKeyguardViewControllerLazy.get().isGoingToNotificationShade()
|| mWakeAndUnlocking && mWallpaperSupportsAmbientMode) {
|| mScreenOnCoordinator.getWakeAndUnlocking()
&& mWallpaperSupportsAmbientMode) {
// When the wallpaper supports ambient mode, the scrim isn't fully opaque during
// wake and unlock and we should fade in the app on top of the wallpaper
flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
@@ -2223,14 +2163,13 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
IRemoteAnimationRunner runner = mKeyguardExitAnimationRunner;
mKeyguardExitAnimationRunner = null;
if (mWakeAndUnlocking && mWakeAndUnlockingDrawnCallback != null) {
if (mScreenOnCoordinator.getWakeAndUnlocking()) {
// Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
// the next draw from here so we don't have to wait for window manager to signal
// this to our ViewRootImpl.
mKeyguardViewControllerLazy.get().getViewRootImpl().setReportNextDraw();
mWakeAndUnlockingDrawnCallback.run();
mWakeAndUnlockingDrawnCallback = null;
mScreenOnCoordinator.setWakeAndUnlocking(false);
}
LatencyTracker.getInstance(mContext)
@@ -2354,7 +2293,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}
setShowingLocked(false);
mWakeAndUnlocking = false;
mScreenOnCoordinator.setWakeAndUnlocking(false);
mDismissCallbackRegistry.notifyDismissSucceeded();
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
@@ -2561,64 +2500,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
Trace.endSection();
}
private void handleNotifyScreenTurningOn(IKeyguardDrawnCallback callback) {
Trace.beginSection("KeyguardViewMediator#handleNotifyScreenTurningOn");
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn");
mPendingDrawnTasks.reset();
if (mUnfoldLightRevealAnimation.isPresent()) {
mUnfoldLightRevealAnimation.get()
.onScreenTurningOn(mPendingDrawnTasks.registerTask("unfold-reveal"));
}
if (mFoldAodAnimationController.isPresent()) {
mFoldAodAnimationController.get()
.onScreenTurningOn(mPendingDrawnTasks.registerTask("fold-to-aod"));
}
if (callback != null) {
if (mWakeAndUnlocking) {
mWakeAndUnlockingDrawnCallback =
mPendingDrawnTasks.registerTask("wake-and-unlocking");
}
}
mPendingDrawnTasks.onTasksComplete(() -> notifyDrawn(callback));
}
Trace.endSection();
}
private void handleNotifyScreenTurnedOn() {
Trace.beginSection("KeyguardViewMediator#handleNotifyScreenTurnedOn");
synchronized (this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOn");
mPendingDrawnTasks.reset();
}
Trace.endSection();
}
private void handleNotifyScreenTurnedOff() {
synchronized (this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff");
mWakeAndUnlockingDrawnCallback = null;
}
}
private void notifyDrawn(final IKeyguardDrawnCallback callback) {
Trace.beginSection("KeyguardViewMediator#notifyDrawn");
try {
if (callback != null) {
callback.onDrawn();
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception calling onDrawn():", e);
}
Trace.endSection();
}
private void resetKeyguardDonePendingLocked() {
mKeyguardDonePending = false;
mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT);
@@ -2642,7 +2523,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
public void onWakeAndUnlocking() {
Trace.beginSection("KeyguardViewMediator#onWakeAndUnlocking");
mWakeAndUnlocking = true;
mScreenOnCoordinator.setWakeAndUnlocking(true);
keyguardDone();
Trace.endSection();
}
@@ -2777,9 +2658,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
pw.print(" mHideAnimationRun: "); pw.println(mHideAnimationRun);
pw.print(" mPendingReset: "); pw.println(mPendingReset);
pw.print(" mPendingLock: "); pw.println(mPendingLock);
pw.print(" mPendingDrawnTasks: "); pw.println(mPendingDrawnTasks.getPendingCount());
pw.print(" mWakeAndUnlocking: "); pw.println(mWakeAndUnlocking);
pw.print(" mDrawnCallback: "); pw.println(mWakeAndUnlockingDrawnCallback);
pw.print(" wakeAndUnlocking: "); pw.println(mScreenOnCoordinator.getWakeAndUnlocking());
}
/**
@@ -2853,7 +2732,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}
private void setShowingLocked(boolean showing, boolean forceCallbacks) {
final boolean aodShowing = mDozing && !mWakeAndUnlocking;
final boolean aodShowing = mDozing && !mScreenOnCoordinator.getWakeAndUnlocking();
final boolean notifyDefaultDisplayCallbacks = showing != mShowing
|| aodShowing != mAodShowing || forceCallbacks;
mShowing = showing;

View File

@@ -20,6 +20,7 @@ import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
@@ -42,4 +43,13 @@ public class Lifecycle<T> {
consumer.accept(mObservers.get(i));
}
}
/**
* Will dispatch the consumer to the observer, along with a single argument of type<U>.
*/
public <U> void dispatch(BiConsumer<T, U> biConsumer, U arg) {
for (int i = 0; i < mObservers.size(); i++) {
biConsumer.accept(mObservers.get(i), arg);
}
}
}

View File

@@ -18,6 +18,8 @@ package com.android.systemui.keyguard;
import android.os.Trace;
import androidx.annotation.NonNull;
import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;
@@ -49,9 +51,14 @@ public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> impleme
return mScreenState;
}
public void dispatchScreenTurningOn() {
/**
* Dispatch screen turning on events to the registered observers
*
* @param onDrawn Invoke to notify the caller that the event has been processed
*/
public void dispatchScreenTurningOn(@NonNull Runnable onDrawn) {
setScreenState(SCREEN_TURNING_ON);
dispatch(Observer::onScreenTurningOn);
dispatch(Observer::onScreenTurningOn, onDrawn);
}
public void dispatchScreenTurnedOn() {
@@ -81,7 +88,12 @@ public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> impleme
}
public interface Observer {
default void onScreenTurningOn() {}
/**
* Receive the screen turning on event
*
* @param onDrawn Invoke to notify the caller that the event has been processed
*/
default void onScreenTurningOn(@NonNull Runnable onDrawn) {}
default void onScreenTurnedOn() {}
default void onScreenTurningOff() {}
default void onScreenTurnedOff() {}

View File

@@ -31,6 +31,7 @@ import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.keyguard.mediator.ScreenOnCoordinator;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.classifier.FalsingModule;
@@ -50,11 +51,9 @@ import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.sensors.AsyncSensorManager;
import java.util.Optional;
import java.util.concurrent.Executor;
import dagger.Lazy;
@@ -93,12 +92,12 @@ public class KeyguardModule {
NavigationModeController navigationModeController,
KeyguardDisplayManager keyguardDisplayManager,
DozeParameters dozeParameters,
Optional<SysUIUnfoldComponent> unfoldComponent,
SysuiStatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
Lazy<KeyguardUnlockAnimationController> keyguardUnlockAnimationController,
ScreenOffAnimationController screenOffAnimationController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
ScreenOnCoordinator screenOnCoordinator,
InteractionJankMonitor interactionJankMonitor) {
return new KeyguardViewMediator(
context,
@@ -117,12 +116,12 @@ public class KeyguardModule {
navigationModeController,
keyguardDisplayManager,
dozeParameters,
unfoldComponent,
statusBarStateController,
keyguardStateController,
keyguardUnlockAnimationController,
screenOffAnimationController,
notificationShadeDepthController,
screenOnCoordinator,
interactionJankMonitor
);
}

View File

@@ -3592,7 +3592,7 @@ public class StatusBar extends CoreStartable implements
final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
@Override
public void onScreenTurningOn() {
public void onScreenTurningOn(Runnable onDrawn) {
mFalsingCollector.onScreenTurningOn();
mNotificationPanelViewController.onScreenTurningOn();
}

View File

@@ -19,7 +19,6 @@ package com.android.systemui.unfold
import android.os.PowerManager
import android.provider.Settings
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.ScreenLifecycle
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.phone.ScreenOffAnimation
@@ -36,12 +35,10 @@ import javax.inject.Inject
*/
@SysUIUnfoldScope
class FoldAodAnimationController @Inject constructor(
private val screenLifecycle: ScreenLifecycle,
private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>,
private val wakefulnessLifecycle: WakefulnessLifecycle,
private val globalSettings: GlobalSettings
) : ScreenLifecycle.Observer,
CallbackController<FoldAodAnimationStatus>,
) : CallbackController<FoldAodAnimationStatus>,
ScreenOffAnimation,
WakefulnessLifecycle.Observer {
@@ -58,7 +55,6 @@ class FoldAodAnimationController @Inject constructor(
override fun initialize(statusBar: StatusBar, lightRevealScrim: LightRevealScrim) {
this.statusBar = statusBar
screenLifecycle.addObserver(this)
wakefulnessLifecycle.addObserver(this)
}
@@ -123,7 +119,7 @@ class FoldAodAnimationController @Inject constructor(
}
}
override fun onScreenTurnedOn() {
fun onScreenTurnedOn() {
if (shouldPlayAnimation) {
statusBar.notificationPanelViewController.startFoldToAodAnimation {
// End action

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.systemui.keyguard
package com.android.systemui.util.concurrency
import android.os.Trace
import java.util.concurrent.atomic.AtomicInteger
@@ -23,9 +23,9 @@ import java.util.concurrent.atomic.AtomicReference
/**
* Allows to wait for multiple callbacks and notify when the last one is executed
*/
class PendingDrawnTasksContainer {
class PendingTasksContainer {
private var pendingDrawnTasksCount: AtomicInteger = AtomicInteger(0)
private var pendingTasksCount: AtomicInteger = AtomicInteger(0)
private var completionCallback: AtomicReference<Runnable> = AtomicReference()
/**
@@ -33,19 +33,19 @@ class PendingDrawnTasksContainer {
* @return a runnable that should be invoked when the task is finished
*/
fun registerTask(name: String): Runnable {
pendingDrawnTasksCount.incrementAndGet()
pendingTasksCount.incrementAndGet()
if (ENABLE_TRACE) {
Trace.beginAsyncSection("PendingDrawnTasksContainer#$name", 0)
Trace.beginAsyncSection("PendingTasksContainer#$name", 0)
}
return Runnable {
if (pendingDrawnTasksCount.decrementAndGet() == 0) {
if (pendingTasksCount.decrementAndGet() == 0) {
val onComplete = completionCallback.getAndSet(null)
onComplete?.run()
if (ENABLE_TRACE) {
Trace.endAsyncSection("PendingDrawnTasksContainer#$name", 0)
Trace.endAsyncSection("PendingTasksContainer#$name", 0)
}
}
}
@@ -57,7 +57,7 @@ class PendingDrawnTasksContainer {
fun reset() {
// Create new objects in case if there are pending callbacks from the previous invocations
completionCallback = AtomicReference()
pendingDrawnTasksCount = AtomicInteger(0)
pendingTasksCount = AtomicInteger(0)
}
/**
@@ -67,7 +67,7 @@ class PendingDrawnTasksContainer {
fun onTasksComplete(onComplete: Runnable) {
completionCallback.set(onComplete)
if (pendingDrawnTasksCount.get() == 0) {
if (pendingTasksCount.get() == 0) {
val currentOnComplete = completionCallback.getAndSet(null)
currentOnComplete?.run()
}
@@ -76,7 +76,7 @@ class PendingDrawnTasksContainer {
/**
* Returns current pending tasks count
*/
fun getPendingCount(): Int = pendingDrawnTasksCount.get()
fun getPendingCount(): Int = pendingTasksCount.get()
}
private const val ENABLE_TRACE = false

View File

@@ -0,0 +1,136 @@
/*
* Copyright (C) 2021 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.keyguard.mediator
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.ScreenLifecycle
import com.android.systemui.unfold.FoldAodAnimationController
import com.android.systemui.unfold.SysUIUnfoldComponent
import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation
import com.android.systemui.util.concurrency.FakeExecution
import com.android.systemui.util.mockito.capture
import java.util.Optional
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.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
class ScreenOnCoordinatorTest : SysuiTestCase() {
@Mock
private lateinit var runnable: Runnable
@Mock
private lateinit var unfoldComponent: SysUIUnfoldComponent
@Mock
private lateinit var foldAodAnimationController: FoldAodAnimationController
@Mock
private lateinit var unfoldAnimation: UnfoldLightRevealOverlayAnimation
@Mock
private lateinit var screenLifecycle: ScreenLifecycle
@Captor
private lateinit var readyCaptor: ArgumentCaptor<Runnable>
private lateinit var screenOnCoordinator: ScreenOnCoordinator
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
`when`(unfoldComponent.getUnfoldLightRevealOverlayAnimation())
.thenReturn(unfoldAnimation)
`when`(unfoldComponent.getFoldAodAnimationController())
.thenReturn(foldAodAnimationController)
screenOnCoordinator = ScreenOnCoordinator(
screenLifecycle,
Optional.of(unfoldComponent),
FakeExecution()
)
// Make sure screen events are registered to observe
verify(screenLifecycle).addObserver(screenOnCoordinator)
}
@Test
fun testUnfoldTransitionEnabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
screenOnCoordinator.onScreenTurningOn(runnable)
onUnfoldOverlayReady()
onFoldAodReady()
// Should be called when both unfold overlay and keyguard drawn ready
verify(runnable).run()
}
@Test
fun testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
// Recreate with empty unfoldComponent
screenOnCoordinator = ScreenOnCoordinator(
screenLifecycle,
Optional.empty(),
FakeExecution()
)
screenOnCoordinator.onScreenTurningOn(runnable)
// Should be called when only keyguard drawn
verify(runnable).run()
}
@Test
fun testWakeAndUnlockDelaysRunnable() {
// GIVEN wakeAndUnlocking has been set to true
screenOnCoordinator.wakeAndUnlocking = true
// WHEN the screen turns on and two tasks have completed
screenOnCoordinator.onScreenTurningOn(runnable)
onUnfoldOverlayReady()
onFoldAodReady()
// THEN the runnable should not have run yet
verify(runnable, never()).run()
// WHEN the value of wakeAndUnlocking changes
screenOnCoordinator.wakeAndUnlocking = false
// THEN the runnable should have run, as it is the last task to complete
verify(runnable).run()
}
private fun onUnfoldOverlayReady() {
verify(unfoldAnimation).onScreenTurningOn(capture(readyCaptor))
readyCaptor.getValue().run()
}
private fun onFoldAodReady() {
verify(foldAodAnimationController).onScreenTurningOn(capture(readyCaptor))
readyCaptor.getValue().run()
}
}

View File

@@ -34,7 +34,6 @@ import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -42,10 +41,10 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.mediator.ScreenOnCoordinator;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollectorFake;
@@ -58,9 +57,6 @@ import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.unfold.FoldAodAnimationController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -69,13 +65,9 @@ import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Optional;
import java.util.function.Function;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
@@ -95,36 +87,25 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock NavigationModeController mNavigationModeController;
private @Mock KeyguardDisplayManager mKeyguardDisplayManager;
private @Mock DozeParameters mDozeParameters;
private @Mock SysUIUnfoldComponent mSysUIUnfoldComponent;
private @Mock UnfoldLightRevealOverlayAnimation mUnfoldAnimation;
private @Mock SysuiStatusBarStateController mStatusBarStateController;
private @Mock KeyguardStateController mKeyguardStateController;
private @Mock NotificationShadeDepthController mNotificationShadeDepthController;
private @Mock KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private @Mock ScreenOffAnimationController mScreenOffAnimationController;
private @Mock FoldAodAnimationController mFoldAodAnimationController;
private @Mock IKeyguardDrawnCallback mKeyguardDrawnCallback;
private @Mock InteractionJankMonitor mInteractionJankMonitor;
private @Mock ScreenOnCoordinator mScreenOnCoordinator;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private Optional<SysUIUnfoldComponent> mSysUiUnfoldComponentOptional;
private FalsingCollectorFake mFalsingCollector;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mFalsingCollector = new FalsingCollectorFake();
mSysUiUnfoldComponentOptional = Optional.of(mSysUIUnfoldComponent);
when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
when(mPowerManager.newWakeLock(anyInt(), any())).thenReturn(mock(WakeLock.class));
when(mSysUIUnfoldComponent.getUnfoldLightRevealOverlayAnimation())
.thenReturn(mUnfoldAnimation);
when(mSysUIUnfoldComponent.getFoldAodAnimationController())
.thenReturn(mFoldAodAnimationController);
when(mInteractionJankMonitor.begin(any(), anyInt())).thenReturn(true);
when(mInteractionJankMonitor.end(anyInt())).thenReturn(true);
@@ -150,33 +131,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
verify(mStatusBarKeyguardViewManager).setKeyguardGoingAwayState(eq(false));
}
@Test
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public void testUnfoldTransitionEnabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback()
throws RemoteException {
mViewMediator.onScreenTurningOn(mKeyguardDrawnCallback);
TestableLooper.get(this).processAllMessages();
onUnfoldOverlayReady();
onFoldAodReady();
// Should be called when both unfold overlay and keyguard drawn ready
verify(mKeyguardDrawnCallback).onDrawn();
}
@Test
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public void testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback()
throws RemoteException {
mSysUiUnfoldComponentOptional = Optional.empty();
createAndStartViewMediator();
mViewMediator.onScreenTurningOn(mKeyguardDrawnCallback);
TestableLooper.get(this).processAllMessages();
// Should be called when only keyguard drawn
verify(mKeyguardDrawnCallback).onDrawn();
}
@Test
public void testIsAnimatingScreenOff() {
when(mDozeParameters.shouldControlUnlockedScreenOff()).thenReturn(true);
@@ -219,20 +173,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
verify(mStatusBarKeyguardViewManager, atLeast(1)).show(null);
}
private void onUnfoldOverlayReady() {
ArgumentCaptor<Runnable> overlayReadyCaptor = ArgumentCaptor.forClass(Runnable.class);
verify(mUnfoldAnimation).onScreenTurningOn(overlayReadyCaptor.capture());
overlayReadyCaptor.getValue().run();
TestableLooper.get(this).processAllMessages();
}
private void onFoldAodReady() {
ArgumentCaptor<Runnable> ready = ArgumentCaptor.forClass(Runnable.class);
verify(mFoldAodAnimationController).onScreenTurningOn(ready.capture());
ready.getValue().run();
TestableLooper.get(this).processAllMessages();
}
private void createAndStartViewMediator() {
mViewMediator = new KeyguardViewMediator(
mContext,
@@ -251,12 +191,12 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mNavigationModeController,
mKeyguardDisplayManager,
mDozeParameters,
mSysUiUnfoldComponentOptional,
mStatusBarStateController,
mKeyguardStateController,
() -> mKeyguardUnlockAnimationController,
mScreenOffAnimationController,
() -> mNotificationShadeDepthController,
mScreenOnCoordinator,
mInteractionJankMonitor);
mViewMediator.start();
}

View File

@@ -57,15 +57,16 @@ public class ScreenLifecycleTest extends SysuiTestCase {
@Test
public void screenTurningOn() throws Exception {
mScreen.dispatchScreenTurningOn();
Runnable onDrawn = () -> {};
mScreen.dispatchScreenTurningOn(onDrawn);
assertEquals(ScreenLifecycle.SCREEN_TURNING_ON, mScreen.getScreenState());
verify(mScreenObserverMock).onScreenTurningOn();
verify(mScreenObserverMock).onScreenTurningOn(onDrawn);
}
@Test
public void screenTurnedOn() throws Exception {
mScreen.dispatchScreenTurningOn();
mScreen.dispatchScreenTurningOn(null);
mScreen.dispatchScreenTurnedOn();
assertEquals(ScreenLifecycle.SCREEN_ON, mScreen.getScreenState());
@@ -74,7 +75,7 @@ public class ScreenLifecycleTest extends SysuiTestCase {
@Test
public void screenTurningOff() throws Exception {
mScreen.dispatchScreenTurningOn();
mScreen.dispatchScreenTurningOn(null);
mScreen.dispatchScreenTurnedOn();
mScreen.dispatchScreenTurningOff();
@@ -84,7 +85,7 @@ public class ScreenLifecycleTest extends SysuiTestCase {
@Test
public void screenTurnedOff() throws Exception {
mScreen.dispatchScreenTurningOn();
mScreen.dispatchScreenTurningOn(null);
mScreen.dispatchScreenTurnedOn();
mScreen.dispatchScreenTurningOff();
mScreen.dispatchScreenTurnedOff();
@@ -97,4 +98,4 @@ public class ScreenLifecycleTest extends SysuiTestCase {
public void dump() throws Exception {
mScreen.dump(null, new PrintWriter(new ByteArrayOutputStream()), new String[0]);
}
}
}