Loading core/java/android/view/SurfaceControl.java +35 −0 Original line number Diff line number Diff line Loading @@ -224,6 +224,8 @@ public final class SurfaceControl implements Parcelable { private static native void nativeReleaseFrameRateFlexibilityToken(long token); private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject, int transformHint); private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken, IBinder focusedToken, int displayId); @Nullable @GuardedBy("mLock") Loading Loading @@ -3261,6 +3263,39 @@ public final class SurfaceControl implements Parcelable { return this; } /** * Sets focus on the window identified by the input {@code token} if the window is focusable * otherwise the request is dropped. * * If the window is not visible, the request will be queued until the window becomes * visible or the request is overrriden by another request. The currently focused window * will lose focus immediately. This is to send the newly focused window any focus * dispatched events that occur while it is completing its first draw. * * @hide */ public Transaction setFocusedWindow(@NonNull IBinder token, int displayId) { nativeSetFocusedWindow(mNativeObject, token, null /* focusedToken */, displayId); return this; } /** * Set focus on the window identified by the input {@code token} if the window identified by * the input {@code focusedToken} is currently focused. If the {@code focusedToken} does not * have focus, the request is dropped. * * This is used by forward focus transfer requests from clients that host embedded windows, * and want to transfer focus to/from them. * * @hide */ public Transaction requestFocusTransfer(@NonNull IBinder token, @NonNull IBinder focusedToken, int displayId) { nativeSetFocusedWindow(mNativeObject, token, focusedToken, displayId); return this; } /** * Merge the other transaction into this transaction, clearing the * other transaction as if it had been applied. Loading core/jni/android_view_SurfaceControl.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -1541,10 +1541,25 @@ static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) { return reinterpret_cast<jlong>(surfaceControl->getHandle().get()); } static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionObj, jobject toTokenObj, jobject focusedTokenObj, jint displayId) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); if (toTokenObj == NULL) return; sp<IBinder> toToken(ibinderForJavaObject(env, toTokenObj)); sp<IBinder> focusedToken; if (focusedTokenObj != NULL) { focusedToken = ibinderForJavaObject(env, focusedTokenObj); } transaction->setFocusedWindow(toToken, focusedToken, systemTime(SYSTEM_TIME_MONOTONIC), displayId); } // ---------------------------------------------------------------------------- // clang-format off static const JNINativeMethod sSurfaceControlMethods[] = { // clang-format off {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J", (void*)nativeCreate }, {"nativeReadFromParcel", "(Landroid/os/Parcel;)J", Loading Loading @@ -1721,7 +1736,11 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetGlobalShadowSettings }, {"nativeGetHandle", "(J)J", (void*)nativeGetHandle }, {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Landroid/os/IBinder;I)V", (void*)nativeSetFocusedWindow}, // clang-format on }; // clang-format on Loading data/etc/services.core.protolog.json +12 −0 Original line number Diff line number Diff line Loading @@ -1393,6 +1393,12 @@ "group": "WM_SHOW_SURFACE_ALLOC", "at": "com\/android\/server\/wm\/BlackFrame.java" }, "155482615": { "message": "Focus requested for window=%s", "level": "VERBOSE", "group": "WM_DEBUG_FOCUS_LIGHT", "at": "com\/android\/server\/wm\/InputMonitor.java" }, "174572959": { "message": "DisplayArea info changed name=%s", "level": "VERBOSE", Loading Loading @@ -2635,6 +2641,12 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java" }, "2081291430": { "message": "Focus not requested for window=%s because it has no surface", "level": "DEBUG", "group": "WM_DEBUG_FOCUS_LIGHT", "at": "com\/android\/server\/wm\/InputMonitor.java" }, "2083556954": { "message": "Set mOrientationChanging of %s", "level": "VERBOSE", Loading services/core/java/com/android/server/wm/DisplayContent.java +6 −0 Original line number Diff line number Diff line Loading @@ -618,6 +618,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ private boolean mInEnsureActivitiesVisible = false; /** * Last window to be requested focus via {@code SurfaceControl.Transaction#setFocusedWindow} to * prevent duplicate requests to input. */ WindowState mLastRequestedFocus = null; private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> { WindowStateAnimator winAnimator = w.mWinAnimator; final ActivityRecord activity = w.mActivityRecord; Loading services/core/java/com/android/server/wm/InputMonitor.java +32 −7 Original line number Diff line number Diff line Loading @@ -275,7 +275,7 @@ final class InputMonitor { void populateInputWindowHandle(final InputWindowHandle inputWindowHandle, final WindowState child, int flags, final int type, final boolean isVisible, final boolean hasFocus, final boolean hasWallpaper) { final boolean focusable, final boolean hasWallpaper) { // Add a window to our list of input windows. inputWindowHandle.name = child.toString(); flags = child.getSurfaceTouchableRegion(inputWindowHandle, flags); Loading @@ -283,7 +283,7 @@ final class InputMonitor { inputWindowHandle.layoutParamsType = type; inputWindowHandle.dispatchingTimeoutMillis = child.getInputDispatchingTimeoutMillis(); inputWindowHandle.visible = isVisible; inputWindowHandle.focusable = hasFocus; inputWindowHandle.focusable = focusable; inputWindowHandle.hasWallpaper = hasWallpaper; inputWindowHandle.paused = child.mActivityRecord != null ? child.mActivityRecord.paused : false; inputWindowHandle.ownerPid = child.mSession.mPid; Loading Loading @@ -472,8 +472,9 @@ final class InputMonitor { resetInputConsumers(mInputTransaction); mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */); mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */); updateInputFocusRequest(); if (!mUpdateInputWindowsImmediately) { mDisplayContent.getPendingTransaction().merge(mInputTransaction); Loading @@ -483,6 +484,29 @@ final class InputMonitor { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } private void updateInputFocusRequest() { if (mDisplayContent.mLastRequestedFocus == mDisplayContent.mCurrentFocus) { return; } final WindowState focus = mDisplayContent.mCurrentFocus; if (focus == null || focus.mInputWindowHandle.token == null) { mDisplayContent.mLastRequestedFocus = focus; return; } if (!focus.mWinAnimator.hasSurface()) { ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Focus not requested for window=%s because it has no surface", focus); return; } mInputTransaction.setFocusedWindow(focus.mInputWindowHandle.token, mDisplayId); mDisplayContent.mLastRequestedFocus = focus; ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Focus requested for window=%s", focus); } @Override public void accept(WindowState w) { final InputChannel inputChannel = w.mInputChannel; Loading Loading @@ -510,11 +534,12 @@ final class InputMonitor { final int flags = w.mAttrs.flags; final int privateFlags = w.mAttrs.privateFlags; final boolean hasFocus = w.isFocused(); final boolean focusable = w.canReceiveKeys() && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop()); if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) { if (recentsAnimationController.updateInputConsumerForApp( mRecentsAnimationInputConsumer.mWindowHandle, hasFocus)) { mRecentsAnimationInputConsumer.mWindowHandle, focusable)) { mRecentsAnimationInputConsumer.show(mInputTransaction, w); mAddRecentsAnimationInputConsumerHandle = false; } Loading Loading @@ -559,7 +584,7 @@ final class InputMonitor { } populateInputWindowHandle( inputWindowHandle, w, flags, type, isVisible, hasFocus, hasWallpaper); inputWindowHandle, w, flags, type, isVisible, focusable, hasWallpaper); // register key interception info mService.mKeyInterceptionInfoForToken.put(inputWindowHandle.token, Loading Loading
core/java/android/view/SurfaceControl.java +35 −0 Original line number Diff line number Diff line Loading @@ -224,6 +224,8 @@ public final class SurfaceControl implements Parcelable { private static native void nativeReleaseFrameRateFlexibilityToken(long token); private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject, int transformHint); private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken, IBinder focusedToken, int displayId); @Nullable @GuardedBy("mLock") Loading Loading @@ -3261,6 +3263,39 @@ public final class SurfaceControl implements Parcelable { return this; } /** * Sets focus on the window identified by the input {@code token} if the window is focusable * otherwise the request is dropped. * * If the window is not visible, the request will be queued until the window becomes * visible or the request is overrriden by another request. The currently focused window * will lose focus immediately. This is to send the newly focused window any focus * dispatched events that occur while it is completing its first draw. * * @hide */ public Transaction setFocusedWindow(@NonNull IBinder token, int displayId) { nativeSetFocusedWindow(mNativeObject, token, null /* focusedToken */, displayId); return this; } /** * Set focus on the window identified by the input {@code token} if the window identified by * the input {@code focusedToken} is currently focused. If the {@code focusedToken} does not * have focus, the request is dropped. * * This is used by forward focus transfer requests from clients that host embedded windows, * and want to transfer focus to/from them. * * @hide */ public Transaction requestFocusTransfer(@NonNull IBinder token, @NonNull IBinder focusedToken, int displayId) { nativeSetFocusedWindow(mNativeObject, token, focusedToken, displayId); return this; } /** * Merge the other transaction into this transaction, clearing the * other transaction as if it had been applied. Loading
core/jni/android_view_SurfaceControl.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -1541,10 +1541,25 @@ static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) { return reinterpret_cast<jlong>(surfaceControl->getHandle().get()); } static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionObj, jobject toTokenObj, jobject focusedTokenObj, jint displayId) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); if (toTokenObj == NULL) return; sp<IBinder> toToken(ibinderForJavaObject(env, toTokenObj)); sp<IBinder> focusedToken; if (focusedTokenObj != NULL) { focusedToken = ibinderForJavaObject(env, focusedTokenObj); } transaction->setFocusedWindow(toToken, focusedToken, systemTime(SYSTEM_TIME_MONOTONIC), displayId); } // ---------------------------------------------------------------------------- // clang-format off static const JNINativeMethod sSurfaceControlMethods[] = { // clang-format off {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J", (void*)nativeCreate }, {"nativeReadFromParcel", "(Landroid/os/Parcel;)J", Loading Loading @@ -1721,7 +1736,11 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetGlobalShadowSettings }, {"nativeGetHandle", "(J)J", (void*)nativeGetHandle }, {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Landroid/os/IBinder;I)V", (void*)nativeSetFocusedWindow}, // clang-format on }; // clang-format on Loading
data/etc/services.core.protolog.json +12 −0 Original line number Diff line number Diff line Loading @@ -1393,6 +1393,12 @@ "group": "WM_SHOW_SURFACE_ALLOC", "at": "com\/android\/server\/wm\/BlackFrame.java" }, "155482615": { "message": "Focus requested for window=%s", "level": "VERBOSE", "group": "WM_DEBUG_FOCUS_LIGHT", "at": "com\/android\/server\/wm\/InputMonitor.java" }, "174572959": { "message": "DisplayArea info changed name=%s", "level": "VERBOSE", Loading Loading @@ -2635,6 +2641,12 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java" }, "2081291430": { "message": "Focus not requested for window=%s because it has no surface", "level": "DEBUG", "group": "WM_DEBUG_FOCUS_LIGHT", "at": "com\/android\/server\/wm\/InputMonitor.java" }, "2083556954": { "message": "Set mOrientationChanging of %s", "level": "VERBOSE", Loading
services/core/java/com/android/server/wm/DisplayContent.java +6 −0 Original line number Diff line number Diff line Loading @@ -618,6 +618,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ private boolean mInEnsureActivitiesVisible = false; /** * Last window to be requested focus via {@code SurfaceControl.Transaction#setFocusedWindow} to * prevent duplicate requests to input. */ WindowState mLastRequestedFocus = null; private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> { WindowStateAnimator winAnimator = w.mWinAnimator; final ActivityRecord activity = w.mActivityRecord; Loading
services/core/java/com/android/server/wm/InputMonitor.java +32 −7 Original line number Diff line number Diff line Loading @@ -275,7 +275,7 @@ final class InputMonitor { void populateInputWindowHandle(final InputWindowHandle inputWindowHandle, final WindowState child, int flags, final int type, final boolean isVisible, final boolean hasFocus, final boolean hasWallpaper) { final boolean focusable, final boolean hasWallpaper) { // Add a window to our list of input windows. inputWindowHandle.name = child.toString(); flags = child.getSurfaceTouchableRegion(inputWindowHandle, flags); Loading @@ -283,7 +283,7 @@ final class InputMonitor { inputWindowHandle.layoutParamsType = type; inputWindowHandle.dispatchingTimeoutMillis = child.getInputDispatchingTimeoutMillis(); inputWindowHandle.visible = isVisible; inputWindowHandle.focusable = hasFocus; inputWindowHandle.focusable = focusable; inputWindowHandle.hasWallpaper = hasWallpaper; inputWindowHandle.paused = child.mActivityRecord != null ? child.mActivityRecord.paused : false; inputWindowHandle.ownerPid = child.mSession.mPid; Loading Loading @@ -472,8 +472,9 @@ final class InputMonitor { resetInputConsumers(mInputTransaction); mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */); mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */); updateInputFocusRequest(); if (!mUpdateInputWindowsImmediately) { mDisplayContent.getPendingTransaction().merge(mInputTransaction); Loading @@ -483,6 +484,29 @@ final class InputMonitor { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } private void updateInputFocusRequest() { if (mDisplayContent.mLastRequestedFocus == mDisplayContent.mCurrentFocus) { return; } final WindowState focus = mDisplayContent.mCurrentFocus; if (focus == null || focus.mInputWindowHandle.token == null) { mDisplayContent.mLastRequestedFocus = focus; return; } if (!focus.mWinAnimator.hasSurface()) { ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Focus not requested for window=%s because it has no surface", focus); return; } mInputTransaction.setFocusedWindow(focus.mInputWindowHandle.token, mDisplayId); mDisplayContent.mLastRequestedFocus = focus; ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Focus requested for window=%s", focus); } @Override public void accept(WindowState w) { final InputChannel inputChannel = w.mInputChannel; Loading Loading @@ -510,11 +534,12 @@ final class InputMonitor { final int flags = w.mAttrs.flags; final int privateFlags = w.mAttrs.privateFlags; final boolean hasFocus = w.isFocused(); final boolean focusable = w.canReceiveKeys() && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop()); if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) { if (recentsAnimationController.updateInputConsumerForApp( mRecentsAnimationInputConsumer.mWindowHandle, hasFocus)) { mRecentsAnimationInputConsumer.mWindowHandle, focusable)) { mRecentsAnimationInputConsumer.show(mInputTransaction, w); mAddRecentsAnimationInputConsumerHandle = false; } Loading Loading @@ -559,7 +584,7 @@ final class InputMonitor { } populateInputWindowHandle( inputWindowHandle, w, flags, type, isVisible, hasFocus, hasWallpaper); inputWindowHandle, w, flags, type, isVisible, focusable, hasWallpaper); // register key interception info mService.mKeyInterceptionInfoForToken.put(inputWindowHandle.token, Loading