summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jean-Michel Trivi <jmtrivi@google.com> 2020-09-22 22:04:00 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-09-22 22:04:00 +0000
commitcc848e93c1f97ff7ff2a12d8f7fa727b89932e84 (patch)
tree5865b34ea3fba2ff1aaa0763c298a9a2a84ddf42
parent8e8eaa8624a5c39de6a1f43a0cb6d559a86db771 (diff)
parente97ad446cb24e4724ebaa34ff829ad5ae2b372bc (diff)
Merge "Revert "Reland "Use new create/removeInputChannel()."""
-rw-r--r--core/java/android/view/InputChannel.java7
-rw-r--r--core/jni/android_view_InputChannel.cpp47
-rw-r--r--core/jni/android_view_InputChannel.h2
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java46
-rw-r--r--services/core/java/com/android/server/wm/DragState.java15
-rw-r--r--services/core/java/com/android/server/wm/EmbeddedWindowController.java16
-rw-r--r--services/core/java/com/android/server/wm/InputConsumerImpl.java17
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java11
-rw-r--r--services/core/java/com/android/server/wm/TaskPositioner.java12
-rw-r--r--services/core/java/com/android/server/wm/TaskPositioningController.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java18
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp124
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java1
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 026396ecdf07..da3319acca24 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);