Merge "Inject a handler for Keyguard transitions" into udc-dev
This commit is contained in:
@@ -77,6 +77,8 @@ import com.android.wm.shell.pip.PipMediaController;
|
|||||||
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
|
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
|
||||||
import com.android.wm.shell.pip.PipUiEventLogger;
|
import com.android.wm.shell.pip.PipUiEventLogger;
|
||||||
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitions;
|
||||||
import com.android.wm.shell.recents.RecentTasks;
|
import com.android.wm.shell.recents.RecentTasks;
|
||||||
import com.android.wm.shell.recents.RecentTasksController;
|
import com.android.wm.shell.recents.RecentTasksController;
|
||||||
import com.android.wm.shell.recents.RecentsTransitionHandler;
|
import com.android.wm.shell.recents.RecentsTransitionHandler;
|
||||||
@@ -561,6 +563,28 @@ public abstract class WMShellBaseModule {
|
|||||||
return new TaskViewTransitions(transitions);
|
return new TaskViewTransitions(transitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Keyguard transitions (optional feature)
|
||||||
|
//
|
||||||
|
|
||||||
|
@WMSingleton
|
||||||
|
@Provides
|
||||||
|
static KeyguardTransitionHandler provideKeyguardTransitionHandler(
|
||||||
|
ShellInit shellInit,
|
||||||
|
Transitions transitions,
|
||||||
|
@ShellMainThread Handler mainHandler,
|
||||||
|
@ShellMainThread ShellExecutor mainExecutor) {
|
||||||
|
return new KeyguardTransitionHandler(
|
||||||
|
shellInit, transitions, mainHandler, mainExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@WMSingleton
|
||||||
|
@Provides
|
||||||
|
static KeyguardTransitions provideKeyguardTransitions(
|
||||||
|
KeyguardTransitionHandler handler) {
|
||||||
|
return handler.asKeyguardTransitions();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Display areas
|
// Display areas
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import com.android.wm.shell.freeform.FreeformComponents;
|
|||||||
import com.android.wm.shell.freeform.FreeformTaskListener;
|
import com.android.wm.shell.freeform.FreeformTaskListener;
|
||||||
import com.android.wm.shell.freeform.FreeformTaskTransitionHandler;
|
import com.android.wm.shell.freeform.FreeformTaskTransitionHandler;
|
||||||
import com.android.wm.shell.freeform.FreeformTaskTransitionObserver;
|
import com.android.wm.shell.freeform.FreeformTaskTransitionObserver;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
|
||||||
import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
|
import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
|
||||||
import com.android.wm.shell.onehanded.OneHandedController;
|
import com.android.wm.shell.onehanded.OneHandedController;
|
||||||
import com.android.wm.shell.pip.Pip;
|
import com.android.wm.shell.pip.Pip;
|
||||||
@@ -532,9 +533,10 @@ public abstract class WMShellModule {
|
|||||||
Optional<SplitScreenController> splitScreenOptional,
|
Optional<SplitScreenController> splitScreenOptional,
|
||||||
Optional<PipTouchHandler> pipTouchHandlerOptional,
|
Optional<PipTouchHandler> pipTouchHandlerOptional,
|
||||||
Optional<RecentsTransitionHandler> recentsTransitionHandler,
|
Optional<RecentsTransitionHandler> recentsTransitionHandler,
|
||||||
|
KeyguardTransitionHandler keyguardTransitionHandler,
|
||||||
Transitions transitions) {
|
Transitions transitions) {
|
||||||
return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional,
|
return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional,
|
||||||
pipTouchHandlerOptional, recentsTransitionHandler);
|
pipTouchHandlerOptional, recentsTransitionHandler, keyguardTransitionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@WMSingleton
|
@WMSingleton
|
||||||
|
|||||||
@@ -0,0 +1,274 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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.wm.shell.keyguard;
|
||||||
|
|
||||||
|
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
|
||||||
|
import static android.view.WindowManager.TRANSIT_CLOSE;
|
||||||
|
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
|
||||||
|
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
|
||||||
|
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
|
||||||
|
import static android.view.WindowManager.TRANSIT_NONE;
|
||||||
|
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||||
|
import static android.view.WindowManager.TRANSIT_SLEEP;
|
||||||
|
import static android.view.WindowManager.TRANSIT_TO_BACK;
|
||||||
|
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||||
|
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
|
||||||
|
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
|
||||||
|
import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD;
|
||||||
|
|
||||||
|
import static com.android.wm.shell.util.TransitionUtil.isOpeningType;
|
||||||
|
import static com.android.wm.shell.util.TransitionUtil.isClosingType;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.SurfaceControl;
|
||||||
|
import android.window.IRemoteTransition;
|
||||||
|
import android.window.IRemoteTransitionFinishedCallback;
|
||||||
|
import android.window.TransitionInfo;
|
||||||
|
import android.window.TransitionRequestInfo;
|
||||||
|
import android.window.WindowContainerTransaction;
|
||||||
|
|
||||||
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
|
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||||
|
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||||
|
import com.android.wm.shell.sysui.ShellInit;
|
||||||
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
import com.android.wm.shell.transition.Transitions.TransitionFinishCallback;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The handler for Keyguard enter/exit and occlude/unocclude animations.
|
||||||
|
*
|
||||||
|
* <p>This takes the highest priority.
|
||||||
|
*/
|
||||||
|
public class KeyguardTransitionHandler implements Transitions.TransitionHandler {
|
||||||
|
private static final String TAG = "KeyguardTransition";
|
||||||
|
|
||||||
|
private final Transitions mTransitions;
|
||||||
|
private final Handler mMainHandler;
|
||||||
|
private final ShellExecutor mMainExecutor;
|
||||||
|
|
||||||
|
private final Map<IBinder, IRemoteTransition> mStartedTransitions = new ArrayMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local IRemoteTransition implementations registered by the keyguard service.
|
||||||
|
* @see KeyguardTransitions
|
||||||
|
*/
|
||||||
|
private IRemoteTransition mExitTransition = null;
|
||||||
|
private IRemoteTransition mOccludeTransition = null;
|
||||||
|
private IRemoteTransition mOccludeByDreamTransition = null;
|
||||||
|
private IRemoteTransition mUnoccludeTransition = null;
|
||||||
|
|
||||||
|
public KeyguardTransitionHandler(
|
||||||
|
@NonNull ShellInit shellInit,
|
||||||
|
@NonNull Transitions transitions,
|
||||||
|
@NonNull Handler mainHandler,
|
||||||
|
@NonNull ShellExecutor mainExecutor) {
|
||||||
|
mTransitions = transitions;
|
||||||
|
mMainHandler = mainHandler;
|
||||||
|
mMainExecutor = mainExecutor;
|
||||||
|
shellInit.addInitCallback(this::onInit, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onInit() {
|
||||||
|
mTransitions.addHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for SystemUI implementations to set custom Keyguard exit/occlude handlers.
|
||||||
|
*/
|
||||||
|
@ExternalThread
|
||||||
|
public KeyguardTransitions asKeyguardTransitions() {
|
||||||
|
return new KeyguardTransitionsImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean handles(TransitionInfo info) {
|
||||||
|
return (info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0
|
||||||
|
|| (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0
|
||||||
|
|| info.getType() == TRANSIT_KEYGUARD_OCCLUDE
|
||||||
|
|| info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
|
||||||
|
@NonNull SurfaceControl.Transaction startTransaction,
|
||||||
|
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||||
|
@NonNull TransitionFinishCallback finishCallback) {
|
||||||
|
if (!handles(info)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasOpeningOcclude = false;
|
||||||
|
boolean hasOpeningDream = false;
|
||||||
|
boolean hasClosingApp = false;
|
||||||
|
|
||||||
|
// Check for occluding/dream/closing apps
|
||||||
|
for (int i = info.getChanges().size() - 1; i >= 0; i--) {
|
||||||
|
final TransitionInfo.Change change = info.getChanges().get(i);
|
||||||
|
if (isOpeningType(change.getMode())) {
|
||||||
|
if (change.hasFlags(FLAG_OCCLUDES_KEYGUARD)) {
|
||||||
|
hasOpeningOcclude = true;
|
||||||
|
}
|
||||||
|
if (change.getTaskInfo() != null
|
||||||
|
&& change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_DREAM) {
|
||||||
|
hasOpeningDream = true;
|
||||||
|
}
|
||||||
|
} else if (isClosingType(change.getMode())) {
|
||||||
|
hasClosingApp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose a transition applicable for the changes and keyguard state.
|
||||||
|
if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) {
|
||||||
|
return startAnimation(mExitTransition,
|
||||||
|
"going-away",
|
||||||
|
transition, info, startTransaction, finishTransaction, finishCallback);
|
||||||
|
}
|
||||||
|
if (hasOpeningOcclude || info.getType() == TRANSIT_KEYGUARD_OCCLUDE) {
|
||||||
|
if (hasOpeningDream) {
|
||||||
|
return startAnimation(mOccludeByDreamTransition,
|
||||||
|
"occlude-by-dream",
|
||||||
|
transition, info, startTransaction, finishTransaction, finishCallback);
|
||||||
|
} else {
|
||||||
|
return startAnimation(mOccludeTransition,
|
||||||
|
"occlude",
|
||||||
|
transition, info, startTransaction, finishTransaction, finishCallback);
|
||||||
|
}
|
||||||
|
} else if (hasClosingApp || info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE) {
|
||||||
|
return startAnimation(mUnoccludeTransition,
|
||||||
|
"unocclude",
|
||||||
|
transition, info, startTransaction, finishTransaction, finishCallback);
|
||||||
|
} else {
|
||||||
|
Log.wtf(TAG, "Failed to play: " + info);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean startAnimation(IRemoteTransition remoteHandler, String description,
|
||||||
|
@NonNull IBinder transition, @NonNull TransitionInfo info,
|
||||||
|
@NonNull SurfaceControl.Transaction startTransaction,
|
||||||
|
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||||
|
@NonNull TransitionFinishCallback finishCallback) {
|
||||||
|
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
|
||||||
|
"start keyguard %s transition, info = %s", description, info);
|
||||||
|
|
||||||
|
try {
|
||||||
|
remoteHandler.startAnimation(transition, info, startTransaction,
|
||||||
|
new IRemoteTransitionFinishedCallback.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onTransitionFinished(
|
||||||
|
WindowContainerTransaction wct, SurfaceControl.Transaction sct) {
|
||||||
|
mMainExecutor.execute(() -> {
|
||||||
|
finishCallback.onTransitionFinished(wct, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mStartedTransitions.put(transition, remoteHandler);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.wtf(TAG, "RemoteException thrown from local IRemoteTransition", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
startTransaction.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mergeAnimation(@NonNull IBinder nextTransition, @NonNull TransitionInfo nextInfo,
|
||||||
|
@NonNull SurfaceControl.Transaction nextT, @NonNull IBinder currentTransition,
|
||||||
|
@NonNull TransitionFinishCallback nextFinishCallback) {
|
||||||
|
final IRemoteTransition playing = mStartedTransitions.get(currentTransition);
|
||||||
|
|
||||||
|
if (playing == null) {
|
||||||
|
ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
|
||||||
|
"unknown keyguard transition %s", currentTransition);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextInfo.getType() == TRANSIT_SLEEP) {
|
||||||
|
// An empty SLEEP transition comes in as a signal to abort transitions whenever a sleep
|
||||||
|
// token is held. In cases where keyguard is showing, we are running the animation for
|
||||||
|
// the device sleeping/waking, so it's best to ignore this and keep playing anyway.
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
finishAnimationImmediately(currentTransition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionConsumed(IBinder transition, boolean aborted,
|
||||||
|
SurfaceControl.Transaction finishTransaction) {
|
||||||
|
finishAnimationImmediately(transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
|
||||||
|
@NonNull TransitionRequestInfo request) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finishAnimationImmediately(IBinder transition) {
|
||||||
|
final IRemoteTransition playing = mStartedTransitions.get(transition);
|
||||||
|
|
||||||
|
if (playing != null) {
|
||||||
|
final IBinder fakeTransition = new Binder();
|
||||||
|
final TransitionInfo fakeInfo = new TransitionInfo(TRANSIT_SLEEP, 0x0);
|
||||||
|
final SurfaceControl.Transaction fakeT = new SurfaceControl.Transaction();
|
||||||
|
final FakeFinishCallback fakeFinishCb = new FakeFinishCallback();
|
||||||
|
try {
|
||||||
|
playing.mergeAnimation(fakeTransition, fakeInfo, fakeT, transition, fakeFinishCb);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// There is no good reason for this to happen because the player is a local object
|
||||||
|
// implementing an AIDL interface.
|
||||||
|
Log.wtf(TAG, "RemoteException thrown from KeyguardService transition", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FakeFinishCallback extends IRemoteTransitionFinishedCallback.Stub {
|
||||||
|
@Override
|
||||||
|
public void onTransitionFinished(
|
||||||
|
WindowContainerTransaction wct, SurfaceControl.Transaction t) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExternalThread
|
||||||
|
private final class KeyguardTransitionsImpl implements KeyguardTransitions {
|
||||||
|
@Override
|
||||||
|
public void register(
|
||||||
|
IRemoteTransition exitTransition,
|
||||||
|
IRemoteTransition occludeTransition,
|
||||||
|
IRemoteTransition occludeByDreamTransition,
|
||||||
|
IRemoteTransition unoccludeTransition) {
|
||||||
|
mMainExecutor.execute(() -> {
|
||||||
|
mExitTransition = exitTransition;
|
||||||
|
mOccludeTransition = occludeTransition;
|
||||||
|
mOccludeByDreamTransition = occludeByDreamTransition;
|
||||||
|
mUnoccludeTransition = unoccludeTransition;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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.wm.shell.keyguard;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.window.IRemoteTransition;
|
||||||
|
|
||||||
|
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface exposed to SystemUI Keyguard to register handlers for running
|
||||||
|
* animations on keyguard visibility changes.
|
||||||
|
*
|
||||||
|
* TODO(b/274954192): Merge the occludeTransition and occludeByDream handlers and just let the
|
||||||
|
* keyguard handler make the decision on which version it wants to play.
|
||||||
|
*/
|
||||||
|
@ExternalThread
|
||||||
|
public interface KeyguardTransitions {
|
||||||
|
/**
|
||||||
|
* Registers a set of remote transitions for Keyguard.
|
||||||
|
*/
|
||||||
|
default void register(
|
||||||
|
@NonNull IRemoteTransition unlockTransition,
|
||||||
|
@NonNull IRemoteTransition occludeTransition,
|
||||||
|
@NonNull IRemoteTransition occludeByDreamTransition,
|
||||||
|
@NonNull IRemoteTransition unoccludeTransition) {}
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ import android.window.WindowContainerTransaction;
|
|||||||
import android.window.WindowContainerTransactionCallback;
|
import android.window.WindowContainerTransactionCallback;
|
||||||
|
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
|
||||||
import com.android.wm.shell.pip.PipTransitionController;
|
import com.android.wm.shell.pip.PipTransitionController;
|
||||||
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
import com.android.wm.shell.pip.phone.PipTouchHandler;
|
||||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||||
@@ -63,6 +64,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
private PipTransitionController mPipHandler;
|
private PipTransitionController mPipHandler;
|
||||||
private RecentsTransitionHandler mRecentsHandler;
|
private RecentsTransitionHandler mRecentsHandler;
|
||||||
private StageCoordinator mSplitHandler;
|
private StageCoordinator mSplitHandler;
|
||||||
|
private final KeyguardTransitionHandler mKeyguardHandler;
|
||||||
|
|
||||||
private static class MixedTransition {
|
private static class MixedTransition {
|
||||||
static final int TYPE_ENTER_PIP_FROM_SPLIT = 1;
|
static final int TYPE_ENTER_PIP_FROM_SPLIT = 1;
|
||||||
@@ -76,6 +78,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
/** Recents transition while split-screen foreground. */
|
/** Recents transition while split-screen foreground. */
|
||||||
static final int TYPE_RECENTS_DURING_SPLIT = 4;
|
static final int TYPE_RECENTS_DURING_SPLIT = 4;
|
||||||
|
|
||||||
|
/** Keyguard exit/occlude/unocclude transition. */
|
||||||
|
static final int TYPE_KEYGUARD = 5;
|
||||||
|
|
||||||
/** The default animation for this mixed transition. */
|
/** The default animation for this mixed transition. */
|
||||||
static final int ANIM_TYPE_DEFAULT = 0;
|
static final int ANIM_TYPE_DEFAULT = 0;
|
||||||
|
|
||||||
@@ -126,8 +131,10 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
public DefaultMixedHandler(@NonNull ShellInit shellInit, @NonNull Transitions player,
|
public DefaultMixedHandler(@NonNull ShellInit shellInit, @NonNull Transitions player,
|
||||||
Optional<SplitScreenController> splitScreenControllerOptional,
|
Optional<SplitScreenController> splitScreenControllerOptional,
|
||||||
Optional<PipTouchHandler> pipTouchHandlerOptional,
|
Optional<PipTouchHandler> pipTouchHandlerOptional,
|
||||||
Optional<RecentsTransitionHandler> recentsHandlerOptional) {
|
Optional<RecentsTransitionHandler> recentsHandlerOptional,
|
||||||
|
KeyguardTransitionHandler keyguardHandler) {
|
||||||
mPlayer = player;
|
mPlayer = player;
|
||||||
|
mKeyguardHandler = keyguardHandler;
|
||||||
if (Transitions.ENABLE_SHELL_TRANSITIONS && pipTouchHandlerOptional.isPresent()
|
if (Transitions.ENABLE_SHELL_TRANSITIONS && pipTouchHandlerOptional.isPresent()
|
||||||
&& splitScreenControllerOptional.isPresent()) {
|
&& splitScreenControllerOptional.isPresent()) {
|
||||||
// Add after dependencies because it is higher priority
|
// Add after dependencies because it is higher priority
|
||||||
@@ -263,12 +270,26 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
@NonNull SurfaceControl.Transaction startTransaction,
|
@NonNull SurfaceControl.Transaction startTransaction,
|
||||||
@NonNull SurfaceControl.Transaction finishTransaction,
|
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||||
@NonNull Transitions.TransitionFinishCallback finishCallback) {
|
@NonNull Transitions.TransitionFinishCallback finishCallback) {
|
||||||
|
|
||||||
MixedTransition mixed = null;
|
MixedTransition mixed = null;
|
||||||
for (int i = mActiveTransitions.size() - 1; i >= 0; --i) {
|
for (int i = mActiveTransitions.size() - 1; i >= 0; --i) {
|
||||||
if (mActiveTransitions.get(i).mTransition != transition) continue;
|
if (mActiveTransitions.get(i).mTransition != transition) continue;
|
||||||
mixed = mActiveTransitions.get(i);
|
mixed = mActiveTransitions.get(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Offer Keyguard the opportunity to take over lock transitions - ideally we could know by
|
||||||
|
// the time of handleRequest, but we need more information than is available at that time.
|
||||||
|
if (KeyguardTransitionHandler.handles(info)) {
|
||||||
|
if (mixed != null && mixed.mType != MixedTransition.TYPE_KEYGUARD) {
|
||||||
|
ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
|
||||||
|
"Converting mixed transition into a keyguard transition");
|
||||||
|
onTransitionConsumed(transition, false, null);
|
||||||
|
}
|
||||||
|
mixed = new MixedTransition(MixedTransition.TYPE_KEYGUARD, transition);
|
||||||
|
mActiveTransitions.add(mixed);
|
||||||
|
}
|
||||||
|
|
||||||
if (mixed == null) return false;
|
if (mixed == null) return false;
|
||||||
|
|
||||||
if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
|
if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
|
||||||
@@ -282,6 +303,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
} else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) {
|
} else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) {
|
||||||
return animateRecentsDuringSplit(mixed, info, startTransaction, finishTransaction,
|
return animateRecentsDuringSplit(mixed, info, startTransaction, finishTransaction,
|
||||||
finishCallback);
|
finishCallback);
|
||||||
|
} else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
|
||||||
|
return mKeyguardHandler.startAnimation(
|
||||||
|
transition, info, startTransaction, finishTransaction, finishCallback);
|
||||||
} else {
|
} else {
|
||||||
mActiveTransitions.remove(mixed);
|
mActiveTransitions.remove(mixed);
|
||||||
throw new IllegalStateException("Starting mixed animation without a known mixed type? "
|
throw new IllegalStateException("Starting mixed animation without a known mixed type? "
|
||||||
@@ -574,6 +598,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
}
|
}
|
||||||
mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget,
|
mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget,
|
||||||
finishCallback);
|
finishCallback);
|
||||||
|
} else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
|
||||||
|
mKeyguardHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Playing a mixed transition with unknown type? "
|
throw new IllegalStateException("Playing a mixed transition with unknown type? "
|
||||||
+ mixed.mType);
|
+ mixed.mType);
|
||||||
@@ -597,6 +623,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
|
mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
|
||||||
} else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) {
|
} else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) {
|
||||||
mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
|
mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
|
||||||
|
} else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
|
||||||
|
mKeyguardHandler.onTransitionConsumed(transition, aborted, finishT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,8 +94,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
|
|||||||
@NonNull SurfaceControl.Transaction startTransaction,
|
@NonNull SurfaceControl.Transaction startTransaction,
|
||||||
@NonNull SurfaceControl.Transaction finishTransaction,
|
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||||
@NonNull Transitions.TransitionFinishCallback finishCallback) {
|
@NonNull Transitions.TransitionFinishCallback finishCallback) {
|
||||||
if (!Transitions.SHELL_TRANSITIONS_ROTATION && TransitionUtil.hasDisplayChange(info)
|
if (!Transitions.SHELL_TRANSITIONS_ROTATION && TransitionUtil.hasDisplayChange(info)) {
|
||||||
&& !TransitionUtil.alwaysReportToKeyguard(info)) {
|
|
||||||
// Note that if the remote doesn't have permission ACCESS_SURFACE_FLINGER, some
|
// Note that if the remote doesn't have permission ACCESS_SURFACE_FLINGER, some
|
||||||
// operations of the start transaction may be ignored.
|
// operations of the start transaction may be ignored.
|
||||||
mRequestedRemotes.remove(transition);
|
mRequestedRemotes.remove(transition);
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ import com.android.wm.shell.common.RemoteCallable;
|
|||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.TransactionPool;
|
import com.android.wm.shell.common.TransactionPool;
|
||||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
|
||||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||||
import com.android.wm.shell.sysui.ShellController;
|
import com.android.wm.shell.sysui.ShellController;
|
||||||
@@ -686,7 +687,11 @@ public class Transitions implements RemoteCallable<Transitions>,
|
|||||||
active.mToken, info, active.mStartT, active.mFinishT);
|
active.mToken, info, active.mStartT, active.mFinishT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.getRootCount() == 0 && !TransitionUtil.alwaysReportToKeyguard(info)) {
|
/*
|
||||||
|
* Some transitions we always need to report to keyguard even if they are empty.
|
||||||
|
* TODO (b/274954192): Remove this once keyguard dispatching fully moves to Shell.
|
||||||
|
*/
|
||||||
|
if (info.getRootCount() == 0 && !KeyguardTransitionHandler.handles(info)) {
|
||||||
// No root-leashes implies that the transition is empty/no-op, so just do
|
// No root-leashes implies that the transition is empty/no-op, so just do
|
||||||
// housekeeping and return.
|
// housekeeping and return.
|
||||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "No transition roots in %s so"
|
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "No transition roots in %s so"
|
||||||
|
|||||||
@@ -85,23 +85,6 @@ public class TransitionUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Some transitions we always need to report to keyguard even if they are empty.
|
|
||||||
* TODO (b/274954192): Remove this once keyguard dispatching moves to Shell.
|
|
||||||
*/
|
|
||||||
public static boolean alwaysReportToKeyguard(TransitionInfo info) {
|
|
||||||
// occlusion status of activities can change while screen is off so there will be no
|
|
||||||
// visibility change but we still need keyguardservice to be notified.
|
|
||||||
if (info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE) return true;
|
|
||||||
|
|
||||||
// It's possible for some activities to stop with bad timing (esp. since we can't yet
|
|
||||||
// queue activity transitions initiated by apps) that results in an empty transition for
|
|
||||||
// keyguard going-away. In general, we should should always report Keyguard-going-away.
|
|
||||||
if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns `true` if `change` is a wallpaper. */
|
/** Returns `true` if `change` is a wallpaper. */
|
||||||
public static boolean isWallpaper(TransitionInfo.Change change) {
|
public static boolean isWallpaper(TransitionInfo.Change change) {
|
||||||
return (change.getTaskInfo() == null)
|
return (change.getTaskInfo() == null)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.android.systemui.dagger.SysUIComponent;
|
|||||||
import com.android.systemui.dagger.WMComponent;
|
import com.android.systemui.dagger.WMComponent;
|
||||||
import com.android.systemui.util.InitializationChecker;
|
import com.android.systemui.util.InitializationChecker;
|
||||||
import com.android.wm.shell.dagger.WMShellConcurrencyModule;
|
import com.android.wm.shell.dagger.WMShellConcurrencyModule;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitions;
|
||||||
import com.android.wm.shell.sysui.ShellInterface;
|
import com.android.wm.shell.sysui.ShellInterface;
|
||||||
import com.android.wm.shell.transition.ShellTransitions;
|
import com.android.wm.shell.transition.ShellTransitions;
|
||||||
|
|
||||||
@@ -93,6 +94,7 @@ public abstract class SystemUIInitializer {
|
|||||||
.setBubbles(mWMComponent.getBubbles())
|
.setBubbles(mWMComponent.getBubbles())
|
||||||
.setTaskViewFactory(mWMComponent.getTaskViewFactory())
|
.setTaskViewFactory(mWMComponent.getTaskViewFactory())
|
||||||
.setTransitions(mWMComponent.getTransitions())
|
.setTransitions(mWMComponent.getTransitions())
|
||||||
|
.setKeyguardTransitions(mWMComponent.getKeyguardTransitions())
|
||||||
.setStartingSurface(mWMComponent.getStartingSurface())
|
.setStartingSurface(mWMComponent.getStartingSurface())
|
||||||
.setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
|
.setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
|
||||||
.setRecentTasks(mWMComponent.getRecentTasks())
|
.setRecentTasks(mWMComponent.getRecentTasks())
|
||||||
@@ -113,6 +115,7 @@ public abstract class SystemUIInitializer {
|
|||||||
.setBubbles(Optional.ofNullable(null))
|
.setBubbles(Optional.ofNullable(null))
|
||||||
.setTaskViewFactory(Optional.ofNullable(null))
|
.setTaskViewFactory(Optional.ofNullable(null))
|
||||||
.setTransitions(new ShellTransitions() {})
|
.setTransitions(new ShellTransitions() {})
|
||||||
|
.setKeyguardTransitions(new KeyguardTransitions() {})
|
||||||
.setDisplayAreaHelper(Optional.ofNullable(null))
|
.setDisplayAreaHelper(Optional.ofNullable(null))
|
||||||
.setStartingSurface(Optional.ofNullable(null))
|
.setStartingSurface(Optional.ofNullable(null))
|
||||||
.setRecentTasks(Optional.ofNullable(null))
|
.setRecentTasks(Optional.ofNullable(null))
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import com.android.wm.shell.back.BackAnimation;
|
|||||||
import com.android.wm.shell.bubbles.Bubbles;
|
import com.android.wm.shell.bubbles.Bubbles;
|
||||||
import com.android.wm.shell.desktopmode.DesktopMode;
|
import com.android.wm.shell.desktopmode.DesktopMode;
|
||||||
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
|
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitions;
|
||||||
import com.android.wm.shell.onehanded.OneHanded;
|
import com.android.wm.shell.onehanded.OneHanded;
|
||||||
import com.android.wm.shell.pip.Pip;
|
import com.android.wm.shell.pip.Pip;
|
||||||
import com.android.wm.shell.recents.RecentTasks;
|
import com.android.wm.shell.recents.RecentTasks;
|
||||||
@@ -103,6 +104,9 @@ public interface SysUIComponent {
|
|||||||
@BindsInstance
|
@BindsInstance
|
||||||
Builder setTransitions(ShellTransitions t);
|
Builder setTransitions(ShellTransitions t);
|
||||||
|
|
||||||
|
@BindsInstance
|
||||||
|
Builder setKeyguardTransitions(KeyguardTransitions k);
|
||||||
|
|
||||||
@BindsInstance
|
@BindsInstance
|
||||||
Builder setStartingSurface(Optional<StartingSurface> s);
|
Builder setStartingSurface(Optional<StartingSurface> s);
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.android.wm.shell.dagger.WMShellModule;
|
|||||||
import com.android.wm.shell.dagger.WMSingleton;
|
import com.android.wm.shell.dagger.WMSingleton;
|
||||||
import com.android.wm.shell.desktopmode.DesktopMode;
|
import com.android.wm.shell.desktopmode.DesktopMode;
|
||||||
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
|
import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitions;
|
||||||
import com.android.wm.shell.onehanded.OneHanded;
|
import com.android.wm.shell.onehanded.OneHanded;
|
||||||
import com.android.wm.shell.pip.Pip;
|
import com.android.wm.shell.pip.Pip;
|
||||||
import com.android.wm.shell.recents.RecentTasks;
|
import com.android.wm.shell.recents.RecentTasks;
|
||||||
@@ -98,6 +99,9 @@ public interface WMComponent {
|
|||||||
@WMSingleton
|
@WMSingleton
|
||||||
ShellTransitions getTransitions();
|
ShellTransitions getTransitions();
|
||||||
|
|
||||||
|
@WMSingleton
|
||||||
|
KeyguardTransitions getKeyguardTransitions();
|
||||||
|
|
||||||
@WMSingleton
|
@WMSingleton
|
||||||
Optional<StartingSurface> getStartingSurface();
|
Optional<StartingSurface> getStartingSurface();
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import static android.view.RemoteAnimationTarget.MODE_CLOSING;
|
|||||||
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
||||||
import static android.view.WindowManager.TRANSIT_CLOSE;
|
import static android.view.WindowManager.TRANSIT_CLOSE;
|
||||||
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
|
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
|
||||||
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
|
|
||||||
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
|
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
|
||||||
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
|
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
|
||||||
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
|
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
|
||||||
@@ -37,7 +36,6 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
|||||||
import static android.view.WindowManager.TransitionFlags;
|
import static android.view.WindowManager.TransitionFlags;
|
||||||
import static android.view.WindowManager.TransitionOldType;
|
import static android.view.WindowManager.TransitionOldType;
|
||||||
import static android.view.WindowManager.TransitionType;
|
import static android.view.WindowManager.TransitionType;
|
||||||
import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD;
|
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityTaskManager;
|
import android.app.ActivityTaskManager;
|
||||||
@@ -67,8 +65,6 @@ import android.view.WindowManager;
|
|||||||
import android.view.WindowManagerPolicyConstants;
|
import android.view.WindowManagerPolicyConstants;
|
||||||
import android.window.IRemoteTransition;
|
import android.window.IRemoteTransition;
|
||||||
import android.window.IRemoteTransitionFinishedCallback;
|
import android.window.IRemoteTransitionFinishedCallback;
|
||||||
import android.window.RemoteTransition;
|
|
||||||
import android.window.TransitionFilter;
|
|
||||||
import android.window.TransitionInfo;
|
import android.window.TransitionInfo;
|
||||||
|
|
||||||
import com.android.internal.policy.IKeyguardDismissCallback;
|
import com.android.internal.policy.IKeyguardDismissCallback;
|
||||||
@@ -178,7 +174,7 @@ public class KeyguardService extends Service {
|
|||||||
|
|
||||||
// Wrap Keyguard going away animation.
|
// Wrap Keyguard going away animation.
|
||||||
// Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy).
|
// Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy).
|
||||||
private static IRemoteTransition wrap(IRemoteAnimationRunner runner) {
|
public static IRemoteTransition wrap(IRemoteAnimationRunner runner) {
|
||||||
return new IRemoteTransition.Stub() {
|
return new IRemoteTransition.Stub() {
|
||||||
final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
|
final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
|
||||||
new ArrayMap<>();
|
new ArrayMap<>();
|
||||||
@@ -273,7 +269,8 @@ public class KeyguardService extends Service {
|
|||||||
if (mShellTransitions == null || !Transitions.ENABLE_SHELL_TRANSITIONS) {
|
if (mShellTransitions == null || !Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||||
RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
|
RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
|
||||||
final RemoteAnimationAdapter exitAnimationAdapter =
|
final RemoteAnimationAdapter exitAnimationAdapter =
|
||||||
new RemoteAnimationAdapter(mExitAnimationRunner, 0, 0);
|
new RemoteAnimationAdapter(
|
||||||
|
mKeyguardViewMediator.getExitAnimationRunner(), 0, 0);
|
||||||
definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY,
|
definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY,
|
||||||
exitAnimationAdapter);
|
exitAnimationAdapter);
|
||||||
definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
|
definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
|
||||||
@@ -297,92 +294,7 @@ public class KeyguardService extends Service {
|
|||||||
unoccludeAnimationAdapter);
|
unoccludeAnimationAdapter);
|
||||||
ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay(
|
ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay(
|
||||||
mDisplayTracker.getDefaultDisplayId(), definition);
|
mDisplayTracker.getDefaultDisplayId(), definition);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_GOING_AWAY");
|
|
||||||
TransitionFilter f = new TransitionFilter();
|
|
||||||
f.mFlags = TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
|
|
||||||
mShellTransitions.registerRemote(f, new RemoteTransition(
|
|
||||||
wrap(mExitAnimationRunner), getIApplicationThread(), "ExitKeyguard"));
|
|
||||||
|
|
||||||
Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_(UN)OCCLUDE");
|
|
||||||
// Register for occluding
|
|
||||||
final RemoteTransition occludeTransition = new RemoteTransition(
|
|
||||||
mOccludeAnimation, getIApplicationThread(), "KeyguardOcclude");
|
|
||||||
f = new TransitionFilter();
|
|
||||||
f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED;
|
|
||||||
f.mRequirements = new TransitionFilter.Requirement[]{
|
|
||||||
new TransitionFilter.Requirement(), new TransitionFilter.Requirement()};
|
|
||||||
// First require at-least one app showing that occludes.
|
|
||||||
f.mRequirements[0].mMustBeIndependent = false;
|
|
||||||
f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD;
|
|
||||||
f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
|
|
||||||
// Then require that we aren't closing any occludes (because this would mean a
|
|
||||||
// regular task->task or activity->activity animation not involving keyguard).
|
|
||||||
f.mRequirements[1].mNot = true;
|
|
||||||
f.mRequirements[1].mMustBeIndependent = false;
|
|
||||||
f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD;
|
|
||||||
f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
|
|
||||||
mShellTransitions.registerRemote(f, occludeTransition);
|
|
||||||
|
|
||||||
// Now register for un-occlude.
|
|
||||||
final RemoteTransition unoccludeTransition = new RemoteTransition(
|
|
||||||
mUnoccludeAnimation, getIApplicationThread(), "KeyguardUnocclude");
|
|
||||||
f = new TransitionFilter();
|
|
||||||
f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED;
|
|
||||||
f.mRequirements = new TransitionFilter.Requirement[]{
|
|
||||||
new TransitionFilter.Requirement(), new TransitionFilter.Requirement()};
|
|
||||||
// First require at-least one app going-away (doesn't need occlude flag
|
|
||||||
// as that is implicit by it having been visible and we don't want to exclude
|
|
||||||
// cases where we are un-occluding because the app removed its showWhenLocked
|
|
||||||
// capability at runtime).
|
|
||||||
f.mRequirements[1].mMustBeIndependent = false;
|
|
||||||
f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
|
|
||||||
f.mRequirements[1].mMustBeTask = true;
|
|
||||||
// Then require that we aren't opening any occludes (otherwise we'd remain
|
|
||||||
// occluded).
|
|
||||||
f.mRequirements[0].mNot = true;
|
|
||||||
f.mRequirements[0].mMustBeIndependent = false;
|
|
||||||
f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD;
|
|
||||||
f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
|
|
||||||
mShellTransitions.registerRemote(f, unoccludeTransition);
|
|
||||||
|
|
||||||
// Register for specific transition type.
|
|
||||||
// Above filter cannot fulfill all conditions.
|
|
||||||
// E.g. close top activity while screen off but next activity is occluded, this should
|
|
||||||
// an occluded transition, but since the activity is invisible, the condition would
|
|
||||||
// match unoccluded transition.
|
|
||||||
// But on the contrary, if we add above condition in occluded transition, then when user
|
|
||||||
// trying to dismiss occluded activity when unlock keyguard, the condition would match
|
|
||||||
// occluded transition.
|
|
||||||
f = new TransitionFilter();
|
|
||||||
f.mTypeSet = new int[]{TRANSIT_KEYGUARD_OCCLUDE};
|
|
||||||
mShellTransitions.registerRemote(f, occludeTransition);
|
|
||||||
|
|
||||||
f = new TransitionFilter();
|
|
||||||
f.mTypeSet = new int[]{TRANSIT_KEYGUARD_UNOCCLUDE};
|
|
||||||
mShellTransitions.registerRemote(f, unoccludeTransition);
|
|
||||||
|
|
||||||
Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_OCCLUDE for DREAM");
|
|
||||||
// Register for occluding by Dream
|
|
||||||
f = new TransitionFilter();
|
|
||||||
f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED;
|
|
||||||
f.mRequirements = new TransitionFilter.Requirement[]{
|
|
||||||
new TransitionFilter.Requirement(), new TransitionFilter.Requirement()};
|
|
||||||
// First require at-least one app of type DREAM showing that occludes.
|
|
||||||
f.mRequirements[0].mActivityType = WindowConfiguration.ACTIVITY_TYPE_DREAM;
|
|
||||||
f.mRequirements[0].mMustBeIndependent = false;
|
|
||||||
f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD;
|
|
||||||
f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
|
|
||||||
// Then require that we aren't closing any occludes (because this would mean a
|
|
||||||
// regular task->task or activity->activity animation not involving keyguard).
|
|
||||||
f.mRequirements[1].mNot = true;
|
|
||||||
f.mRequirements[1].mMustBeIndependent = false;
|
|
||||||
f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD;
|
|
||||||
f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
|
|
||||||
mShellTransitions.registerRemote(f, new RemoteTransition(
|
|
||||||
wrap(mKeyguardViewMediator.getOccludeByDreamAnimationRunner()),
|
|
||||||
getIApplicationThread(), "KeyguardOccludeByDream"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -402,27 +314,6 @@ public class KeyguardService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final IRemoteAnimationRunner.Stub mExitAnimationRunner =
|
|
||||||
new IRemoteAnimationRunner.Stub() {
|
|
||||||
@Override // Binder interface
|
|
||||||
public void onAnimationStart(@WindowManager.TransitionOldType int transit,
|
|
||||||
RemoteAnimationTarget[] apps,
|
|
||||||
RemoteAnimationTarget[] wallpapers,
|
|
||||||
RemoteAnimationTarget[] nonApps,
|
|
||||||
IRemoteAnimationFinishedCallback finishedCallback) {
|
|
||||||
Trace.beginSection("mExitAnimationRunner.onAnimationStart#startKeyguardExitAnimation");
|
|
||||||
checkPermission();
|
|
||||||
mKeyguardViewMediator.startKeyguardExitAnimation(transit, apps, wallpapers,
|
|
||||||
nonApps, finishedCallback);
|
|
||||||
Trace.endSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override // Binder interface
|
|
||||||
public void onAnimationCancelled() {
|
|
||||||
mKeyguardViewMediator.cancelKeyguardExitAnimation();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
final IRemoteTransition mOccludeAnimation = new IRemoteTransition.Stub() {
|
final IRemoteTransition mOccludeAnimation = new IRemoteTransition.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void startAnimation(IBinder transition, TransitionInfo info,
|
public void startAnimation(IBinder transition, TransitionInfo info,
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ import android.view.WindowManager;
|
|||||||
import android.view.WindowManagerPolicyConstants;
|
import android.view.WindowManagerPolicyConstants;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.window.IRemoteTransition;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -153,12 +154,14 @@ import com.android.systemui.statusbar.phone.ScrimController;
|
|||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||||
import com.android.systemui.util.DeviceConfigProxy;
|
import com.android.systemui.util.DeviceConfigProxy;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitions;
|
||||||
|
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -961,7 +964,26 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private IRemoteAnimationRunner mOccludeAnimationRunner =
|
private final IRemoteAnimationRunner.Stub mExitAnimationRunner =
|
||||||
|
new IRemoteAnimationRunner.Stub() {
|
||||||
|
@Override // Binder interface
|
||||||
|
public void onAnimationStart(@WindowManager.TransitionOldType int transit,
|
||||||
|
RemoteAnimationTarget[] apps,
|
||||||
|
RemoteAnimationTarget[] wallpapers,
|
||||||
|
RemoteAnimationTarget[] nonApps,
|
||||||
|
IRemoteAnimationFinishedCallback finishedCallback) {
|
||||||
|
Trace.beginSection("mExitAnimationRunner.onAnimationStart#startKeyguardExitAnimation");
|
||||||
|
startKeyguardExitAnimation(transit, apps, wallpapers, nonApps, finishedCallback);
|
||||||
|
Trace.endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // Binder interface
|
||||||
|
public void onAnimationCancelled() {
|
||||||
|
cancelKeyguardExitAnimation();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final IRemoteAnimationRunner mOccludeAnimationRunner =
|
||||||
new OccludeActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
|
new OccludeActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
|
||||||
|
|
||||||
private final IRemoteAnimationRunner mOccludeByDreamAnimationRunner =
|
private final IRemoteAnimationRunner mOccludeByDreamAnimationRunner =
|
||||||
@@ -1186,6 +1208,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
private final InteractionJankMonitor mInteractionJankMonitor;
|
private final InteractionJankMonitor mInteractionJankMonitor;
|
||||||
private boolean mWallpaperSupportsAmbientMode;
|
private boolean mWallpaperSupportsAmbientMode;
|
||||||
private ScreenOnCoordinator mScreenOnCoordinator;
|
private ScreenOnCoordinator mScreenOnCoordinator;
|
||||||
|
private final KeyguardTransitions mKeyguardTransitions;
|
||||||
|
|
||||||
private Lazy<ActivityLaunchAnimator> mActivityLaunchAnimator;
|
private Lazy<ActivityLaunchAnimator> mActivityLaunchAnimator;
|
||||||
private Lazy<ScrimController> mScrimControllerLazy;
|
private Lazy<ScrimController> mScrimControllerLazy;
|
||||||
@@ -1221,6 +1244,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
ScreenOffAnimationController screenOffAnimationController,
|
ScreenOffAnimationController screenOffAnimationController,
|
||||||
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
|
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
|
||||||
ScreenOnCoordinator screenOnCoordinator,
|
ScreenOnCoordinator screenOnCoordinator,
|
||||||
|
KeyguardTransitions keyguardTransitions,
|
||||||
InteractionJankMonitor interactionJankMonitor,
|
InteractionJankMonitor interactionJankMonitor,
|
||||||
DreamOverlayStateController dreamOverlayStateController,
|
DreamOverlayStateController dreamOverlayStateController,
|
||||||
Lazy<ShadeController> shadeControllerLazy,
|
Lazy<ShadeController> shadeControllerLazy,
|
||||||
@@ -1248,6 +1272,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
dumpManager.registerDumpable(getClass().getName(), this);
|
dumpManager.registerDumpable(getClass().getName(), this);
|
||||||
mDeviceConfig = deviceConfig;
|
mDeviceConfig = deviceConfig;
|
||||||
mScreenOnCoordinator = screenOnCoordinator;
|
mScreenOnCoordinator = screenOnCoordinator;
|
||||||
|
mKeyguardTransitions = keyguardTransitions;
|
||||||
mNotificationShadeWindowControllerLazy = notificationShadeWindowControllerLazy;
|
mNotificationShadeWindowControllerLazy = notificationShadeWindowControllerLazy;
|
||||||
mShowHomeOverLockscreen = mDeviceConfig.getBoolean(
|
mShowHomeOverLockscreen = mDeviceConfig.getBoolean(
|
||||||
DeviceConfig.NAMESPACE_SYSTEMUI,
|
DeviceConfig.NAMESPACE_SYSTEMUI,
|
||||||
@@ -1323,6 +1348,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
setShowingLocked(false /* showing */, true /* forceCallbacks */);
|
setShowingLocked(false /* showing */, true /* forceCallbacks */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mKeyguardTransitions.register(
|
||||||
|
KeyguardService.wrap(getExitAnimationRunner()),
|
||||||
|
KeyguardService.wrap(getOccludeAnimationRunner()),
|
||||||
|
KeyguardService.wrap(getOccludeByDreamAnimationRunner()),
|
||||||
|
KeyguardService.wrap(getUnoccludeAnimationRunner()));
|
||||||
|
|
||||||
final ContentResolver cr = mContext.getContentResolver();
|
final ContentResolver cr = mContext.getContentResolver();
|
||||||
|
|
||||||
mDeviceInteractive = mPM.isInteractive();
|
mDeviceInteractive = mPM.isInteractive();
|
||||||
@@ -1858,6 +1889,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
|
|||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IRemoteAnimationRunner getExitAnimationRunner() {
|
||||||
|
return mExitAnimationRunner;
|
||||||
|
}
|
||||||
|
|
||||||
public IRemoteAnimationRunner getOccludeAnimationRunner() {
|
public IRemoteAnimationRunner getOccludeAnimationRunner() {
|
||||||
return mOccludeAnimationRunner;
|
return mOccludeAnimationRunner;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ import com.android.systemui.statusbar.phone.ScrimController;
|
|||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||||
import com.android.systemui.util.DeviceConfigProxy;
|
import com.android.systemui.util.DeviceConfigProxy;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitions;
|
||||||
|
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
@@ -119,6 +120,7 @@ public class KeyguardModule {
|
|||||||
ScreenOffAnimationController screenOffAnimationController,
|
ScreenOffAnimationController screenOffAnimationController,
|
||||||
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
|
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
|
||||||
ScreenOnCoordinator screenOnCoordinator,
|
ScreenOnCoordinator screenOnCoordinator,
|
||||||
|
KeyguardTransitions keyguardTransitions,
|
||||||
InteractionJankMonitor interactionJankMonitor,
|
InteractionJankMonitor interactionJankMonitor,
|
||||||
DreamOverlayStateController dreamOverlayStateController,
|
DreamOverlayStateController dreamOverlayStateController,
|
||||||
Lazy<ShadeController> shadeController,
|
Lazy<ShadeController> shadeController,
|
||||||
@@ -152,6 +154,7 @@ public class KeyguardModule {
|
|||||||
screenOffAnimationController,
|
screenOffAnimationController,
|
||||||
notificationShadeDepthController,
|
notificationShadeDepthController,
|
||||||
screenOnCoordinator,
|
screenOnCoordinator,
|
||||||
|
keyguardTransitions,
|
||||||
interactionJankMonitor,
|
interactionJankMonitor,
|
||||||
dreamOverlayStateController,
|
dreamOverlayStateController,
|
||||||
shadeController,
|
shadeController,
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ import com.android.systemui.util.DeviceConfigProxy;
|
|||||||
import com.android.systemui.util.DeviceConfigProxyFake;
|
import com.android.systemui.util.DeviceConfigProxyFake;
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||||
import com.android.systemui.util.time.FakeSystemClock;
|
import com.android.systemui.util.time.FakeSystemClock;
|
||||||
|
import com.android.wm.shell.keyguard.KeyguardTransitions;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -135,6 +136,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
|
|||||||
private @Mock ScreenOffAnimationController mScreenOffAnimationController;
|
private @Mock ScreenOffAnimationController mScreenOffAnimationController;
|
||||||
private @Mock InteractionJankMonitor mInteractionJankMonitor;
|
private @Mock InteractionJankMonitor mInteractionJankMonitor;
|
||||||
private @Mock ScreenOnCoordinator mScreenOnCoordinator;
|
private @Mock ScreenOnCoordinator mScreenOnCoordinator;
|
||||||
|
private @Mock KeyguardTransitions mKeyguardTransitions;
|
||||||
private @Mock ShadeController mShadeController;
|
private @Mock ShadeController mShadeController;
|
||||||
private NotificationShadeWindowController mNotificationShadeWindowController;
|
private NotificationShadeWindowController mNotificationShadeWindowController;
|
||||||
private @Mock DreamOverlayStateController mDreamOverlayStateController;
|
private @Mock DreamOverlayStateController mDreamOverlayStateController;
|
||||||
@@ -620,6 +622,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
|
|||||||
mScreenOffAnimationController,
|
mScreenOffAnimationController,
|
||||||
() -> mNotificationShadeDepthController,
|
() -> mNotificationShadeDepthController,
|
||||||
mScreenOnCoordinator,
|
mScreenOnCoordinator,
|
||||||
|
mKeyguardTransitions,
|
||||||
mInteractionJankMonitor,
|
mInteractionJankMonitor,
|
||||||
mDreamOverlayStateController,
|
mDreamOverlayStateController,
|
||||||
() -> mShadeController,
|
() -> mShadeController,
|
||||||
|
|||||||
Reference in New Issue
Block a user