Loading services/core/java/com/android/server/wm/InputMonitor.java +39 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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. */ Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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)) { Loading services/core/java/com/android/server/wm/Transition.java +60 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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 Loading Loading @@ -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() { Loading Loading @@ -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; Loading @@ -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(); Loading @@ -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); Loading Loading
services/core/java/com/android/server/wm/InputMonitor.java +39 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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. */ Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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)) { Loading
services/core/java/com/android/server/wm/Transition.java +60 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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 Loading Loading @@ -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() { Loading Loading @@ -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; Loading @@ -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(); Loading @@ -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); Loading