diff options
6 files changed, 63 insertions, 12 deletions
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp index 0c6dac02453a..da21438bafd1 100644 --- a/libs/input/SpriteController.cpp +++ b/libs/input/SpriteController.cpp @@ -27,10 +27,12 @@ namespace android { // --- SpriteController --- -SpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer) : - mLooper(looper), mOverlayLayer(overlayLayer) { +SpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer, + ParentSurfaceProvider parentSurfaceProvider) + : mLooper(looper), + mOverlayLayer(overlayLayer), + mParentSurfaceProvider(std::move(parentSurfaceProvider)) { mHandler = new WeakMessageHandler(this); - mLocked.transactionNestingCount = 0; mLocked.deferredSpriteUpdate = false; } @@ -168,8 +170,7 @@ void SpriteController::doUpdateSprites() { // If surface is a new one, we have to set right layer stack. if (update.surfaceChanged || update.state.dirty & DIRTY_DISPLAY_ID) { - t.setLayerStack(update.state.surfaceControl, - ui::LayerStack::fromValue(update.state.displayId)); + t.reparent(update.state.surfaceControl, mParentSurfaceProvider(update.state.displayId)); needApplyTransaction = true; } } diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h index 137b5646feae..2a80d9579711 100644 --- a/libs/input/SpriteController.h +++ b/libs/input/SpriteController.h @@ -114,7 +114,8 @@ protected: virtual ~SpriteController(); public: - SpriteController(const sp<Looper>& looper, int32_t overlayLayer); + using ParentSurfaceProvider = std::function<sp<SurfaceControl>(int /*displayId*/)>; + SpriteController(const sp<Looper>& looper, int32_t overlayLayer, ParentSurfaceProvider parent); /* Creates a new sprite, initially invisible. */ virtual sp<Sprite> createSprite(); @@ -245,6 +246,7 @@ private: sp<Looper> mLooper; const int32_t mOverlayLayer; sp<WeakMessageHandler> mHandler; + ParentSurfaceProvider mParentSurfaceProvider; sp<SurfaceComposerClient> mSurfaceComposerClient; diff --git a/libs/input/tests/mocks/MockSpriteController.h b/libs/input/tests/mocks/MockSpriteController.h index a034f66c9abf..62f1d65e77a5 100644 --- a/libs/input/tests/mocks/MockSpriteController.h +++ b/libs/input/tests/mocks/MockSpriteController.h @@ -26,7 +26,8 @@ namespace android { class MockSpriteController : public SpriteController { public: - MockSpriteController(sp<Looper> looper) : SpriteController(looper, 0) {} + MockSpriteController(sp<Looper> looper) + : SpriteController(looper, 0, [](int) { return nullptr; }) {} ~MockSpriteController() {} MOCK_METHOD(sp<Sprite>, createSprite, (), (override)); diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 15d2a056ffbb..3d04037185f3 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -98,6 +98,7 @@ import android.view.InputMonitor; import android.view.KeyEvent; import android.view.PointerIcon; import android.view.Surface; +import android.view.SurfaceControl; import android.view.VerifiedInputEvent; import android.view.ViewConfiguration; import android.widget.Toast; @@ -2906,6 +2907,15 @@ public class InputManagerService extends IInputManager.Stub return PointerIcon.getDefaultIcon(getContextForPointerIcon(displayId)); } + // Native callback. + private long getParentSurfaceForPointers(int displayId) { + final SurfaceControl sc = mWindowManagerCallbacks.getParentSurfaceForPointers(displayId); + if (sc == null) { + return 0; + } + return sc.mNativeObject; + } + @NonNull private Context getContextForPointerIcon(int displayId) { if (mPointerIconDisplayContext != null @@ -3105,6 +3115,12 @@ public class InputManagerService extends IInputManager.Stub * Called when the drag over window has changed. */ void notifyDropWindow(IBinder token, float x, float y); + + /** + * Get the {@link SurfaceControl} that should be the parent for the surfaces created for + * pointers such as the mouse cursor and touch spots for the given display. + */ + SurfaceControl getParentSurfaceForPointers(int displayId); } /** diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java index 18a2c601f6d3..e02e7c5ab15d 100644 --- a/services/core/java/com/android/server/wm/InputManagerCallback.java +++ b/services/core/java/com/android/server/wm/InputManagerCallback.java @@ -29,6 +29,7 @@ import android.os.IBinder; import android.util.Slog; import android.view.InputApplicationHandle; import android.view.KeyEvent; +import android.view.SurfaceControl; import android.view.WindowManager; import android.view.WindowManagerPolicyConstants; @@ -234,6 +235,19 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal mService.mDragDropController::reportDropWindow, token, x, y)); } + @Override + public SurfaceControl getParentSurfaceForPointers(int displayId) { + synchronized (mService.mGlobalLock) { + final DisplayContent dc = mService.mRoot.getDisplayContent(displayId); + if (dc == null) { + Slog.e(TAG, "Failed to get parent surface for pointers on display " + displayId + + " - DisplayContent not found."); + return null; + } + return dc.getOverlayLayer(); + } + } + /** Waits until the built-in input devices have been configured. */ public boolean waitForInputDevicesReady(long timeoutMillis) { synchronized (mInputDevicesReadyMonitor) { diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 790acbf2cd23..85e7f7b5226b 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -129,6 +129,7 @@ static struct { jmethodID getTouchCalibrationForInputDevice; jmethodID getContextForDisplay; jmethodID notifyDropWindow; + jmethodID getParentSurfaceForPointers; } gServiceClassInfo; static struct { @@ -390,7 +391,7 @@ private: void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags); void ensureSpriteControllerLocked(); int32_t getPointerDisplayId(); - void updatePointerDisplayLocked(); + sp<SurfaceControl> getParentSurfaceForPointers(int displayId); static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName); static inline JNIEnv* jniEnv() { @@ -669,6 +670,18 @@ int32_t NativeInputManager::getPointerDisplayId() { return pointerDisplayId; } +sp<SurfaceControl> NativeInputManager::getParentSurfaceForPointers(int displayId) { + JNIEnv* env = jniEnv(); + jlong nativeSurfaceControlPtr = + env->CallLongMethod(mServiceObj, gServiceClassInfo.getParentSurfaceForPointers, + displayId); + if (checkAndClearExceptionFromCallback(env, "getParentSurfaceForPointers")) { + return nullptr; + } + + return reinterpret_cast<SurfaceControl*>(nativeSurfaceControlPtr); +} + void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) { if (mLocked.spriteController == nullptr) { JNIEnv* env = jniEnv(); @@ -676,7 +689,9 @@ void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) { if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) { layer = -1; } - mLocked.spriteController = new SpriteController(mLooper, layer); + mLocked.spriteController = new SpriteController(mLooper, layer, [this](int displayId) { + return getParentSurfaceForPointers(displayId); + }); } } @@ -2504,9 +2519,11 @@ int register_android_server_InputManager(JNIEnv* env) { "getTouchCalibrationForInputDevice", "(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;"); - GET_METHOD_ID(gServiceClassInfo.getContextForDisplay, clazz, - "getContextForDisplay", - "(I)Landroid/content/Context;") + GET_METHOD_ID(gServiceClassInfo.getContextForDisplay, clazz, "getContextForDisplay", + "(I)Landroid/content/Context;"); + + GET_METHOD_ID(gServiceClassInfo.getParentSurfaceForPointers, clazz, + "getParentSurfaceForPointers", "(I)J"); // InputDevice |