summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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, 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);