Merge "Add an inputconsumer override method for modern recents transitions" into sc-v2-dev

This commit is contained in:
Evan Rosky
2021-08-17 21:45:24 +00:00
committed by Android (Google) Code Review
2 changed files with 99 additions and 7 deletions

View File

@@ -47,6 +47,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.LOGTAG_INPUT_FOCUS;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Handler;
@@ -66,6 +67,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.Set;
import java.util.function.Consumer;
@@ -99,6 +101,15 @@ final class InputMonitor {
*/
private final ArrayMap<String, InputConsumerImpl> mInputConsumers = new ArrayMap();
/**
* Set when recents (overview) is active as part of a shell transition. While set, any focus
* going to the recents activity will be redirected to the Recents input consumer. Since we
* draw the live-tile above the recents activity, we also need to provide that activity as a
* z-layering reference so that we can place the recents input consumer above it.
*/
private WeakReference<ActivityRecord> mActiveRecentsActivity = null;
private WeakReference<ActivityRecord> mActiveRecentsLayerRef = null;
/**
* Representation of a input consumer that the policy has added to the window manager to consume
* input events going to windows below it.
@@ -394,6 +405,21 @@ final class InputMonitor {
}
}
/**
* Inform InputMonitor when recents is active so it can enable the recents input consumer.
* @param activity The active recents activity. {@code null} means recents is not active.
* @param layer An activity whose Z-layer is used as a reference for how to sort the consumer.
*/
void setActiveRecents(@Nullable ActivityRecord activity, @Nullable ActivityRecord layer) {
final boolean clear = activity == null;
mActiveRecentsActivity = clear ? null : new WeakReference<>(activity);
mActiveRecentsLayerRef = clear ? null : new WeakReference<>(layer);
}
private static <T> T getWeak(WeakReference<T> ref) {
return ref != null ? ref.get() : null;
}
/**
* Called when the current input focus changes.
*/
@@ -404,8 +430,10 @@ final class InputMonitor {
if (recentsAnimationInputConsumer != null && focus != null) {
final RecentsAnimationController recentsAnimationController =
mService.getRecentsAnimationController();
final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null
&& recentsAnimationController.shouldApplyInputConsumer(focus.mActivityRecord);
final boolean shouldApplyRecentsInputConsumer = (recentsAnimationController != null
&& recentsAnimationController.shouldApplyInputConsumer(focus.mActivityRecord))
// Shell transitions doesn't use RecentsAnimationController
|| getWeak(mActiveRecentsActivity) != null;
if (shouldApplyRecentsInputConsumer) {
requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
recentsAnimationInputConsumer.mName);
@@ -505,6 +533,14 @@ final class InputMonitor {
mInDrag = inDrag;
resetInputConsumers(mInputTransaction);
// Update recents input consumer layer if active
if (mAddRecentsAnimationInputConsumerHandle
&& getWeak(mActiveRecentsActivity) != null) {
final WindowContainer layer = getWeak(mActiveRecentsLayerRef);
mRecentsAnimationInputConsumer.show(mInputTransaction,
layer != null ? layer : getWeak(mActiveRecentsActivity));
mAddRecentsAnimationInputConsumerHandle = false;
}
mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */);
updateInputFocusRequest(mRecentsAnimationInputConsumer);
@@ -539,6 +575,7 @@ final class InputMonitor {
final int privateFlags = w.mAttrs.privateFlags;
// This only works for legacy transitions.
if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
if (recentsAnimationController.updateInputConsumerForApp(
mRecentsAnimationInputConsumer.mWindowHandle)) {

View File

@@ -16,10 +16,13 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_CHANGE;
@@ -156,7 +159,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
// TODO(b/188595497): remove when not needed.
/** @see RecentsAnimationController#mNavigationBarAttachedToApp */
private boolean mNavBarAttachedToApp = false;
private int mNavBarDisplayId = INVALID_DISPLAY;
private int mRecentsDisplayId = INVALID_DISPLAY;
Transition(@TransitionType int type, @TransitionFlags int flags,
TransitionController controller, BLASTSyncEngine syncEngine) {
@@ -176,6 +179,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
return mSyncId;
}
@TransitionFlags
int getFlags() {
return mFlags;
}
/**
* Formally starts the transition. Participants can be collected before this is started,
* but this won't consider itself ready until started -- even if all the participants have
@@ -407,6 +415,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
sendRemoteCallback(mClientAnimationFinishCallback);
legacyRestoreNavigationBarFromApp();
if (mRecentsDisplayId != INVALID_DISPLAY) {
// Clean up input monitors (for recents)
final DisplayContent dc =
mController.mAtm.mRootWindowContainer.getDisplayContent(mRecentsDisplayId);
dc.getInputMonitor().setActiveRecents(null /* activity */, null /* layer */);
}
}
void abort() {
@@ -560,7 +575,43 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
}
final DisplayContent dc =
mController.mAtm.mRootWindowContainer.getDisplayContent(displayId);
if (dc == null || !dc.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
if (dc == null) return;
mRecentsDisplayId = displayId;
// Recents has an input-consumer to grab input from the "live tile" app. Set that up here
final InputConsumerImpl recentsAnimationInputConsumer =
dc.getInputMonitor().getInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
if (recentsAnimationInputConsumer != null) {
// find the top-most going-away activity and the recents activity. The top-most
// is used as layer reference while the recents is used for registering the consumer
// override.
ActivityRecord recentsActivity = null;
ActivityRecord topActivity = null;
for (int i = 0; i < info.getChanges().size(); ++i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (change.getTaskInfo() == null) continue;
final Task task = Task.fromWindowContainerToken(
info.getChanges().get(i).getTaskInfo().token);
if (task == null) continue;
final int activityType = change.getTaskInfo().topActivityType;
final boolean isRecents = activityType == ACTIVITY_TYPE_HOME
|| activityType == ACTIVITY_TYPE_RECENTS;
if (isRecents && recentsActivity == null) {
recentsActivity = task.getTopVisibleActivity();
} else if (!isRecents && topActivity == null) {
topActivity = task.getTopNonFinishingActivity();
}
}
if (recentsActivity != null && topActivity != null) {
recentsAnimationInputConsumer.mWindowHandle.touchableRegion.set(
topActivity.getBounds());
dc.getInputMonitor().setActiveRecents(recentsActivity, topActivity);
}
}
// The rest of this function handles nav-bar reparenting
if (!dc.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
// Skip the case where the nav bar is controlled by fade rotation.
|| dc.getFadeRotationAnimationController() != null) {
return;
@@ -587,7 +638,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
return;
}
mNavBarAttachedToApp = true;
mNavBarDisplayId = displayId;
navWindow.mToken.cancelAnimation();
final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction();
final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl();
@@ -611,12 +661,17 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
if (!mNavBarAttachedToApp) return;
mNavBarAttachedToApp = false;
if (mRecentsDisplayId == INVALID_DISPLAY) {
Slog.e(TAG, "Reparented navigation bar without a valid display");
mRecentsDisplayId = DEFAULT_DISPLAY;
}
if (mController.mStatusBar != null) {
mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mNavBarDisplayId, true);
mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, true);
}
final DisplayContent dc =
mController.mAtm.mRootWindowContainer.getDisplayContent(mNavBarDisplayId);
mController.mAtm.mRootWindowContainer.getDisplayContent(mRecentsDisplayId);
final WindowState navWindow = dc.getDisplayPolicy().getNavigationBar();
if (navWindow == null) return;
navWindow.setSurfaceTranslationY(0);