diff options
14 files changed, 151 insertions, 170 deletions
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java index e1b042160062..f2d3f5ad08bf 100644 --- a/core/java/android/view/InputChannel.java +++ b/core/java/android/view/InputChannel.java @@ -83,7 +83,7 @@ public final class InputChannel implements Parcelable { * * @hide */ - public void setNativeInputChannel(long nativeChannel) { + private void setNativeInputChannel(long nativeChannel) { if (nativeChannel == 0) { throw new IllegalArgumentException("Attempting to set native input channel to null."); } @@ -148,12 +148,11 @@ public final class InputChannel implements Parcelable { } /** - * Transfers ownership of the internal state of the input channel to another - * instance and invalidates this instance. This is used to pass an input channel + * Creates a copy of this instance to the outParameter. This is used to pass an input channel * as an out parameter in a binder call. * @param other The other input channel instance. */ - public void transferTo(InputChannel outParameter) { + public void copyTo(InputChannel outParameter) { if (outParameter == null) { throw new IllegalArgumentException("outParameter must not be null"); } diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp index 2436b23a45d0..d4a746290baa 100644 --- a/core/jni/android_view_InputChannel.cpp +++ b/core/jni/android_view_InputChannel.cpp @@ -36,6 +36,9 @@ namespace android { static struct { jclass clazz; + jmethodID mCtor; + jmethodID mSetNativeInputChannel; + jfieldID mPtr; // native object attached to the DVM InputChannel } gInputChannelClassInfo; @@ -43,7 +46,7 @@ static struct { class NativeInputChannel { public: - explicit NativeInputChannel(const std::shared_ptr<InputChannel>& inputChannel); + explicit NativeInputChannel(std::unique_ptr<InputChannel> inputChannel); ~NativeInputChannel(); inline std::shared_ptr<InputChannel> getInputChannel() { return mInputChannel; } @@ -59,8 +62,8 @@ private: // ---------------------------------------------------------------------------- -NativeInputChannel::NativeInputChannel(const std::shared_ptr<InputChannel>& inputChannel) - : mInputChannel(inputChannel), mDisposeCallback(nullptr) {} +NativeInputChannel::NativeInputChannel(std::unique_ptr<InputChannel> inputChannel) + : mInputChannel(std::move(inputChannel)), mDisposeCallback(nullptr) {} NativeInputChannel::~NativeInputChannel() { } @@ -110,13 +113,33 @@ void android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChan } static jlong android_view_InputChannel_createInputChannel( - JNIEnv* env, std::shared_ptr<InputChannel> inputChannel) { + JNIEnv* env, std::unique_ptr<InputChannel> inputChannel) { std::unique_ptr<NativeInputChannel> nativeInputChannel = - std::make_unique<NativeInputChannel>(inputChannel); + std::make_unique<NativeInputChannel>(std::move(inputChannel)); return reinterpret_cast<jlong>(nativeInputChannel.release()); } +jobject android_view_InputChannel_createJavaObject(JNIEnv* env, + std::unique_ptr<InputChannel> inputChannel) { + std::string name = inputChannel->getName(); + jlong ptr = android_view_InputChannel_createInputChannel(env, std::move(inputChannel)); + jobject javaInputChannel = + env->NewObject(gInputChannelClassInfo.clazz, gInputChannelClassInfo.mCtor); + if (!javaInputChannel) { + ALOGE("Failed to create a Java InputChannel for channel %s.", name.c_str()); + return nullptr; + } + + env->CallVoidMethod(javaInputChannel, gInputChannelClassInfo.mSetNativeInputChannel, ptr); + if (env->ExceptionOccurred()) { + ALOGE("Failed to set native ptr to the Java InputChannel for channel %s.", + inputChannel->getName().c_str()); + return nullptr; + } + return javaInputChannel; +} + static jlongArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* env, jclass clazz, jstring nameObj) { ScopedUtfChars nameChars(env, nameObj); @@ -180,9 +203,10 @@ static jlong android_view_InputChannel_nativeReadFromParcel(JNIEnv* env, jobject if (parcel) { bool isInitialized = parcel->readInt32(); if (isInitialized) { - std::shared_ptr<InputChannel> inputChannel = std::make_shared<InputChannel>(); + std::unique_ptr<InputChannel> inputChannel = std::make_unique<InputChannel>(); inputChannel->readFromParcel(parcel); - NativeInputChannel* nativeInputChannel = new NativeInputChannel(inputChannel); + NativeInputChannel* nativeInputChannel = + new NativeInputChannel(std::move(inputChannel)); return reinterpret_cast<jlong>(nativeInputChannel); } } @@ -233,13 +257,13 @@ static jlong android_view_InputChannel_nativeDup(JNIEnv* env, jobject obj, jlong return 0; } - std::shared_ptr<InputChannel> dupInputChannel = inputChannel->dup(); + std::unique_ptr<InputChannel> dupInputChannel = inputChannel->dup(); if (dupInputChannel == nullptr) { std::string message = android::base::StringPrintf( "Could not duplicate input channel %s", inputChannel->getName().c_str()); jniThrowRuntimeException(env, message.c_str()); } - return reinterpret_cast<jlong>(new NativeInputChannel(dupInputChannel)); + return reinterpret_cast<jlong>(new NativeInputChannel(std::move(dupInputChannel))); } static jobject android_view_InputChannel_nativeGetToken(JNIEnv* env, jobject obj, jlong channel) { @@ -281,6 +305,11 @@ int register_android_view_InputChannel(JNIEnv* env) { jclass clazz = FindClassOrDie(env, "android/view/InputChannel"); gInputChannelClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); + gInputChannelClassInfo.mCtor = + GetMethodIDOrDie(env, gInputChannelClassInfo.clazz, "<init>", "()V"); + gInputChannelClassInfo.mSetNativeInputChannel = + GetMethodIDOrDie(env, gInputChannelClassInfo.clazz, "setNativeInputChannel", "(J)V"); + gInputChannelClassInfo.mPtr = GetFieldIDOrDie(env, gInputChannelClassInfo.clazz, "mPtr", "J"); return res; diff --git a/core/jni/android_view_InputChannel.h b/core/jni/android_view_InputChannel.h index 8030c96ab19f..50b9aed4b12c 100644 --- a/core/jni/android_view_InputChannel.h +++ b/core/jni/android_view_InputChannel.h @@ -36,6 +36,8 @@ extern std::shared_ptr<InputChannel> android_view_InputChannel_getInputChannel( extern void android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChannelObj, InputChannelObjDisposeCallback callback, void* data = NULL); +extern jobject android_view_InputChannel_createJavaObject( + JNIEnv* env, std::unique_ptr<InputChannel> inputChannel); } // namespace android #endif // _ANDROID_OS_INPUTCHANNEL_H diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 6c14b2cbed09..828591aaa75a 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -219,10 +219,10 @@ public class InputManagerService extends IInputManager.Stub int deviceId, int sourceMask, int sw); private static native boolean nativeHasKeys(long ptr, int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists); - private static native void nativeRegisterInputChannel(long ptr, InputChannel inputChannel); - private static native void nativeRegisterInputMonitor(long ptr, InputChannel inputChannel, - int displayId, boolean isGestureMonitor); - private static native void nativeUnregisterInputChannel(long ptr, IBinder connectionToken); + private static native InputChannel nativeCreateInputChannel(long ptr, String name); + private static native InputChannel nativeCreateInputMonitor(long ptr, int displayId, + boolean isGestureMonitor, String name); + private static native void nativeRemoveInputChannel(long ptr, IBinder connectionToken); private static native void nativePilferPointers(long ptr, IBinder token); private static native void nativeSetInputFilterEnabled(long ptr, boolean enable); private static native void nativeSetInTouchMode(long ptr, boolean inTouchMode); @@ -522,10 +522,8 @@ public class InputManagerService extends IInputManager.Stub throw new IllegalArgumentException("displayId must >= 0."); } - InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName); - nativeRegisterInputMonitor(mPtr, inputChannels[0], displayId, false /*isGestureMonitor*/); - inputChannels[0].dispose(); // don't need to retain the Java object reference - return inputChannels[1]; + return nativeCreateInputMonitor(mPtr, displayId, false /* isGestureMonitor */, + inputChannelName); } /** @@ -552,38 +550,32 @@ public class InputManagerService extends IInputManager.Stub final long ident = Binder.clearCallingIdentity(); try { - InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName); - InputMonitorHost host = new InputMonitorHost(inputChannels[0]); - nativeRegisterInputMonitor( - mPtr, inputChannels[0], displayId, true /*isGestureMonitor*/); + InputChannel inputChannel = nativeCreateInputMonitor( + mPtr, displayId, true /*isGestureMonitor*/, inputChannelName); + InputMonitorHost host = new InputMonitorHost(inputChannel); synchronized (mGestureMonitorPidsLock) { - mGestureMonitorPidsByToken.put(inputChannels[1].getToken(), pid); + mGestureMonitorPidsByToken.put(inputChannel.getToken(), pid); } - return new InputMonitor(inputChannels[1], host); + return new InputMonitor(inputChannel, host); } finally { Binder.restoreCallingIdentity(ident); } } /** - * Registers an input channel so that it can be used as an input event target. The channel is - * registered with a generated token. + * Creates an input channel to be used as an input event target. * - * @param inputChannel The input channel to register. + * @param name The name of this input channel */ - public void registerInputChannel(InputChannel inputChannel) { - if (inputChannel == null) { - throw new IllegalArgumentException("inputChannel must not be null."); - } - - nativeRegisterInputChannel(mPtr, inputChannel); + public InputChannel createInputChannel(String name) { + return nativeCreateInputChannel(mPtr, name); } /** - * Unregisters an input channel. + * Removes an input channel. * @param connectionToken The input channel to unregister. */ - public void unregisterInputChannel(IBinder connectionToken) { + public void removeInputChannel(IBinder connectionToken) { if (connectionToken == null) { throw new IllegalArgumentException("connectionToken must not be null."); } @@ -591,7 +583,7 @@ public class InputManagerService extends IInputManager.Stub mGestureMonitorPidsByToken.remove(connectionToken); } - nativeUnregisterInputChannel(mPtr, connectionToken); + nativeRemoveInputChannel(mPtr, connectionToken); } /** @@ -2455,7 +2447,7 @@ public class InputManagerService extends IInputManager.Stub @Override public void dispose() { - nativeUnregisterInputChannel(mPtr, mInputChannel.getToken()); + nativeRemoveInputChannel(mPtr, mInputChannel.getToken()); mInputChannel.dispose(); } } diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 6e32d0eddaaf..b80ed6be2256 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -258,16 +258,13 @@ class DragState { } class InputInterceptor { - InputChannel mServerChannel, mClientChannel; + InputChannel mClientChannel; DragInputEventReceiver mInputEventReceiver; InputApplicationHandle mDragApplicationHandle; InputWindowHandle mDragWindowHandle; InputInterceptor(Display display) { - InputChannel[] channels = InputChannel.openInputChannelPair("drag"); - mServerChannel = channels[0]; - mClientChannel = channels[1]; - mService.mInputManager.registerInputChannel(mServerChannel); + mClientChannel = mService.mInputManager.createInputChannel("drag"); mInputEventReceiver = new DragInputEventReceiver(mClientChannel, mService.mH.getLooper(), mDragDropController); @@ -278,7 +275,7 @@ class DragState { mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, display.getDisplayId()); mDragWindowHandle.name = "drag"; - mDragWindowHandle.token = mServerChannel.getToken(); + mDragWindowHandle.token = mClientChannel.getToken(); mDragWindowHandle.layoutParamsFlags = 0; mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG; mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; @@ -308,13 +305,11 @@ class DragState { } void tearDown() { - mService.mInputManager.unregisterInputChannel(mServerChannel.getToken()); + mService.mInputManager.removeInputChannel(mClientChannel.getToken()); mInputEventReceiver.dispose(); mInputEventReceiver = null; mClientChannel.dispose(); - mServerChannel.dispose(); mClientChannel = null; - mServerChannel = null; mDragWindowHandle = null; mDragApplicationHandle = null; @@ -326,7 +321,7 @@ class DragState { } InputChannel getInputChannel() { - return mInputInterceptor == null ? null : mInputInterceptor.mServerChannel; + return mInputInterceptor == null ? null : mInputInterceptor.mClientChannel; } InputWindowHandle getInputWindowHandle() { diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java index 2a5bf16e09d0..3b89a24184f0 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -184,23 +184,13 @@ class EmbeddedWindowController { InputChannel openInputChannel() { final String name = getName(); - - final InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); - mInputChannel = inputChannels[0]; - final InputChannel clientChannel = inputChannels[1]; - mWmService.mInputManager.registerInputChannel(mInputChannel); - - if (mInputChannel.getToken() != clientChannel.getToken()) { - throw new IllegalStateException("Client and Server tokens are expected to" - + "be the same"); - } - - return clientChannel; + mInputChannel = mWmService.mInputManager.createInputChannel(name); + return mInputChannel; } void onRemoved() { if (mInputChannel != null) { - mWmService.mInputManager.unregisterInputChannel(mInputChannel.getToken()); + mWmService.mInputManager.removeInputChannel(mInputChannel.getToken()); mInputChannel.dispose(); mInputChannel = null; } diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java index 1d1a2663823c..edb5e853af4f 100644 --- a/services/core/java/com/android/server/wm/InputConsumerImpl.java +++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java @@ -35,7 +35,7 @@ import java.io.PrintWriter; class InputConsumerImpl implements IBinder.DeathRecipient { final WindowManagerService mService; - final InputChannel mServerChannel, mClientChannel; + final InputChannel mClientChannel; final InputApplicationHandle mApplicationHandle; final InputWindowHandle mWindowHandle; @@ -58,16 +58,10 @@ class InputConsumerImpl implements IBinder.DeathRecipient { mClientPid = clientPid; mClientUser = clientUser; - InputChannel[] channels = InputChannel.openInputChannelPair(name); - mServerChannel = channels[0]; + mClientChannel = mService.mInputManager.createInputChannel(name); if (inputChannel != null) { - channels[1].transferTo(inputChannel); - channels[1].dispose(); - mClientChannel = inputChannel; - } else { - mClientChannel = channels[1]; + mClientChannel.copyTo(inputChannel); } - mService.mInputManager.registerInputChannel(mServerChannel); mApplicationHandle = new InputApplicationHandle(new Binder()); mApplicationHandle.name = name; @@ -75,7 +69,7 @@ class InputConsumerImpl implements IBinder.DeathRecipient { mWindowHandle = new InputWindowHandle(mApplicationHandle, displayId); mWindowHandle.name = name; - mWindowHandle.token = mServerChannel.getToken(); + mWindowHandle.token = mClientChannel.getToken(); mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER; mWindowHandle.layoutParamsFlags = 0; mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; @@ -156,9 +150,8 @@ class InputConsumerImpl implements IBinder.DeathRecipient { } void disposeChannelsLw(SurfaceControl.Transaction t) { - mService.mInputManager.unregisterInputChannel(mServerChannel.getToken()); + mService.mInputManager.removeInputChannel(mClientChannel.getToken()); mClientChannel.dispose(); - mServerChannel.dispose(); t.remove(mInputSurface); unlinkFromDeathRecipient(); } diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index 4fe678dc1974..44ce4de529b0 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -191,7 +191,6 @@ public class Letterbox { } private static class InputInterceptor { - final InputChannel mServerChannel; final InputChannel mClientChannel; final InputWindowHandle mWindowHandle; final InputEventReceiver mInputEventReceiver; @@ -201,13 +200,10 @@ public class Letterbox { InputInterceptor(String namePrefix, WindowState win) { mWmService = win.mWmService; final String name = namePrefix + (win.mActivityRecord != null ? win.mActivityRecord : win); - final InputChannel[] channels = InputChannel.openInputChannelPair(name); - mServerChannel = channels[0]; - mClientChannel = channels[1]; + mClientChannel = mWmService.mInputManager.createInputChannel(name); mInputEventReceiver = new SimpleInputReceiver(mClientChannel); - mWmService.mInputManager.registerInputChannel(mServerChannel); - mToken = mServerChannel.getToken(); + mToken = mClientChannel.getToken(); mWindowHandle = new InputWindowHandle(null /* inputApplicationHandle */, win.getDisplayId()); @@ -239,9 +235,8 @@ public class Letterbox { } void dispose() { - mWmService.mInputManager.unregisterInputChannel(mServerChannel.getToken()); + mWmService.mInputManager.removeInputChannel(mToken); mInputEventReceiver.dispose(); - mServerChannel.dispose(); mClientChannel.dispose(); } diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index abe632941b97..a6f0f464c8b3 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -96,7 +96,6 @@ class TaskPositioner implements IBinder.DeathRecipient { boolean mDragEnded; IBinder mClientCallback; - InputChannel mServerChannel; InputChannel mClientChannel; InputApplicationHandle mDragApplicationHandle; InputWindowHandle mDragWindowHandle; @@ -220,10 +219,7 @@ class TaskPositioner implements IBinder.DeathRecipient { } mDisplayContent = displayContent; - final InputChannel[] channels = InputChannel.openInputChannelPair(TAG); - mServerChannel = channels[0]; - mClientChannel = channels[1]; - mService.mInputManager.registerInputChannel(mServerChannel); + mClientChannel = mService.mInputManager.createInputChannel(TAG); mInputEventReceiver = new WindowPositionerEventReceiver( mClientChannel, mService.mAnimationHandler.getLooper(), @@ -237,7 +233,7 @@ class TaskPositioner implements IBinder.DeathRecipient { mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, displayContent.getDisplayId()); mDragWindowHandle.name = TAG; - mDragWindowHandle.token = mServerChannel.getToken(); + mDragWindowHandle.token = mClientChannel.getToken(); mDragWindowHandle.layoutParamsFlags = 0; mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG; mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; @@ -299,14 +295,12 @@ class TaskPositioner implements IBinder.DeathRecipient { } mService.mTaskPositioningController.hideInputSurface(mDisplayContent.getDisplayId()); - mService.mInputManager.unregisterInputChannel(mServerChannel.getToken()); + mService.mInputManager.removeInputChannel(mClientChannel.getToken()); mInputEventReceiver.dispose(); mInputEventReceiver = null; mClientChannel.dispose(); - mServerChannel.dispose(); mClientChannel = null; - mServerChannel = null; mDragWindowHandle = null; mDragApplicationHandle = null; diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java index b9a449f558f0..9d35c25fc546 100644 --- a/services/core/java/com/android/server/wm/TaskPositioningController.java +++ b/services/core/java/com/android/server/wm/TaskPositioningController.java @@ -188,7 +188,7 @@ class TaskPositioningController { transferFocusFromWin = displayContent.mCurrentFocus; } if (!mInputManager.transferTouchFocus( - transferFocusFromWin.mInputChannel, mTaskPositioner.mServerChannel)) { + transferFocusFromWin.mInputChannel, mTaskPositioner.mClientChannel)) { Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus"); cleanUpTaskPositioner(); return false; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8c2619d75201..4519916f278a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7997,8 +7997,7 @@ public class WindowManagerService extends IWindowManager.Stub updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface, name, applicationHandle, flags, privateFlags, type, null /* region */); - clientChannel.transferTo(outInputChannel); - clientChannel.dispose(); + clientChannel.copyTo(outInputChannel); } private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid, diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e4a079d84a2a..1f7457c088c5 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -556,7 +556,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // Input channel and input window handle used by the input dispatcher. final InputWindowHandle mInputWindowHandle; InputChannel mInputChannel; - private InputChannel mClientChannel; // Used to improve performance of toString() private String mStringNameCache; @@ -2478,20 +2477,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP throw new IllegalStateException("Window already has an input channel."); } String name = getName(); - InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); - mInputChannel = inputChannels[0]; - mClientChannel = inputChannels[1]; - mWmService.mInputManager.registerInputChannel(mInputChannel); + mInputChannel = mWmService.mInputManager.createInputChannel(name); mInputWindowHandle.token = mInputChannel.getToken(); if (outInputChannel != null) { - mClientChannel.transferTo(outInputChannel); - mClientChannel.dispose(); - mClientChannel = null; + mInputChannel.copyTo(outInputChannel); } else { // If the window died visible, we setup a fake input channel, so that taps // can still detected by input monitor channel, and we can relaunch the app. // Create fake event receiver that simply reports all events as handled. - mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel); + mDeadWindowEventReceiver = new DeadWindowEventReceiver(mInputChannel); } mWmService.mInputToWindowMap.put(mInputWindowHandle.token, this); } @@ -2504,15 +2498,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // unregister server channel first otherwise it complains about broken channel if (mInputChannel != null) { - mWmService.mInputManager.unregisterInputChannel(mInputChannel.getToken()); + mWmService.mInputManager.removeInputChannel(mInputChannel.getToken()); mInputChannel.dispose(); mInputChannel = null; } - if (mClientChannel != null) { - mClientChannel.dispose(); - mClientChannel = null; - } mWmService.mKeyInterceptionInfoForToken.remove(mInputWindowHandle.token); mWmService.mInputToWindowMap.remove(mInputWindowHandle.token); mInputWindowHandle.token = null; diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 46136ca0647d..17a05f3c7d1a 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -206,10 +206,12 @@ public: void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray); - status_t registerInputChannel(JNIEnv* env, const std::shared_ptr<InputChannel>& inputChannel); - status_t registerInputMonitor(JNIEnv* env, const std::shared_ptr<InputChannel>& inputChannel, - int32_t displayId, bool isGestureMonitor); - status_t unregisterInputChannel(JNIEnv* env, const sp<IBinder>& connectionToken); + base::Result<std::unique_ptr<InputChannel>> createInputChannel(JNIEnv* env, + const std::string& name); + base::Result<std::unique_ptr<InputChannel>> createInputMonitor(JNIEnv* env, int32_t displayId, + bool isGestureMonitor, + const std::string& name); + status_t removeInputChannel(JNIEnv* env, const sp<IBinder>& connectionToken); status_t pilferPointers(const sp<IBinder>& token); void displayRemoved(JNIEnv* env, int32_t displayId); @@ -432,24 +434,22 @@ void NativeInputManager::setDisplayViewports(JNIEnv* env, jobjectArray viewportO InputReaderConfiguration::CHANGE_DISPLAY_INFO); } -status_t NativeInputManager::registerInputChannel( - JNIEnv* /* env */, const std::shared_ptr<InputChannel>& inputChannel) { +base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputChannel( + JNIEnv* /* env */, const std::string& name) { ATRACE_CALL(); - return mInputManager->getDispatcher()->registerInputChannel(inputChannel); + return mInputManager->getDispatcher()->createInputChannel(name); } -status_t NativeInputManager::registerInputMonitor(JNIEnv* /* env */, - const std::shared_ptr<InputChannel>& inputChannel, - int32_t displayId, bool isGestureMonitor) { +base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputMonitor( + JNIEnv* /* env */, int32_t displayId, bool isGestureMonitor, const std::string& name) { ATRACE_CALL(); - return mInputManager->getDispatcher()->registerInputMonitor( - inputChannel, displayId, isGestureMonitor); + return mInputManager->getDispatcher()->createInputMonitor(displayId, isGestureMonitor, name); } -status_t NativeInputManager::unregisterInputChannel(JNIEnv* /* env */, - const sp<IBinder>& connectionToken) { +status_t NativeInputManager::removeInputChannel(JNIEnv* /* env */, + const sp<IBinder>& connectionToken) { ATRACE_CALL(); - return mInputManager->getDispatcher()->unregisterInputChannel(connectionToken); + return mInputManager->getDispatcher()->removeInputChannel(connectionToken); } status_t NativeInputManager::pilferPointers(const sp<IBinder>& token) { @@ -1352,80 +1352,83 @@ static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */, return result; } -static void throwInputChannelNotInitialized(JNIEnv* env) { - jniThrowException(env, "java/lang/IllegalStateException", - "inputChannel is not initialized"); -} - static void handleInputChannelDisposed(JNIEnv* env, jobject /* inputChannelObj */, const std::shared_ptr<InputChannel>& inputChannel, void* data) { NativeInputManager* im = static_cast<NativeInputManager*>(data); - ALOGW("Input channel object '%s' was disposed without first being unregistered with " - "the input manager!", inputChannel->getName().c_str()); - im->unregisterInputChannel(env, inputChannel->getConnectionToken()); + ALOGW("Input channel object '%s' was disposed without first being removed with " + "the input manager!", + inputChannel->getName().c_str()); + im->removeInputChannel(env, inputChannel->getConnectionToken()); } -static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */, - jlong ptr, jobject inputChannelObj) { +static jobject nativeCreateInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, + jstring nameObj) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); - std::shared_ptr<InputChannel> inputChannel = - android_view_InputChannel_getInputChannel(env, inputChannelObj); - if (inputChannel == nullptr) { - throwInputChannelNotInitialized(env); - return; - } + ScopedUtfChars nameChars(env, nameObj); + std::string name = nameChars.c_str(); - status_t status = im->registerInputChannel(env, inputChannel); + base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(env, name); - if (status) { - std::string message; - message += StringPrintf("Failed to register input channel. status=%d", status); + if (!inputChannel) { + std::string message = inputChannel.error().message(); + message += StringPrintf(" Status=%d", inputChannel.error().code()); jniThrowRuntimeException(env, message.c_str()); - return; + return nullptr; + } + + jobject inputChannelObj = + android_view_InputChannel_createJavaObject(env, std::move(*inputChannel)); + if (!inputChannelObj) { + return nullptr; } android_view_InputChannel_setDisposeCallback(env, inputChannelObj, handleInputChannelDisposed, im); + return inputChannelObj; } -static void nativeRegisterInputMonitor(JNIEnv* env, jclass /* clazz */, - jlong ptr, jobject inputChannelObj, jint displayId, jboolean isGestureMonitor) { +static jobject nativeCreateInputMonitor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId, + jboolean isGestureMonitor, jstring nameObj) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); - std::shared_ptr<InputChannel> inputChannel = - android_view_InputChannel_getInputChannel(env, inputChannelObj); - if (inputChannel == nullptr) { - throwInputChannelNotInitialized(env); - return; - } - if (displayId == ADISPLAY_ID_NONE) { std::string message = "InputChannel used as a monitor must be associated with a display"; jniThrowRuntimeException(env, message.c_str()); - return; + return nullptr; } - status_t status = im->registerInputMonitor(env, inputChannel, displayId, isGestureMonitor); + ScopedUtfChars nameChars(env, nameObj); + std::string name = nameChars.c_str(); + + base::Result<std::unique_ptr<InputChannel>> inputChannel = + im->createInputMonitor(env, displayId, isGestureMonitor, name); - if (status) { - std::string message = StringPrintf("Failed to register input channel. status=%d", status); + if (!inputChannel) { + std::string message = inputChannel.error().message(); + message += StringPrintf(" Status=%d", inputChannel.error().code()); jniThrowRuntimeException(env, message.c_str()); - return; + return nullptr; + } + + jobject inputChannelObj = + android_view_InputChannel_createJavaObject(env, std::move(*inputChannel)); + if (!inputChannelObj) { + return nullptr; } + return inputChannelObj; } -static void nativeUnregisterInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, - jobject tokenObj) { +static void nativeRemoveInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); sp<IBinder> token = ibinderForJavaObject(env, tokenObj); - status_t status = im->unregisterInputChannel(env, token); - if (status && status != BAD_VALUE) { // ignore already unregistered channel + status_t status = im->removeInputChannel(env, token); + if (status && status != BAD_VALUE) { // ignore already removed channel std::string message; - message += StringPrintf("Failed to unregister input channel. status=%d", status); + message += StringPrintf("Failed to remove input channel. status=%d", status); jniThrowRuntimeException(env, message.c_str()); } } @@ -1780,12 +1783,11 @@ static const JNINativeMethod gInputManagerMethods[] = { {"nativeGetKeyCodeState", "(JIII)I", (void*)nativeGetKeyCodeState}, {"nativeGetSwitchState", "(JIII)I", (void*)nativeGetSwitchState}, {"nativeHasKeys", "(JII[I[Z)Z", (void*)nativeHasKeys}, - {"nativeRegisterInputChannel", "(JLandroid/view/InputChannel;)V", - (void*)nativeRegisterInputChannel}, - {"nativeRegisterInputMonitor", "(JLandroid/view/InputChannel;IZ)V", - (void*)nativeRegisterInputMonitor}, - {"nativeUnregisterInputChannel", "(JLandroid/os/IBinder;)V", - (void*)nativeUnregisterInputChannel}, + {"nativeCreateInputChannel", "(JLjava/lang/String;)Landroid/view/InputChannel;", + (void*)nativeCreateInputChannel}, + {"nativeCreateInputMonitor", "(JIZLjava/lang/String;)Landroid/view/InputChannel;", + (void*)nativeCreateInputMonitor}, + {"nativeRemoveInputChannel", "(JLandroid/os/IBinder;)V", (void*)nativeRemoveInputChannel}, {"nativePilferPointers", "(JLandroid/os/IBinder;)V", (void*)nativePilferPointers}, {"nativeSetInputFilterEnabled", "(JZ)V", (void*)nativeSetInputFilterEnabled}, {"nativeSetInTouchMode", "(JZ)V", (void*)nativeSetInTouchMode}, diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index 6a29c5b5424a..1d6199eaa793 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -236,6 +236,7 @@ public class SystemServicesTestRule implements TestRule { inputChannels[0].dispose(); mInputChannel = inputChannels[1]; doReturn(mInputChannel).when(mImService).monitorInput(anyString(), anyInt()); + doReturn(mInputChannel).when(mImService).createInputChannel(anyString()); // StatusBarManagerInternal final StatusBarManagerInternal sbmi = mock(StatusBarManagerInternal.class); |