diff options
| author | 2020-09-22 21:53:55 +0000 | |
|---|---|---|
| committer | 2020-09-22 21:53:55 +0000 | |
| commit | e97ad446cb24e4724ebaa34ff829ad5ae2b372bc (patch) | |
| tree | d83a46e8ee27eecc7492600c3b8241965dbbc4b6 | |
| parent | c27066ac9f8981ef1fe39870e635205b1ebdfc05 (diff) | |
Revert "Reland "Use new create/removeInputChannel().""
Revert "Reland "Let InputFlinger create the server InputChannel""
Revert submission 12655292-hide-server-input-channel
Reason for revert: b/169173706
Reverted Changes:
Iefbfd9313:Reland "Let InputFlinger create the server InputCh...
I14837d545:Reland "Use new create/removeInputChannel()."
Change-Id: I2e002829ad2f077e1f118d0b09d274002b71afa9
14 files changed, 170 insertions, 151 deletions
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java index f2d3f5ad08bf..e1b042160062 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 */ - private void setNativeInputChannel(long nativeChannel) { + public void setNativeInputChannel(long nativeChannel) { if (nativeChannel == 0) { throw new IllegalArgumentException("Attempting to set native input channel to null."); } @@ -148,11 +148,12 @@ public final class InputChannel implements Parcelable { } /** - * Creates a copy of this instance to the outParameter. This is used to pass an input channel + * 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 * as an out parameter in a binder call. * @param other The other input channel instance. */ - public void copyTo(InputChannel outParameter) { + public void transferTo(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 d4a746290baa..2436b23a45d0 100644 --- a/core/jni/android_view_InputChannel.cpp +++ b/core/jni/android_view_InputChannel.cpp @@ -36,9 +36,6 @@ namespace android { static struct { jclass clazz; - jmethodID mCtor; - jmethodID mSetNativeInputChannel; - jfieldID mPtr; // native object attached to the DVM InputChannel } gInputChannelClassInfo; @@ -46,7 +43,7 @@ static struct { class NativeInputChannel { public: - explicit NativeInputChannel(std::unique_ptr<InputChannel> inputChannel); + explicit NativeInputChannel(const std::shared_ptr<InputChannel>& inputChannel); ~NativeInputChannel(); inline std::shared_ptr<InputChannel> getInputChannel() { return mInputChannel; } @@ -62,8 +59,8 @@ private: // ---------------------------------------------------------------------------- -NativeInputChannel::NativeInputChannel(std::unique_ptr<InputChannel> inputChannel) - : mInputChannel(std::move(inputChannel)), mDisposeCallback(nullptr) {} +NativeInputChannel::NativeInputChannel(const std::shared_ptr<InputChannel>& inputChannel) + : mInputChannel(inputChannel), mDisposeCallback(nullptr) {} NativeInputChannel::~NativeInputChannel() { } @@ -113,33 +110,13 @@ void android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChan } static jlong android_view_InputChannel_createInputChannel( - JNIEnv* env, std::unique_ptr<InputChannel> inputChannel) { + JNIEnv* env, std::shared_ptr<InputChannel> inputChannel) { std::unique_ptr<NativeInputChannel> nativeInputChannel = - std::make_unique<NativeInputChannel>(std::move(inputChannel)); + std::make_unique<NativeInputChannel>(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); @@ -203,10 +180,9 @@ static jlong android_view_InputChannel_nativeReadFromParcel(JNIEnv* env, jobject if (parcel) { bool isInitialized = parcel->readInt32(); if (isInitialized) { - std::unique_ptr<InputChannel> inputChannel = std::make_unique<InputChannel>(); + std::shared_ptr<InputChannel> inputChannel = std::make_shared<InputChannel>(); inputChannel->readFromParcel(parcel); - NativeInputChannel* nativeInputChannel = - new NativeInputChannel(std::move(inputChannel)); + NativeInputChannel* nativeInputChannel = new NativeInputChannel(inputChannel); return reinterpret_cast<jlong>(nativeInputChannel); } } @@ -257,13 +233,13 @@ static jlong android_view_InputChannel_nativeDup(JNIEnv* env, jobject obj, jlong return 0; } - std::unique_ptr<InputChannel> dupInputChannel = inputChannel->dup(); + std::shared_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(std::move(dupInputChannel))); + return reinterpret_cast<jlong>(new NativeInputChannel(dupInputChannel)); } static jobject android_view_InputChannel_nativeGetToken(JNIEnv* env, jobject obj, jlong channel) { @@ -305,11 +281,6 @@ 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 50b9aed4b12c..8030c96ab19f 100644 --- a/core/jni/android_view_InputChannel.h +++ b/core/jni/android_view_InputChannel.h @@ -36,8 +36,6 @@ 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 828591aaa75a..6c14b2cbed09 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 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 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 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,8 +522,10 @@ public class InputManagerService extends IInputManager.Stub throw new IllegalArgumentException("displayId must >= 0."); } - return nativeCreateInputMonitor(mPtr, displayId, false /* isGestureMonitor */, - inputChannelName); + 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]; } /** @@ -550,32 +552,38 @@ public class InputManagerService extends IInputManager.Stub final long ident = Binder.clearCallingIdentity(); try { - InputChannel inputChannel = nativeCreateInputMonitor( - mPtr, displayId, true /*isGestureMonitor*/, inputChannelName); - InputMonitorHost host = new InputMonitorHost(inputChannel); + InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName); + InputMonitorHost host = new InputMonitorHost(inputChannels[0]); + nativeRegisterInputMonitor( + mPtr, inputChannels[0], displayId, true /*isGestureMonitor*/); synchronized (mGestureMonitorPidsLock) { - mGestureMonitorPidsByToken.put(inputChannel.getToken(), pid); + mGestureMonitorPidsByToken.put(inputChannels[1].getToken(), pid); } - return new InputMonitor(inputChannel, host); + return new InputMonitor(inputChannels[1], host); } finally { Binder.restoreCallingIdentity(ident); } } /** - * Creates an input channel to be used as an input event target. + * Registers an input channel so that it can be used as an input event target. The channel is + * registered with a generated token. * - * @param name The name of this input channel + * @param inputChannel The input channel to register. */ - public InputChannel createInputChannel(String name) { - return nativeCreateInputChannel(mPtr, name); + public void registerInputChannel(InputChannel inputChannel) { + if (inputChannel == null) { + throw new IllegalArgumentException("inputChannel must not be null."); + } + + nativeRegisterInputChannel(mPtr, inputChannel); } /** - * Removes an input channel. + * Unregisters an input channel. * @param connectionToken The input channel to unregister. */ - public void removeInputChannel(IBinder connectionToken) { + public void unregisterInputChannel(IBinder connectionToken) { if (connectionToken == null) { throw new IllegalArgumentException("connectionToken must not be null."); } @@ -583,7 +591,7 @@ public class InputManagerService extends IInputManager.Stub mGestureMonitorPidsByToken.remove(connectionToken); } - nativeRemoveInputChannel(mPtr, connectionToken); + nativeUnregisterInputChannel(mPtr, connectionToken); } /** @@ -2447,7 +2455,7 @@ public class InputManagerService extends IInputManager.Stub @Override public void dispose() { - nativeRemoveInputChannel(mPtr, mInputChannel.getToken()); + nativeUnregisterInputChannel(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 b80ed6be2256..6e32d0eddaaf 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -258,13 +258,16 @@ class DragState { } class InputInterceptor { - InputChannel mClientChannel; + InputChannel mServerChannel, mClientChannel; DragInputEventReceiver mInputEventReceiver; InputApplicationHandle mDragApplicationHandle; InputWindowHandle mDragWindowHandle; InputInterceptor(Display display) { - mClientChannel = mService.mInputManager.createInputChannel("drag"); + InputChannel[] channels = InputChannel.openInputChannelPair("drag"); + mServerChannel = channels[0]; + mClientChannel = channels[1]; + mService.mInputManager.registerInputChannel(mServerChannel); mInputEventReceiver = new DragInputEventReceiver(mClientChannel, mService.mH.getLooper(), mDragDropController); @@ -275,7 +278,7 @@ class DragState { mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, display.getDisplayId()); mDragWindowHandle.name = "drag"; - mDragWindowHandle.token = mClientChannel.getToken(); + mDragWindowHandle.token = mServerChannel.getToken(); mDragWindowHandle.layoutParamsFlags = 0; mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG; mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; @@ -305,11 +308,13 @@ class DragState { } void tearDown() { - mService.mInputManager.removeInputChannel(mClientChannel.getToken()); + mService.mInputManager.unregisterInputChannel(mServerChannel.getToken()); mInputEventReceiver.dispose(); mInputEventReceiver = null; mClientChannel.dispose(); + mServerChannel.dispose(); mClientChannel = null; + mServerChannel = null; mDragWindowHandle = null; mDragApplicationHandle = null; @@ -321,7 +326,7 @@ class DragState { } InputChannel getInputChannel() { - return mInputInterceptor == null ? null : mInputInterceptor.mClientChannel; + return mInputInterceptor == null ? null : mInputInterceptor.mServerChannel; } 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 3b89a24184f0..2a5bf16e09d0 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -184,13 +184,23 @@ class EmbeddedWindowController { InputChannel openInputChannel() { final String name = getName(); - mInputChannel = mWmService.mInputManager.createInputChannel(name); - return mInputChannel; + + 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; } void onRemoved() { if (mInputChannel != null) { - mWmService.mInputManager.removeInputChannel(mInputChannel.getToken()); + mWmService.mInputManager.unregisterInputChannel(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 edb5e853af4f..1d1a2663823c 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 mClientChannel; + final InputChannel mServerChannel, mClientChannel; final InputApplicationHandle mApplicationHandle; final InputWindowHandle mWindowHandle; @@ -58,10 +58,16 @@ class InputConsumerImpl implements IBinder.DeathRecipient { mClientPid = clientPid; mClientUser = clientUser; - mClientChannel = mService.mInputManager.createInputChannel(name); + InputChannel[] channels = InputChannel.openInputChannelPair(name); + mServerChannel = channels[0]; if (inputChannel != null) { - mClientChannel.copyTo(inputChannel); + channels[1].transferTo(inputChannel); + channels[1].dispose(); + mClientChannel = inputChannel; + } else { + mClientChannel = channels[1]; } + mService.mInputManager.registerInputChannel(mServerChannel); mApplicationHandle = new InputApplicationHandle(new Binder()); mApplicationHandle.name = name; @@ -69,7 +75,7 @@ class InputConsumerImpl implements IBinder.DeathRecipient { mWindowHandle = new InputWindowHandle(mApplicationHandle, displayId); mWindowHandle.name = name; - mWindowHandle.token = mClientChannel.getToken(); + mWindowHandle.token = mServerChannel.getToken(); mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER; mWindowHandle.layoutParamsFlags = 0; mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; @@ -150,8 +156,9 @@ class InputConsumerImpl implements IBinder.DeathRecipient { } void disposeChannelsLw(SurfaceControl.Transaction t) { - mService.mInputManager.removeInputChannel(mClientChannel.getToken()); + mService.mInputManager.unregisterInputChannel(mServerChannel.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 44ce4de529b0..4fe678dc1974 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -191,6 +191,7 @@ public class Letterbox { } private static class InputInterceptor { + final InputChannel mServerChannel; final InputChannel mClientChannel; final InputWindowHandle mWindowHandle; final InputEventReceiver mInputEventReceiver; @@ -200,10 +201,13 @@ public class Letterbox { InputInterceptor(String namePrefix, WindowState win) { mWmService = win.mWmService; final String name = namePrefix + (win.mActivityRecord != null ? win.mActivityRecord : win); - mClientChannel = mWmService.mInputManager.createInputChannel(name); + final InputChannel[] channels = InputChannel.openInputChannelPair(name); + mServerChannel = channels[0]; + mClientChannel = channels[1]; mInputEventReceiver = new SimpleInputReceiver(mClientChannel); - mToken = mClientChannel.getToken(); + mWmService.mInputManager.registerInputChannel(mServerChannel); + mToken = mServerChannel.getToken(); mWindowHandle = new InputWindowHandle(null /* inputApplicationHandle */, win.getDisplayId()); @@ -235,8 +239,9 @@ public class Letterbox { } void dispose() { - mWmService.mInputManager.removeInputChannel(mToken); + mWmService.mInputManager.unregisterInputChannel(mServerChannel.getToken()); 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 a6f0f464c8b3..abe632941b97 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -96,6 +96,7 @@ class TaskPositioner implements IBinder.DeathRecipient { boolean mDragEnded; IBinder mClientCallback; + InputChannel mServerChannel; InputChannel mClientChannel; InputApplicationHandle mDragApplicationHandle; InputWindowHandle mDragWindowHandle; @@ -219,7 +220,10 @@ class TaskPositioner implements IBinder.DeathRecipient { } mDisplayContent = displayContent; - mClientChannel = mService.mInputManager.createInputChannel(TAG); + final InputChannel[] channels = InputChannel.openInputChannelPair(TAG); + mServerChannel = channels[0]; + mClientChannel = channels[1]; + mService.mInputManager.registerInputChannel(mServerChannel); mInputEventReceiver = new WindowPositionerEventReceiver( mClientChannel, mService.mAnimationHandler.getLooper(), @@ -233,7 +237,7 @@ class TaskPositioner implements IBinder.DeathRecipient { mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, displayContent.getDisplayId()); mDragWindowHandle.name = TAG; - mDragWindowHandle.token = mClientChannel.getToken(); + mDragWindowHandle.token = mServerChannel.getToken(); mDragWindowHandle.layoutParamsFlags = 0; mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG; mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; @@ -295,12 +299,14 @@ class TaskPositioner implements IBinder.DeathRecipient { } mService.mTaskPositioningController.hideInputSurface(mDisplayContent.getDisplayId()); - mService.mInputManager.removeInputChannel(mClientChannel.getToken()); + mService.mInputManager.unregisterInputChannel(mServerChannel.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 9d35c25fc546..b9a449f558f0 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.mClientChannel)) { + transferFocusFromWin.mInputChannel, mTaskPositioner.mServerChannel)) { 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 4519916f278a..8c2619d75201 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7997,7 +7997,8 @@ public class WindowManagerService extends IWindowManager.Stub updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface, name, applicationHandle, flags, privateFlags, type, null /* region */); - clientChannel.copyTo(outInputChannel); + clientChannel.transferTo(outInputChannel); + clientChannel.dispose(); } 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 1f7457c088c5..e4a079d84a2a 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -556,6 +556,7 @@ 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; @@ -2477,15 +2478,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP throw new IllegalStateException("Window already has an input channel."); } String name = getName(); - mInputChannel = mWmService.mInputManager.createInputChannel(name); + InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); + mInputChannel = inputChannels[0]; + mClientChannel = inputChannels[1]; + mWmService.mInputManager.registerInputChannel(mInputChannel); mInputWindowHandle.token = mInputChannel.getToken(); if (outInputChannel != null) { - mInputChannel.copyTo(outInputChannel); + mClientChannel.transferTo(outInputChannel); + mClientChannel.dispose(); + mClientChannel = null; } 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(mInputChannel); + mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel); } mWmService.mInputToWindowMap.put(mInputWindowHandle.token, this); } @@ -2498,11 +2504,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // unregister server channel first otherwise it complains about broken channel if (mInputChannel != null) { - mWmService.mInputManager.removeInputChannel(mInputChannel.getToken()); + mWmService.mInputManager.unregisterInputChannel(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 17a05f3c7d1a..46136ca0647d 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -206,12 +206,10 @@ public: void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray); - 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 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); status_t pilferPointers(const sp<IBinder>& token); void displayRemoved(JNIEnv* env, int32_t displayId); @@ -434,22 +432,24 @@ void NativeInputManager::setDisplayViewports(JNIEnv* env, jobjectArray viewportO InputReaderConfiguration::CHANGE_DISPLAY_INFO); } -base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputChannel( - JNIEnv* /* env */, const std::string& name) { +status_t NativeInputManager::registerInputChannel( + JNIEnv* /* env */, const std::shared_ptr<InputChannel>& inputChannel) { ATRACE_CALL(); - return mInputManager->getDispatcher()->createInputChannel(name); + return mInputManager->getDispatcher()->registerInputChannel(inputChannel); } -base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputMonitor( - JNIEnv* /* env */, int32_t displayId, bool isGestureMonitor, const std::string& name) { +status_t NativeInputManager::registerInputMonitor(JNIEnv* /* env */, + const std::shared_ptr<InputChannel>& inputChannel, + int32_t displayId, bool isGestureMonitor) { ATRACE_CALL(); - return mInputManager->getDispatcher()->createInputMonitor(displayId, isGestureMonitor, name); + return mInputManager->getDispatcher()->registerInputMonitor( + inputChannel, displayId, isGestureMonitor); } -status_t NativeInputManager::removeInputChannel(JNIEnv* /* env */, - const sp<IBinder>& connectionToken) { +status_t NativeInputManager::unregisterInputChannel(JNIEnv* /* env */, + const sp<IBinder>& connectionToken) { ATRACE_CALL(); - return mInputManager->getDispatcher()->removeInputChannel(connectionToken); + return mInputManager->getDispatcher()->unregisterInputChannel(connectionToken); } status_t NativeInputManager::pilferPointers(const sp<IBinder>& token) { @@ -1352,83 +1352,80 @@ 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 removed with " - "the input manager!", - inputChannel->getName().c_str()); - im->removeInputChannel(env, inputChannel->getConnectionToken()); + ALOGW("Input channel object '%s' was disposed without first being unregistered with " + "the input manager!", inputChannel->getName().c_str()); + im->unregisterInputChannel(env, inputChannel->getConnectionToken()); } -static jobject nativeCreateInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, - jstring nameObj) { +static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */, + jlong ptr, jobject inputChannelObj) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); - ScopedUtfChars nameChars(env, nameObj); - std::string name = nameChars.c_str(); + std::shared_ptr<InputChannel> inputChannel = + android_view_InputChannel_getInputChannel(env, inputChannelObj); + if (inputChannel == nullptr) { + throwInputChannelNotInitialized(env); + return; + } - base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(env, name); + status_t status = im->registerInputChannel(env, inputChannel); - if (!inputChannel) { - std::string message = inputChannel.error().message(); - message += StringPrintf(" Status=%d", inputChannel.error().code()); + if (status) { + std::string message; + message += StringPrintf("Failed to register input channel. status=%d", status); jniThrowRuntimeException(env, message.c_str()); - return nullptr; - } - - jobject inputChannelObj = - android_view_InputChannel_createJavaObject(env, std::move(*inputChannel)); - if (!inputChannelObj) { - return nullptr; + return; } android_view_InputChannel_setDisposeCallback(env, inputChannelObj, handleInputChannelDisposed, im); - return inputChannelObj; } -static jobject nativeCreateInputMonitor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId, - jboolean isGestureMonitor, jstring nameObj) { +static void nativeRegisterInputMonitor(JNIEnv* env, jclass /* clazz */, + jlong ptr, jobject inputChannelObj, jint displayId, jboolean isGestureMonitor) { 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 nullptr; + return; } - ScopedUtfChars nameChars(env, nameObj); - std::string name = nameChars.c_str(); - - base::Result<std::unique_ptr<InputChannel>> inputChannel = - im->createInputMonitor(env, displayId, isGestureMonitor, name); + status_t status = im->registerInputMonitor(env, inputChannel, displayId, isGestureMonitor); - if (!inputChannel) { - std::string message = inputChannel.error().message(); - message += StringPrintf(" Status=%d", inputChannel.error().code()); + if (status) { + std::string message = StringPrintf("Failed to register input channel. status=%d", status); jniThrowRuntimeException(env, message.c_str()); - return nullptr; - } - - jobject inputChannelObj = - android_view_InputChannel_createJavaObject(env, std::move(*inputChannel)); - if (!inputChannelObj) { - return nullptr; + return; } - return inputChannelObj; } -static void nativeRemoveInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) { +static void nativeUnregisterInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, + jobject tokenObj) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); sp<IBinder> token = ibinderForJavaObject(env, tokenObj); - status_t status = im->removeInputChannel(env, token); - if (status && status != BAD_VALUE) { // ignore already removed channel + status_t status = im->unregisterInputChannel(env, token); + if (status && status != BAD_VALUE) { // ignore already unregistered channel std::string message; - message += StringPrintf("Failed to remove input channel. status=%d", status); + message += StringPrintf("Failed to unregister input channel. status=%d", status); jniThrowRuntimeException(env, message.c_str()); } } @@ -1783,11 +1780,12 @@ static const JNINativeMethod gInputManagerMethods[] = { {"nativeGetKeyCodeState", "(JIII)I", (void*)nativeGetKeyCodeState}, {"nativeGetSwitchState", "(JIII)I", (void*)nativeGetSwitchState}, {"nativeHasKeys", "(JII[I[Z)Z", (void*)nativeHasKeys}, - {"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}, + {"nativeRegisterInputChannel", "(JLandroid/view/InputChannel;)V", + (void*)nativeRegisterInputChannel}, + {"nativeRegisterInputMonitor", "(JLandroid/view/InputChannel;IZ)V", + (void*)nativeRegisterInputMonitor}, + {"nativeUnregisterInputChannel", "(JLandroid/os/IBinder;)V", + (void*)nativeUnregisterInputChannel}, {"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 1d6199eaa793..6a29c5b5424a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -236,7 +236,6 @@ 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); |