Merge "Add an inputconsumer override method for modern recents transitions" into sc-v2-dev
This commit is contained in:
@@ -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.WindowManagerDebugConfig.TAG_WM;
|
||||||
import static com.android.server.wm.WindowManagerService.LOGTAG_INPUT_FOCUS;
|
import static com.android.server.wm.WindowManagerService.LOGTAG_INPUT_FOCUS;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -66,6 +67,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
|||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -99,6 +101,15 @@ final class InputMonitor {
|
|||||||
*/
|
*/
|
||||||
private final ArrayMap<String, InputConsumerImpl> mInputConsumers = new ArrayMap();
|
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
|
* Representation of a input consumer that the policy has added to the window manager to consume
|
||||||
* input events going to windows below it.
|
* 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.
|
* Called when the current input focus changes.
|
||||||
*/
|
*/
|
||||||
@@ -404,8 +430,10 @@ final class InputMonitor {
|
|||||||
if (recentsAnimationInputConsumer != null && focus != null) {
|
if (recentsAnimationInputConsumer != null && focus != null) {
|
||||||
final RecentsAnimationController recentsAnimationController =
|
final RecentsAnimationController recentsAnimationController =
|
||||||
mService.getRecentsAnimationController();
|
mService.getRecentsAnimationController();
|
||||||
final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null
|
final boolean shouldApplyRecentsInputConsumer = (recentsAnimationController != null
|
||||||
&& recentsAnimationController.shouldApplyInputConsumer(focus.mActivityRecord);
|
&& recentsAnimationController.shouldApplyInputConsumer(focus.mActivityRecord))
|
||||||
|
// Shell transitions doesn't use RecentsAnimationController
|
||||||
|
|| getWeak(mActiveRecentsActivity) != null;
|
||||||
if (shouldApplyRecentsInputConsumer) {
|
if (shouldApplyRecentsInputConsumer) {
|
||||||
requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
|
requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
|
||||||
recentsAnimationInputConsumer.mName);
|
recentsAnimationInputConsumer.mName);
|
||||||
@@ -505,6 +533,14 @@ final class InputMonitor {
|
|||||||
mInDrag = inDrag;
|
mInDrag = inDrag;
|
||||||
|
|
||||||
resetInputConsumers(mInputTransaction);
|
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 */);
|
mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */);
|
||||||
updateInputFocusRequest(mRecentsAnimationInputConsumer);
|
updateInputFocusRequest(mRecentsAnimationInputConsumer);
|
||||||
|
|
||||||
@@ -539,6 +575,7 @@ final class InputMonitor {
|
|||||||
|
|
||||||
final int privateFlags = w.mAttrs.privateFlags;
|
final int privateFlags = w.mAttrs.privateFlags;
|
||||||
|
|
||||||
|
// This only works for legacy transitions.
|
||||||
if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
|
if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
|
||||||
if (recentsAnimationController.updateInputConsumerForApp(
|
if (recentsAnimationController.updateInputConsumerForApp(
|
||||||
mRecentsAnimationInputConsumer.mWindowHandle)) {
|
mRecentsAnimationInputConsumer.mWindowHandle)) {
|
||||||
|
|||||||
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
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.ACTIVITY_TYPE_STANDARD;
|
||||||
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
|
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
import static android.view.Display.INVALID_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_SEAMLESS;
|
||||||
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
|
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
|
||||||
import static android.view.WindowManager.TRANSIT_CHANGE;
|
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.
|
// TODO(b/188595497): remove when not needed.
|
||||||
/** @see RecentsAnimationController#mNavigationBarAttachedToApp */
|
/** @see RecentsAnimationController#mNavigationBarAttachedToApp */
|
||||||
private boolean mNavBarAttachedToApp = false;
|
private boolean mNavBarAttachedToApp = false;
|
||||||
private int mNavBarDisplayId = INVALID_DISPLAY;
|
private int mRecentsDisplayId = INVALID_DISPLAY;
|
||||||
|
|
||||||
Transition(@TransitionType int type, @TransitionFlags int flags,
|
Transition(@TransitionType int type, @TransitionFlags int flags,
|
||||||
TransitionController controller, BLASTSyncEngine syncEngine) {
|
TransitionController controller, BLASTSyncEngine syncEngine) {
|
||||||
@@ -176,6 +179,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
return mSyncId;
|
return mSyncId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TransitionFlags
|
||||||
|
int getFlags() {
|
||||||
|
return mFlags;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formally starts the transition. Participants can be collected before this is started,
|
* 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
|
* 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);
|
sendRemoteCallback(mClientAnimationFinishCallback);
|
||||||
|
|
||||||
legacyRestoreNavigationBarFromApp();
|
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() {
|
void abort() {
|
||||||
@@ -560,7 +575,43 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
}
|
}
|
||||||
final DisplayContent dc =
|
final DisplayContent dc =
|
||||||
mController.mAtm.mRootWindowContainer.getDisplayContent(displayId);
|
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.
|
// Skip the case where the nav bar is controlled by fade rotation.
|
||||||
|| dc.getFadeRotationAnimationController() != null) {
|
|| dc.getFadeRotationAnimationController() != null) {
|
||||||
return;
|
return;
|
||||||
@@ -587,7 +638,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mNavBarAttachedToApp = true;
|
mNavBarAttachedToApp = true;
|
||||||
mNavBarDisplayId = displayId;
|
|
||||||
navWindow.mToken.cancelAnimation();
|
navWindow.mToken.cancelAnimation();
|
||||||
final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction();
|
final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction();
|
||||||
final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl();
|
final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl();
|
||||||
@@ -611,12 +661,17 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
if (!mNavBarAttachedToApp) return;
|
if (!mNavBarAttachedToApp) return;
|
||||||
mNavBarAttachedToApp = false;
|
mNavBarAttachedToApp = false;
|
||||||
|
|
||||||
|
if (mRecentsDisplayId == INVALID_DISPLAY) {
|
||||||
|
Slog.e(TAG, "Reparented navigation bar without a valid display");
|
||||||
|
mRecentsDisplayId = DEFAULT_DISPLAY;
|
||||||
|
}
|
||||||
|
|
||||||
if (mController.mStatusBar != null) {
|
if (mController.mStatusBar != null) {
|
||||||
mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mNavBarDisplayId, true);
|
mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
final DisplayContent dc =
|
final DisplayContent dc =
|
||||||
mController.mAtm.mRootWindowContainer.getDisplayContent(mNavBarDisplayId);
|
mController.mAtm.mRootWindowContainer.getDisplayContent(mRecentsDisplayId);
|
||||||
final WindowState navWindow = dc.getDisplayPolicy().getNavigationBar();
|
final WindowState navWindow = dc.getDisplayPolicy().getNavigationBar();
|
||||||
if (navWindow == null) return;
|
if (navWindow == null) return;
|
||||||
navWindow.setSurfaceTranslationY(0);
|
navWindow.setSurfaceTranslationY(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user