static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject inputChannelObj, jobject messageQueueObj) { sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj); if (inputChannel == NULL) { jniThrowRuntimeException(env, "InputChannel is not initialized."); return 0; } sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env, receiverWeak, inputChannel, messageQueue); status_t status = receiver->initialize(); if (status) { String8 message; message.appendFormat("Failed to initialize input event receiver. status=%d", status); jniThrowRuntimeException(env, message.string()); return 0; } receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object return reinterpret_cast<jlong>(receiver.get()); }
status_t NativeInputQueue::unregisterInputChannel(JNIEnv* env, jobject inputChannelObj) { sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj); if (inputChannel == NULL) { ALOGW("Input channel is not initialized."); return BAD_VALUE; } #if DEBUG_REGISTRATION ALOGD("channel '%s' - Unregistered", inputChannel->getName().string()); #endif { // acquire lock AutoMutex _l(mLock); ssize_t connectionIndex = getConnectionIndex(inputChannel); if (connectionIndex < 0) { ALOGW("Attempted to unregister already unregistered input channel '%s'", inputChannel->getName().string()); return BAD_VALUE; } sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); mConnectionsByReceiveFd.removeItemsAt(connectionIndex); connection->status = Connection::STATUS_ZOMBIE; connection->looper->removeFd(inputChannel->getReceivePipeFd()); env->DeleteGlobalRef(connection->inputHandlerObjGlobal); connection->inputHandlerObjGlobal = NULL; if (connection->messageInProgress) { ALOGI("Sending finished signal for input channel '%s' since it is being unregistered " "while an input message is still in progress.", connection->getInputChannelName()); connection->messageInProgress = false; connection->inputConsumer.sendFinishedSignal(false); // ignoring result } } // release lock android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL); return OK; }
bool NativeInputWindowHandle::updateInfo() { JNIEnv* env = AndroidRuntime::getJNIEnv(); jobject obj = env->NewLocalRef(mObjWeak); if (!obj) { releaseInfo(); return false; } if (!mInfo) { mInfo = new InputWindowInfo(); } jobject inputChannelObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.inputChannel); if (inputChannelObj) { mInfo->inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj); env->DeleteLocalRef(inputChannelObj); } else { mInfo->inputChannel.clear(); } jstring nameObj = jstring(env->GetObjectField(obj, gInputWindowHandleClassInfo.name)); if (nameObj) { const char* nameStr = env->GetStringUTFChars(nameObj, NULL); mInfo->name.setTo(nameStr); env->ReleaseStringUTFChars(nameObj, nameStr); env->DeleteLocalRef(nameObj); } else { mInfo->name.setTo("<null>"); } mInfo->layoutParamsFlags = env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsFlags); mInfo->layoutParamsPrivateFlags = env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsPrivateFlags); mInfo->layoutParamsType = env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsType); mInfo->dispatchingTimeout = env->GetLongField(obj, gInputWindowHandleClassInfo.dispatchingTimeoutNanos); mInfo->frameLeft = env->GetIntField(obj, gInputWindowHandleClassInfo.frameLeft); mInfo->frameTop = env->GetIntField(obj, gInputWindowHandleClassInfo.frameTop); mInfo->frameRight = env->GetIntField(obj, gInputWindowHandleClassInfo.frameRight); mInfo->frameBottom = env->GetIntField(obj, gInputWindowHandleClassInfo.frameBottom); mInfo->scaleFactor = env->GetFloatField(obj, gInputWindowHandleClassInfo.scaleFactor); jobject regionObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.touchableRegion); if (regionObj) { SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj); mInfo->touchableRegion.set(*region); env->DeleteLocalRef(regionObj); } else { mInfo->touchableRegion.setEmpty(); } mInfo->visible = env->GetBooleanField(obj, gInputWindowHandleClassInfo.visible); mInfo->canReceiveKeys = env->GetBooleanField(obj, gInputWindowHandleClassInfo.canReceiveKeys); mInfo->hasFocus = env->GetBooleanField(obj, gInputWindowHandleClassInfo.hasFocus); mInfo->hasWallpaper = env->GetBooleanField(obj, gInputWindowHandleClassInfo.hasWallpaper); mInfo->paused = env->GetBooleanField(obj, gInputWindowHandleClassInfo.paused); mInfo->layer = env->GetIntField(obj, gInputWindowHandleClassInfo.layer); mInfo->ownerPid = env->GetIntField(obj, gInputWindowHandleClassInfo.ownerPid); mInfo->ownerUid = env->GetIntField(obj, gInputWindowHandleClassInfo.ownerUid); mInfo->inputFeatures = env->GetIntField(obj, gInputWindowHandleClassInfo.inputFeatures); mInfo->displayId = env->GetIntField(obj, gInputWindowHandleClassInfo.displayId); env->DeleteLocalRef(obj); return true; }