146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/* 246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Copyright (C) 2010 The Android Open Source Project 346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * you may not use this file except in compliance with the License. 646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * You may obtain a copy of the License at 746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 1046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Unless required by applicable law or agreed to in writing, software 1146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * See the License for the specific language governing permissions and 1446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * limitations under the License. 1546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */ 1646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "InputChannel-JNI" 1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "JNIHelp.h" 2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 2146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <android_runtime/AndroidRuntime.h> 2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <binder/Parcel.h> 2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <utils/Log.h> 249d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/InputTransport.h> 2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_view_InputChannel.h" 26d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include "android_os_Parcel.h" 2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_util_Binder.h" 2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 29987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe#include "core_jni_helpers.h" 30987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android { 3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 3446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct { 3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jclass clazz; 3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mPtr; // native object attached to the DVM InputChannel 3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jmethodID ctor; 4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gInputChannelClassInfo; 4146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownclass NativeInputChannel { 4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownpublic: 46c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh explicit NativeInputChannel(const sp<InputChannel>& inputChannel); 4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown ~NativeInputChannel(); 4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown inline sp<InputChannel> getInputChannel() { return mInputChannel; } 5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown void setDisposeCallback(InputChannelObjDisposeCallback callback, void* data); 5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown void invokeAndRemoveDisposeCallback(JNIEnv* env, jobject obj); 5346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 5446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownprivate: 5546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown sp<InputChannel> mInputChannel; 5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown InputChannelObjDisposeCallback mDisposeCallback; 5746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown void* mDisposeData; 5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}; 5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownNativeInputChannel::NativeInputChannel(const sp<InputChannel>& inputChannel) : 6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mInputChannel(inputChannel), mDisposeCallback(NULL) { 6446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 6546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 6646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownNativeInputChannel::~NativeInputChannel() { 6746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 6846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 6946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid NativeInputChannel::setDisposeCallback(InputChannelObjDisposeCallback callback, void* data) { 7046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mDisposeCallback = callback; 7146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mDisposeData = data; 7246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 7346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 7446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid NativeInputChannel::invokeAndRemoveDisposeCallback(JNIEnv* env, jobject obj) { 7546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (mDisposeCallback) { 7646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mDisposeCallback(env, obj, mInputChannel, mDisposeData); 7746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mDisposeCallback = NULL; 7846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mDisposeData = NULL; 7946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 8246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 8346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 8446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic NativeInputChannel* android_view_InputChannel_getNativeInputChannel(JNIEnv* env, 8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jobject inputChannelObj) { 86a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat jlong longPtr = env->GetLongField(inputChannelObj, gInputChannelClassInfo.mPtr); 87a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat return reinterpret_cast<NativeInputChannel*>(longPtr); 8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 8946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 9046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_setNativeInputChannel(JNIEnv* env, jobject inputChannelObj, 9146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeInputChannel* nativeInputChannel) { 92a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat env->SetLongField(inputChannelObj, gInputChannelClassInfo.mPtr, 93a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat reinterpret_cast<jlong>(nativeInputChannel)); 9446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 9546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 9646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownsp<InputChannel> android_view_InputChannel_getInputChannel(JNIEnv* env, jobject inputChannelObj) { 9746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeInputChannel* nativeInputChannel = 9846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_getNativeInputChannel(env, inputChannelObj); 9946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return nativeInputChannel != NULL ? nativeInputChannel->getInputChannel() : NULL; 10046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 10146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 10246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChannelObj, 10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown InputChannelObjDisposeCallback callback, void* data) { 10446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeInputChannel* nativeInputChannel = 10546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_getNativeInputChannel(env, inputChannelObj); 10646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (nativeInputChannel == NULL) { 1078564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Cannot set dispose callback because input channel object has not been initialized."); 10846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } else { 10946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nativeInputChannel->setDisposeCallback(callback, data); 11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 11146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 11246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic jobject android_view_InputChannel_createInputChannel(JNIEnv* env, 11418f307aed32d7a74a088fd871b90a5b9be86d8faGeorge Burgess IV std::unique_ptr<NativeInputChannel> nativeInputChannel) { 11546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jobject inputChannelObj = env->NewObject(gInputChannelClassInfo.clazz, 11646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown gInputChannelClassInfo.ctor); 117cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown if (inputChannelObj) { 11818f307aed32d7a74a088fd871b90a5b9be86d8faGeorge Burgess IV android_view_InputChannel_setNativeInputChannel(env, inputChannelObj, 11918f307aed32d7a74a088fd871b90a5b9be86d8faGeorge Burgess IV nativeInputChannel.release()); 120cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown } 12146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return inputChannelObj; 12246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 12346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic jobjectArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* env, 12546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jclass clazz, jstring nameObj) { 12646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown const char* nameChars = env->GetStringUTFChars(nameObj, NULL); 12746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown String8 name(nameChars); 12846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown env->ReleaseStringUTFChars(nameObj, nameChars); 12946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1305c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown sp<InputChannel> serverChannel; 1315c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown sp<InputChannel> clientChannel; 1325c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel); 13346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 13446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (result) { 135cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown String8 message; 136cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown message.appendFormat("Could not open input channel pair. status=%d", result); 137cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown jniThrowRuntimeException(env, message.string()); 138cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown return NULL; 139cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown } 140cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown 141cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown jobjectArray channelPair = env->NewObjectArray(2, gInputChannelClassInfo.clazz, NULL); 142cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown if (env->ExceptionCheck()) { 14346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return NULL; 14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 14546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 14646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jobject serverChannelObj = android_view_InputChannel_createInputChannel(env, 14718f307aed32d7a74a088fd871b90a5b9be86d8faGeorge Burgess IV std::make_unique<NativeInputChannel>(serverChannel)); 148cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown if (env->ExceptionCheck()) { 149cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown return NULL; 150cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown } 151cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown 15246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jobject clientChannelObj = android_view_InputChannel_createInputChannel(env, 15318f307aed32d7a74a088fd871b90a5b9be86d8faGeorge Burgess IV std::make_unique<NativeInputChannel>(clientChannel)); 154cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown if (env->ExceptionCheck()) { 155cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown return NULL; 156cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown } 15746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown env->SetObjectArrayElement(channelPair, 0, serverChannelObj); 15946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown env->SetObjectArrayElement(channelPair, 1, clientChannelObj); 16046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return channelPair; 16146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 16246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_nativeDispose(JNIEnv* env, jobject obj, jboolean finalized) { 16446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeInputChannel* nativeInputChannel = 16546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_getNativeInputChannel(env, obj); 16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (nativeInputChannel) { 16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (finalized) { 1688564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("Input channel object '%s' was finalized without being disposed!", 16946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nativeInputChannel->getInputChannel()->getName().string()); 17046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 17146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 17246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nativeInputChannel->invokeAndRemoveDisposeCallback(env, obj); 17346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 17446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_setNativeInputChannel(env, obj, NULL); 17546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown delete nativeInputChannel; 17646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 17746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 17846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 17946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_nativeTransferTo(JNIEnv* env, jobject obj, 18046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jobject otherObj) { 181cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown if (android_view_InputChannel_getNativeInputChannel(env, otherObj) != NULL) { 18246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jniThrowException(env, "java/lang/IllegalStateException", 18346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "Other object already has a native input channel."); 18446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return; 18546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 18646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 18746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeInputChannel* nativeInputChannel = 18846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_getNativeInputChannel(env, obj); 18946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_setNativeInputChannel(env, otherObj, nativeInputChannel); 19046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_setNativeInputChannel(env, obj, NULL); 19146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 19246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 19346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_nativeReadFromParcel(JNIEnv* env, jobject obj, 19446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jobject parcelObj) { 195cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown if (android_view_InputChannel_getNativeInputChannel(env, obj) != NULL) { 19646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jniThrowException(env, "java/lang/IllegalStateException", 19746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "This object already has a native input channel."); 19846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return; 19946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 20046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 20146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown Parcel* parcel = parcelForJavaObject(env, parcelObj); 20246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (parcel) { 20346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown bool isInitialized = parcel->readInt32(); 20446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (isInitialized) { 20546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown String8 name = parcel->readString8(); 20691e328984c0d1e0f95b3d37f779d9d4fa9bfe8f8Jeff Brown int rawFd = parcel->readFileDescriptor(); 20791e328984c0d1e0f95b3d37f779d9d4fa9bfe8f8Jeff Brown int dupFd = dup(rawFd); 20891e328984c0d1e0f95b3d37f779d9d4fa9bfe8f8Jeff Brown if (dupFd < 0) { 209cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown ALOGE("Error %d dup channel fd %d.", errno, rawFd); 21046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jniThrowRuntimeException(env, 21146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "Could not read input channel file descriptors from parcel."); 21246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return; 21346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 21446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 215cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown InputChannel* inputChannel = new InputChannel(name, dupFd); 21646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeInputChannel* nativeInputChannel = new NativeInputChannel(inputChannel); 21746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 21846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_setNativeInputChannel(env, obj, nativeInputChannel); 21946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 22046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 22146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 22246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 22346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_nativeWriteToParcel(JNIEnv* env, jobject obj, 22446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jobject parcelObj) { 22546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown Parcel* parcel = parcelForJavaObject(env, parcelObj); 22646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (parcel) { 22746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeInputChannel* nativeInputChannel = 22846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_getNativeInputChannel(env, obj); 22946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (nativeInputChannel) { 23046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown sp<InputChannel> inputChannel = nativeInputChannel->getInputChannel(); 23146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 23246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown parcel->writeInt32(1); 23346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown parcel->writeString8(inputChannel->getName()); 234cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown parcel->writeDupFileDescriptor(inputChannel->getFd()); 23546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } else { 23646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown parcel->writeInt32(0); 23746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 23846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 23946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 24046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 24146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic jstring android_view_InputChannel_nativeGetName(JNIEnv* env, jobject obj) { 24246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeInputChannel* nativeInputChannel = 24346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_view_InputChannel_getNativeInputChannel(env, obj); 24446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (! nativeInputChannel) { 24546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return NULL; 24646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 24746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 24846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jstring name = env->NewStringUTF(nativeInputChannel->getInputChannel()->getName().string()); 24946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return name; 25046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 25146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 2521951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brownstatic void android_view_InputChannel_nativeDup(JNIEnv* env, jobject obj, jobject otherObj) { 2531951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown NativeInputChannel* nativeInputChannel = 2541951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown android_view_InputChannel_getNativeInputChannel(env, obj); 2551951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown if (nativeInputChannel) { 2561951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown android_view_InputChannel_setNativeInputChannel(env, otherObj, 2571951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown new NativeInputChannel(nativeInputChannel->getInputChannel()->dup())); 2581951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown } 2591951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown} 2601951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown 26146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 26246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 26376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gInputChannelMethods[] = { 26446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown /* name, signature, funcPtr */ 26546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown { "nativeOpenInputChannelPair", "(Ljava/lang/String;)[Landroid/view/InputChannel;", 26646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown (void*)android_view_InputChannel_nativeOpenInputChannelPair }, 26746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown { "nativeDispose", "(Z)V", 26846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown (void*)android_view_InputChannel_nativeDispose }, 26946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown { "nativeTransferTo", "(Landroid/view/InputChannel;)V", 27046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown (void*)android_view_InputChannel_nativeTransferTo }, 27146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown { "nativeReadFromParcel", "(Landroid/os/Parcel;)V", 27246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown (void*)android_view_InputChannel_nativeReadFromParcel }, 27346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown { "nativeWriteToParcel", "(Landroid/os/Parcel;)V", 27446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown (void*)android_view_InputChannel_nativeWriteToParcel }, 27546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown { "nativeGetName", "()Ljava/lang/String;", 27646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown (void*)android_view_InputChannel_nativeGetName }, 2771951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown { "nativeDup", "(Landroid/view/InputChannel;)V", 2781951ce86c21445ac191e4d2d95233f4f5c096b56Jeff Brown (void*)android_view_InputChannel_nativeDup }, 27946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}; 28046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 28146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_InputChannel(JNIEnv* env) { 282987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe int res = RegisterMethodsOrDie(env, "android/view/InputChannel", gInputChannelMethods, 283987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe NELEM(gInputChannelMethods)); 284987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 285987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe jclass clazz = FindClassOrDie(env, "android/view/InputChannel"); 286987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gInputChannelClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); 28746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 288987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gInputChannelClassInfo.mPtr = GetFieldIDOrDie(env, gInputChannelClassInfo.clazz, "mPtr", "J"); 28946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 290987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gInputChannelClassInfo.ctor = GetMethodIDOrDie(env, gInputChannelClassInfo.clazz, "<init>", 291987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe "()V"); 29246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 293987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe return res; 29446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 29546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 29646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android 297