Merge "[Unfold transition] Fully manage the vignette on the background thread" into tm-qpr-dev am: c514109b3b
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20725066 Change-Id: I6d7376119f00699a87b39f8be06995b03eeb2446 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -16,31 +16,25 @@
|
|||||||
|
|
||||||
package com.android.keyguard.mediator
|
package com.android.keyguard.mediator
|
||||||
|
|
||||||
|
import android.annotation.BinderThread
|
||||||
import android.os.Trace
|
import android.os.Trace
|
||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
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.unfold.SysUIUnfoldComponent
|
||||||
|
import com.android.systemui.util.concurrency.PendingTasksContainer
|
||||||
import com.android.systemui.util.kotlin.getOrNull
|
import com.android.systemui.util.kotlin.getOrNull
|
||||||
|
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Coordinates screen on/turning on animations for the KeyguardViewMediator. Specifically for
|
* 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
|
* 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
|
* should route back to the [com.android.systemui.keyguard.KeyguardService], which informs
|
||||||
* drawn.
|
* the system_server that keyguard has drawn.
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
class ScreenOnCoordinator @Inject constructor(
|
class ScreenOnCoordinator @Inject constructor(
|
||||||
screenLifecycle: ScreenLifecycle,
|
unfoldComponent: Optional<SysUIUnfoldComponent>
|
||||||
unfoldComponent: Optional<SysUIUnfoldComponent>,
|
) {
|
||||||
private val execution: Execution
|
|
||||||
) : ScreenLifecycle.Observer {
|
|
||||||
|
|
||||||
private val unfoldLightRevealAnimation = unfoldComponent.map(
|
private val unfoldLightRevealAnimation = unfoldComponent.map(
|
||||||
SysUIUnfoldComponent::getUnfoldLightRevealOverlayAnimation).getOrNull()
|
SysUIUnfoldComponent::getUnfoldLightRevealOverlayAnimation).getOrNull()
|
||||||
@@ -48,15 +42,12 @@ class ScreenOnCoordinator @Inject constructor(
|
|||||||
SysUIUnfoldComponent::getFoldAodAnimationController).getOrNull()
|
SysUIUnfoldComponent::getFoldAodAnimationController).getOrNull()
|
||||||
private val pendingTasks = PendingTasksContainer()
|
private val pendingTasks = PendingTasksContainer()
|
||||||
|
|
||||||
init {
|
|
||||||
screenLifecycle.addObserver(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When turning on, registers tasks that may need to run before invoking [onDrawn].
|
* When turning on, registers tasks that may need to run before invoking [onDrawn].
|
||||||
|
* This is called on a binder thread from [com.android.systemui.keyguard.KeyguardService].
|
||||||
*/
|
*/
|
||||||
override fun onScreenTurningOn(onDrawn: Runnable) {
|
@BinderThread
|
||||||
execution.assertIsMainThread()
|
fun onScreenTurningOn(onDrawn: Runnable) {
|
||||||
Trace.beginSection("ScreenOnCoordinator#onScreenTurningOn")
|
Trace.beginSection("ScreenOnCoordinator#onScreenTurningOn")
|
||||||
|
|
||||||
pendingTasks.reset()
|
pendingTasks.reset()
|
||||||
@@ -68,11 +59,13 @@ class ScreenOnCoordinator @Inject constructor(
|
|||||||
Trace.endSection()
|
Trace.endSection()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onScreenTurnedOn() {
|
/**
|
||||||
execution.assertIsMainThread()
|
* Called when screen is fully turned on and screen on blocker is removed.
|
||||||
|
* This is called on a binder thread from [com.android.systemui.keyguard.KeyguardService].
|
||||||
|
*/
|
||||||
|
@BinderThread
|
||||||
|
fun onScreenTurnedOn() {
|
||||||
foldAodAnimationController?.onScreenTurnedOn()
|
foldAodAnimationController?.onScreenTurnedOn()
|
||||||
|
|
||||||
pendingTasks.reset()
|
pendingTasks.reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,8 @@ package com.android.systemui.keyguard;
|
|||||||
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.android.internal.policy.IKeyguardDrawnCallback;
|
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -80,33 +77,10 @@ public class KeyguardLifecyclesDispatcher {
|
|||||||
private Handler mHandler = new Handler() {
|
private Handler mHandler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
final Object obj = msg.obj;
|
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case SCREEN_TURNING_ON:
|
case SCREEN_TURNING_ON:
|
||||||
Trace.beginSection("KeyguardLifecyclesDispatcher#SCREEN_TURNING_ON");
|
Trace.beginSection("KeyguardLifecyclesDispatcher#SCREEN_TURNING_ON");
|
||||||
final String onDrawWaitingTraceTag =
|
mScreenLifecycle.dispatchScreenTurningOn();
|
||||||
"Waiting for KeyguardDrawnCallback#onDrawn";
|
|
||||||
int traceCookie = System.identityHashCode(msg);
|
|
||||||
Trace.beginAsyncSection(onDrawWaitingTraceTag, traceCookie);
|
|
||||||
// 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 {
|
|
||||||
Trace.endAsyncSection(onDrawWaitingTraceTag, traceCookie);
|
|
||||||
((IKeyguardDrawnCallback) obj).onDrawn();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.w(TAG, "Exception calling onDrawn():", e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "KeyguardDrawnCallback#onDrawn() invoked > 1 times");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
break;
|
break;
|
||||||
case SCREEN_TURNED_ON:
|
case SCREEN_TURNED_ON:
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ import com.android.internal.policy.IKeyguardDrawnCallback;
|
|||||||
import com.android.internal.policy.IKeyguardExitCallback;
|
import com.android.internal.policy.IKeyguardExitCallback;
|
||||||
import com.android.internal.policy.IKeyguardService;
|
import com.android.internal.policy.IKeyguardService;
|
||||||
import com.android.internal.policy.IKeyguardStateCallback;
|
import com.android.internal.policy.IKeyguardStateCallback;
|
||||||
|
import com.android.keyguard.mediator.ScreenOnCoordinator;
|
||||||
import com.android.systemui.SystemUIApplication;
|
import com.android.systemui.SystemUIApplication;
|
||||||
import com.android.wm.shell.transition.ShellTransitions;
|
import com.android.wm.shell.transition.ShellTransitions;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
@@ -120,6 +121,7 @@ public class KeyguardService extends Service {
|
|||||||
|
|
||||||
private final KeyguardViewMediator mKeyguardViewMediator;
|
private final KeyguardViewMediator mKeyguardViewMediator;
|
||||||
private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
|
private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
|
||||||
|
private final ScreenOnCoordinator mScreenOnCoordinator;
|
||||||
private final ShellTransitions mShellTransitions;
|
private final ShellTransitions mShellTransitions;
|
||||||
|
|
||||||
private static int newModeToLegacyMode(int newMode) {
|
private static int newModeToLegacyMode(int newMode) {
|
||||||
@@ -283,10 +285,12 @@ public class KeyguardService extends Service {
|
|||||||
@Inject
|
@Inject
|
||||||
public KeyguardService(KeyguardViewMediator keyguardViewMediator,
|
public KeyguardService(KeyguardViewMediator keyguardViewMediator,
|
||||||
KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher,
|
KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher,
|
||||||
|
ScreenOnCoordinator screenOnCoordinator,
|
||||||
ShellTransitions shellTransitions) {
|
ShellTransitions shellTransitions) {
|
||||||
super();
|
super();
|
||||||
mKeyguardViewMediator = keyguardViewMediator;
|
mKeyguardViewMediator = keyguardViewMediator;
|
||||||
mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
|
mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
|
||||||
|
mScreenOnCoordinator = screenOnCoordinator;
|
||||||
mShellTransitions = shellTransitions;
|
mShellTransitions = shellTransitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,6 +587,31 @@ public class KeyguardService extends Service {
|
|||||||
checkPermission();
|
checkPermission();
|
||||||
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON,
|
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON,
|
||||||
callback);
|
callback);
|
||||||
|
|
||||||
|
final String onDrawWaitingTraceTag = "Waiting for KeyguardDrawnCallback#onDrawn";
|
||||||
|
final int traceCookie = System.identityHashCode(callback);
|
||||||
|
Trace.beginAsyncSection(onDrawWaitingTraceTag, traceCookie);
|
||||||
|
|
||||||
|
// Ensure the drawn callback is only ever called once
|
||||||
|
mScreenOnCoordinator.onScreenTurningOn(new Runnable() {
|
||||||
|
boolean mInvoked;
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (callback == null) return;
|
||||||
|
if (!mInvoked) {
|
||||||
|
mInvoked = true;
|
||||||
|
try {
|
||||||
|
Trace.endAsyncSection(onDrawWaitingTraceTag, traceCookie);
|
||||||
|
callback.onDrawn();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(TAG, "Exception calling onDrawn():", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "KeyguardDrawnCallback#onDrawn() invoked > 1 times");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,6 +620,7 @@ public class KeyguardService extends Service {
|
|||||||
Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
|
Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
|
||||||
checkPermission();
|
checkPermission();
|
||||||
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
|
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
|
||||||
|
mScreenOnCoordinator.onScreenTurnedOn();
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class LifecycleScreenStatusProvider @Inject constructor(screenLifecycle: ScreenL
|
|||||||
listeners.forEach(ScreenListener::onScreenTurningOff)
|
listeners.forEach(ScreenListener::onScreenTurningOff)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onScreenTurningOn(ignored: Runnable) {
|
override fun onScreenTurningOn() {
|
||||||
listeners.forEach(ScreenListener::onScreenTurningOn)
|
listeners.forEach(ScreenListener::onScreenTurningOn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ package com.android.systemui.keyguard;
|
|||||||
|
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
|
|
||||||
@@ -50,14 +48,9 @@ public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> impleme
|
|||||||
return mScreenState;
|
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);
|
setScreenState(SCREEN_TURNING_ON);
|
||||||
dispatch(Observer::onScreenTurningOn, onDrawn);
|
dispatch(Observer::onScreenTurningOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispatchScreenTurnedOn() {
|
public void dispatchScreenTurnedOn() {
|
||||||
@@ -87,12 +80,7 @@ public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface Observer {
|
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 onScreenTurnedOn() {}
|
||||||
default void onScreenTurningOff() {}
|
default void onScreenTurningOff() {}
|
||||||
default void onScreenTurnedOff() {}
|
default void onScreenTurnedOff() {}
|
||||||
|
|||||||
@@ -889,7 +889,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
|
|||||||
* Notifies the Launcher that screen is starting to turn on.
|
* Notifies the Launcher that screen is starting to turn on.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onScreenTurningOn(@NonNull Runnable ignored) {
|
public void onScreenTurningOn() {
|
||||||
try {
|
try {
|
||||||
if (mOverviewProxy != null) {
|
if (mOverviewProxy != null) {
|
||||||
mOverviewProxy.onScreenTurningOn();
|
mOverviewProxy.onScreenTurningOn();
|
||||||
|
|||||||
@@ -3575,7 +3575,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
|||||||
|
|
||||||
final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
|
final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
|
||||||
@Override
|
@Override
|
||||||
public void onScreenTurningOn(Runnable onDrawn) {
|
public void onScreenTurningOn() {
|
||||||
mFalsingCollector.onScreenTurningOn();
|
mFalsingCollector.onScreenTurningOn();
|
||||||
mNotificationPanelViewController.onScreenTurningOn();
|
mNotificationPanelViewController.onScreenTurningOn();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.systemui.unfold
|
package com.android.systemui.unfold
|
||||||
|
|
||||||
|
import android.annotation.BinderThread
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.hardware.devicestate.DeviceStateManager
|
import android.hardware.devicestate.DeviceStateManager
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
@@ -41,7 +42,6 @@ import java.util.function.Consumer
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,7 +52,7 @@ import kotlinx.coroutines.launch
|
|||||||
class FoldAodAnimationController
|
class FoldAodAnimationController
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
@Main private val executor: DelayableExecutor,
|
@Main private val mainExecutor: DelayableExecutor,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val deviceStateManager: DeviceStateManager,
|
private val deviceStateManager: DeviceStateManager,
|
||||||
private val wakefulnessLifecycle: WakefulnessLifecycle,
|
private val wakefulnessLifecycle: WakefulnessLifecycle,
|
||||||
@@ -89,7 +89,7 @@ constructor(
|
|||||||
override fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) {
|
override fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) {
|
||||||
this.centralSurfaces = centralSurfaces
|
this.centralSurfaces = centralSurfaces
|
||||||
|
|
||||||
deviceStateManager.registerCallback(executor, FoldListener())
|
deviceStateManager.registerCallback(mainExecutor, FoldListener())
|
||||||
wakefulnessLifecycle.addObserver(this)
|
wakefulnessLifecycle.addObserver(this)
|
||||||
|
|
||||||
// TODO(b/254878364): remove this call to NPVC.getView()
|
// TODO(b/254878364): remove this call to NPVC.getView()
|
||||||
@@ -139,7 +139,8 @@ constructor(
|
|||||||
* @param onReady callback when the animation is ready
|
* @param onReady callback when the animation is ready
|
||||||
* @see [com.android.systemui.keyguard.KeyguardViewMediator]
|
* @see [com.android.systemui.keyguard.KeyguardViewMediator]
|
||||||
*/
|
*/
|
||||||
fun onScreenTurningOn(onReady: Runnable) {
|
@BinderThread
|
||||||
|
fun onScreenTurningOn(onReady: Runnable) = mainExecutor.execute {
|
||||||
if (shouldPlayAnimation) {
|
if (shouldPlayAnimation) {
|
||||||
// The device was not dozing and going to sleep after folding, play the animation
|
// The device was not dozing and going to sleep after folding, play the animation
|
||||||
|
|
||||||
@@ -179,12 +180,13 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onScreenTurnedOn() {
|
@BinderThread
|
||||||
|
fun onScreenTurnedOn() = mainExecutor.execute {
|
||||||
if (shouldPlayAnimation) {
|
if (shouldPlayAnimation) {
|
||||||
cancelAnimation?.run()
|
cancelAnimation?.run()
|
||||||
|
|
||||||
// Post starting the animation to the next frame to avoid junk due to inset changes
|
// Post starting the animation to the next frame to avoid junk due to inset changes
|
||||||
cancelAnimation = executor.executeDelayed(startAnimationRunnable, /* delayMillis= */ 0)
|
cancelAnimation = mainExecutor.executeDelayed(startAnimationRunnable, /* delayMillis= */ 0)
|
||||||
shouldPlayAnimation = false
|
shouldPlayAnimation = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.unfold
|
package com.android.systemui.unfold
|
||||||
|
|
||||||
|
import android.annotation.BinderThread
|
||||||
import android.content.ContentResolver
|
import android.content.ContentResolver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.PixelFormat
|
import android.graphics.PixelFormat
|
||||||
@@ -34,9 +35,7 @@ import android.view.SurfaceControlViewHost
|
|||||||
import android.view.SurfaceSession
|
import android.view.SurfaceSession
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.view.WindowlessWindowManager
|
import android.view.WindowlessWindowManager
|
||||||
import com.android.systemui.dagger.qualifiers.Background
|
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.dagger.qualifiers.UiBackground
|
|
||||||
import com.android.systemui.statusbar.LightRevealEffect
|
import com.android.systemui.statusbar.LightRevealEffect
|
||||||
import com.android.systemui.statusbar.LightRevealScrim
|
import com.android.systemui.statusbar.LightRevealScrim
|
||||||
import com.android.systemui.statusbar.LinearLightRevealEffect
|
import com.android.systemui.statusbar.LinearLightRevealEffect
|
||||||
@@ -45,7 +44,7 @@ import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation.AddOverlayR
|
|||||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
|
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
|
||||||
import com.android.systemui.unfold.updates.RotationChangeProvider
|
import com.android.systemui.unfold.updates.RotationChangeProvider
|
||||||
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider.Companion.areAnimationsEnabled
|
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider.Companion.areAnimationsEnabled
|
||||||
import com.android.systemui.util.Assert.isMainThread
|
import com.android.systemui.util.concurrency.ThreadFactory
|
||||||
import com.android.systemui.util.traceSection
|
import com.android.systemui.util.traceSection
|
||||||
import com.android.wm.shell.displayareahelper.DisplayAreaHelper
|
import com.android.wm.shell.displayareahelper.DisplayAreaHelper
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
@@ -64,14 +63,16 @@ constructor(
|
|||||||
private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
|
private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
|
||||||
private val displayAreaHelper: Optional<DisplayAreaHelper>,
|
private val displayAreaHelper: Optional<DisplayAreaHelper>,
|
||||||
@Main private val executor: Executor,
|
@Main private val executor: Executor,
|
||||||
@UiBackground private val backgroundExecutor: Executor,
|
private val threadFactory: ThreadFactory,
|
||||||
@Background private val bgHandler: Handler,
|
|
||||||
private val rotationChangeProvider: RotationChangeProvider,
|
private val rotationChangeProvider: RotationChangeProvider,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val transitionListener = TransitionListener()
|
private val transitionListener = TransitionListener()
|
||||||
private val rotationWatcher = RotationWatcher()
|
private val rotationWatcher = RotationWatcher()
|
||||||
|
|
||||||
|
private lateinit var bgHandler: Handler
|
||||||
|
private lateinit var bgExecutor: Executor
|
||||||
|
|
||||||
private lateinit var wwm: WindowlessWindowManager
|
private lateinit var wwm: WindowlessWindowManager
|
||||||
private lateinit var unfoldedDisplayInfo: DisplayInfo
|
private lateinit var unfoldedDisplayInfo: DisplayInfo
|
||||||
private lateinit var overlayContainer: SurfaceControl
|
private lateinit var overlayContainer: SurfaceControl
|
||||||
@@ -84,7 +85,12 @@ constructor(
|
|||||||
private var currentRotation: Int = context.display!!.rotation
|
private var currentRotation: Int = context.display!!.rotation
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
deviceStateManager.registerCallback(executor, FoldListener())
|
// This method will be called only on devices where this animation is enabled,
|
||||||
|
// so normally this thread won't be created
|
||||||
|
bgHandler = threadFactory.buildHandlerOnNewThread(TAG)
|
||||||
|
bgExecutor = threadFactory.buildDelayableExecutorOnHandler(bgHandler)
|
||||||
|
|
||||||
|
deviceStateManager.registerCallback(bgExecutor, FoldListener())
|
||||||
unfoldTransitionProgressProvider.addCallback(transitionListener)
|
unfoldTransitionProgressProvider.addCallback(transitionListener)
|
||||||
rotationChangeProvider.addCallback(rotationWatcher)
|
rotationChangeProvider.addCallback(rotationWatcher)
|
||||||
|
|
||||||
@@ -122,20 +128,23 @@ constructor(
|
|||||||
* @param onOverlayReady callback when the overlay is drawn and visible on the screen
|
* @param onOverlayReady callback when the overlay is drawn and visible on the screen
|
||||||
* @see [com.android.systemui.keyguard.KeyguardViewMediator]
|
* @see [com.android.systemui.keyguard.KeyguardViewMediator]
|
||||||
*/
|
*/
|
||||||
|
@BinderThread
|
||||||
fun onScreenTurningOn(onOverlayReady: Runnable) {
|
fun onScreenTurningOn(onOverlayReady: Runnable) {
|
||||||
Trace.beginSection("UnfoldLightRevealOverlayAnimation#onScreenTurningOn")
|
executeInBackground {
|
||||||
try {
|
Trace.beginSection("$TAG#onScreenTurningOn")
|
||||||
// Add the view only if we are unfolding and this is the first screen on
|
try {
|
||||||
if (!isFolded && !isUnfoldHandled && contentResolver.areAnimationsEnabled()) {
|
// Add the view only if we are unfolding and this is the first screen on
|
||||||
executeInBackground { addOverlay(onOverlayReady, reason = UNFOLD) }
|
if (!isFolded && !isUnfoldHandled && contentResolver.areAnimationsEnabled()) {
|
||||||
isUnfoldHandled = true
|
addOverlay(onOverlayReady, reason = UNFOLD)
|
||||||
} else {
|
isUnfoldHandled = true
|
||||||
// No unfold transition, immediately report that overlay is ready
|
} else {
|
||||||
executeInBackground { ensureOverlayRemoved() }
|
// No unfold transition, immediately report that overlay is ready
|
||||||
onOverlayReady.run()
|
ensureOverlayRemoved()
|
||||||
|
onOverlayReady.run()
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Trace.endSection()
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
Trace.endSection()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,17 +163,18 @@ constructor(
|
|||||||
LightRevealScrim(context, null).apply {
|
LightRevealScrim(context, null).apply {
|
||||||
revealEffect = createLightRevealEffect()
|
revealEffect = createLightRevealEffect()
|
||||||
isScrimOpaqueChangedListener = Consumer {}
|
isScrimOpaqueChangedListener = Consumer {}
|
||||||
revealAmount = when (reason) {
|
revealAmount =
|
||||||
FOLD -> TRANSPARENT
|
when (reason) {
|
||||||
UNFOLD -> BLACK
|
FOLD -> TRANSPARENT
|
||||||
}
|
UNFOLD -> BLACK
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val params = getLayoutParams()
|
val params = getLayoutParams()
|
||||||
newRoot.setView(newView, params)
|
newRoot.setView(newView, params)
|
||||||
|
|
||||||
if (onOverlayReady != null) {
|
if (onOverlayReady != null) {
|
||||||
Trace.beginAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
|
Trace.beginAsyncSection("$TAG#relayout", 0)
|
||||||
|
|
||||||
newRoot.relayout(params) { transaction ->
|
newRoot.relayout(params) { transaction ->
|
||||||
val vsyncId = Choreographer.getSfInstance().vsyncId
|
val vsyncId = Choreographer.getSfInstance().vsyncId
|
||||||
@@ -179,8 +189,8 @@ constructor(
|
|||||||
|
|
||||||
transaction
|
transaction
|
||||||
.setFrameTimelineVsync(vsyncId + 1)
|
.setFrameTimelineVsync(vsyncId + 1)
|
||||||
.addTransactionCommittedListener(backgroundExecutor) {
|
.addTransactionCommittedListener(bgExecutor) {
|
||||||
Trace.endAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
|
Trace.endAsyncSection("$TAG#relayout", 0)
|
||||||
onOverlayReady.run()
|
onOverlayReady.run()
|
||||||
}
|
}
|
||||||
.apply()
|
.apply()
|
||||||
@@ -233,7 +243,8 @@ constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getUnfoldedDisplayInfo(): DisplayInfo =
|
private fun getUnfoldedDisplayInfo(): DisplayInfo =
|
||||||
displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)
|
displayManager
|
||||||
|
.getDisplays(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.map { DisplayInfo().apply { it.getDisplayInfo(this) } }
|
.map { DisplayInfo().apply { it.getDisplayInfo(this) } }
|
||||||
.filter { it.type == Display.TYPE_INTERNAL }
|
.filter { it.type == Display.TYPE_INTERNAL }
|
||||||
@@ -261,10 +272,10 @@ constructor(
|
|||||||
|
|
||||||
private inner class RotationWatcher : RotationChangeProvider.RotationListener {
|
private inner class RotationWatcher : RotationChangeProvider.RotationListener {
|
||||||
override fun onRotationChanged(newRotation: Int) {
|
override fun onRotationChanged(newRotation: Int) {
|
||||||
traceSection("UnfoldLightRevealOverlayAnimation#onRotationChanged") {
|
executeInBackground {
|
||||||
if (currentRotation != newRotation) {
|
traceSection("$TAG#onRotationChanged") {
|
||||||
currentRotation = newRotation
|
if (currentRotation != newRotation) {
|
||||||
executeInBackground {
|
currentRotation = newRotation
|
||||||
scrimView?.revealEffect = createLightRevealEffect()
|
scrimView?.revealEffect = createLightRevealEffect()
|
||||||
root?.relayout(getLayoutParams())
|
root?.relayout(getLayoutParams())
|
||||||
}
|
}
|
||||||
@@ -274,7 +285,10 @@ constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun executeInBackground(f: () -> Unit) {
|
private fun executeInBackground(f: () -> Unit) {
|
||||||
ensureInMainThread()
|
check(Looper.myLooper() != bgHandler.looper) {
|
||||||
|
"Trying to execute using background handler while already running" +
|
||||||
|
" in the background handler"
|
||||||
|
}
|
||||||
// The UiBackground executor is not used as it doesn't have a prepared looper.
|
// The UiBackground executor is not used as it doesn't have a prepared looper.
|
||||||
bgHandler.post(f)
|
bgHandler.post(f)
|
||||||
}
|
}
|
||||||
@@ -283,25 +297,25 @@ constructor(
|
|||||||
check(Looper.myLooper() == bgHandler.looper) { "Not being executed in the background!" }
|
check(Looper.myLooper() == bgHandler.looper) { "Not being executed in the background!" }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ensureInMainThread() {
|
|
||||||
isMainThread()
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class FoldListener :
|
private inner class FoldListener :
|
||||||
FoldStateListener(
|
FoldStateListener(
|
||||||
context,
|
context,
|
||||||
Consumer { isFolded ->
|
Consumer { isFolded ->
|
||||||
if (isFolded) {
|
if (isFolded) {
|
||||||
executeInBackground { ensureOverlayRemoved() }
|
ensureOverlayRemoved()
|
||||||
isUnfoldHandled = false
|
isUnfoldHandled = false
|
||||||
}
|
}
|
||||||
this.isFolded = isFolded
|
this.isFolded = isFolded
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
private enum class AddOverlayReason { FOLD, UNFOLD }
|
private enum class AddOverlayReason {
|
||||||
|
FOLD,
|
||||||
|
UNFOLD
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
const val TAG = "UnfoldLightRevealOverlayAnimation"
|
||||||
const val ROTATION_ANIMATION_OVERLAY_Z_INDEX = Integer.MAX_VALUE
|
const val ROTATION_ANIMATION_OVERLAY_Z_INDEX = Integer.MAX_VALUE
|
||||||
|
|
||||||
// Put the unfold overlay below the rotation animation screenshot to hide the moment
|
// Put the unfold overlay below the rotation animation screenshot to hide the moment
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ import java.util.concurrent.atomic.AtomicReference
|
|||||||
*/
|
*/
|
||||||
class PendingTasksContainer {
|
class PendingTasksContainer {
|
||||||
|
|
||||||
private var pendingTasksCount: AtomicInteger = AtomicInteger(0)
|
@Volatile
|
||||||
private var completionCallback: AtomicReference<Runnable> = AtomicReference()
|
private var pendingTasksCount = AtomicInteger(0)
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var completionCallback = AtomicReference<Runnable>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a task that we should wait for
|
* Registers a task that we should wait for
|
||||||
|
|||||||
@@ -52,8 +52,6 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {
|
|||||||
private lateinit var foldAodAnimationController: FoldAodAnimationController
|
private lateinit var foldAodAnimationController: FoldAodAnimationController
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var unfoldAnimation: UnfoldLightRevealOverlayAnimation
|
private lateinit var unfoldAnimation: UnfoldLightRevealOverlayAnimation
|
||||||
@Mock
|
|
||||||
private lateinit var screenLifecycle: ScreenLifecycle
|
|
||||||
@Captor
|
@Captor
|
||||||
private lateinit var readyCaptor: ArgumentCaptor<Runnable>
|
private lateinit var readyCaptor: ArgumentCaptor<Runnable>
|
||||||
|
|
||||||
@@ -69,13 +67,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {
|
|||||||
.thenReturn(foldAodAnimationController)
|
.thenReturn(foldAodAnimationController)
|
||||||
|
|
||||||
screenOnCoordinator = ScreenOnCoordinator(
|
screenOnCoordinator = ScreenOnCoordinator(
|
||||||
screenLifecycle,
|
|
||||||
Optional.of(unfoldComponent),
|
Optional.of(unfoldComponent),
|
||||||
FakeExecution()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Make sure screen events are registered to observe
|
|
||||||
verify(screenLifecycle).addObserver(screenOnCoordinator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -93,9 +86,7 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {
|
|||||||
fun testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
|
fun testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
|
||||||
// Recreate with empty unfoldComponent
|
// Recreate with empty unfoldComponent
|
||||||
screenOnCoordinator = ScreenOnCoordinator(
|
screenOnCoordinator = ScreenOnCoordinator(
|
||||||
screenLifecycle,
|
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
FakeExecution()
|
|
||||||
)
|
)
|
||||||
screenOnCoordinator.onScreenTurningOn(runnable)
|
screenOnCoordinator.onScreenTurningOn(runnable)
|
||||||
|
|
||||||
@@ -105,11 +96,11 @@ class ScreenOnCoordinatorTest : SysuiTestCase() {
|
|||||||
|
|
||||||
private fun onUnfoldOverlayReady() {
|
private fun onUnfoldOverlayReady() {
|
||||||
verify(unfoldAnimation).onScreenTurningOn(capture(readyCaptor))
|
verify(unfoldAnimation).onScreenTurningOn(capture(readyCaptor))
|
||||||
readyCaptor.getValue().run()
|
readyCaptor.value.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onFoldAodReady() {
|
private fun onFoldAodReady() {
|
||||||
verify(foldAodAnimationController).onScreenTurningOn(capture(readyCaptor))
|
verify(foldAodAnimationController).onScreenTurningOn(capture(readyCaptor))
|
||||||
readyCaptor.getValue().run()
|
readyCaptor.value.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,15 +58,15 @@ public class ScreenLifecycleTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void screenTurningOn() throws Exception {
|
public void screenTurningOn() throws Exception {
|
||||||
Runnable onDrawn = () -> {};
|
Runnable onDrawn = () -> {};
|
||||||
mScreen.dispatchScreenTurningOn(onDrawn);
|
mScreen.dispatchScreenTurningOn();
|
||||||
|
|
||||||
assertEquals(ScreenLifecycle.SCREEN_TURNING_ON, mScreen.getScreenState());
|
assertEquals(ScreenLifecycle.SCREEN_TURNING_ON, mScreen.getScreenState());
|
||||||
verify(mScreenObserverMock).onScreenTurningOn(onDrawn);
|
verify(mScreenObserverMock).onScreenTurningOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void screenTurnedOn() throws Exception {
|
public void screenTurnedOn() throws Exception {
|
||||||
mScreen.dispatchScreenTurningOn(null);
|
mScreen.dispatchScreenTurningOn();
|
||||||
mScreen.dispatchScreenTurnedOn();
|
mScreen.dispatchScreenTurnedOn();
|
||||||
|
|
||||||
assertEquals(ScreenLifecycle.SCREEN_ON, mScreen.getScreenState());
|
assertEquals(ScreenLifecycle.SCREEN_ON, mScreen.getScreenState());
|
||||||
@@ -75,7 +75,7 @@ public class ScreenLifecycleTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void screenTurningOff() throws Exception {
|
public void screenTurningOff() throws Exception {
|
||||||
mScreen.dispatchScreenTurningOn(null);
|
mScreen.dispatchScreenTurningOn();
|
||||||
mScreen.dispatchScreenTurnedOn();
|
mScreen.dispatchScreenTurnedOn();
|
||||||
mScreen.dispatchScreenTurningOff();
|
mScreen.dispatchScreenTurningOff();
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ public class ScreenLifecycleTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void screenTurnedOff() throws Exception {
|
public void screenTurnedOff() throws Exception {
|
||||||
mScreen.dispatchScreenTurningOn(null);
|
mScreen.dispatchScreenTurningOn();
|
||||||
mScreen.dispatchScreenTurnedOn();
|
mScreen.dispatchScreenTurnedOn();
|
||||||
mScreen.dispatchScreenTurningOff();
|
mScreen.dispatchScreenTurningOff();
|
||||||
mScreen.dispatchScreenTurnedOff();
|
mScreen.dispatchScreenTurnedOff();
|
||||||
|
|||||||
Reference in New Issue
Block a user