android_view_InputChannel.cpp revision 8564c8da817a845353d213acd8636b76f567b234
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>
2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <ui/InputTransport.h>
2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_view_InputChannel.h"
2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_util_Binder.h"
2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct {
3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jclass clazz;
3446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mPtr;   // native object attached to the DVM InputChannel
3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jmethodID ctor;
3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gInputChannelClassInfo;
3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownclass NativeInputChannel {
4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownpublic:
4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    NativeInputChannel(const sp<InputChannel>& inputChannel);
4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    ~NativeInputChannel();
4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    inline sp<InputChannel> getInputChannel() { return mInputChannel; }
4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    void setDisposeCallback(InputChannelObjDisposeCallback callback, void* data);
4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    void invokeAndRemoveDisposeCallback(JNIEnv* env, jobject obj);
5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownprivate:
5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    sp<InputChannel> mInputChannel;
5346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    InputChannelObjDisposeCallback mDisposeCallback;
5446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    void* mDisposeData;
5546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown};
5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownNativeInputChannel::NativeInputChannel(const sp<InputChannel>& inputChannel) :
6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mInputChannel(inputChannel), mDisposeCallback(NULL) {
6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownNativeInputChannel::~NativeInputChannel() {
6446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
6546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid NativeInputChannel::setDisposeCallback(InputChannelObjDisposeCallback callback, void* data) {
6746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mDisposeCallback = callback;
6846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mDisposeData = data;
6946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
7046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid NativeInputChannel::invokeAndRemoveDisposeCallback(JNIEnv* env, jobject obj) {
7246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (mDisposeCallback) {
7346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        mDisposeCallback(env, obj, mInputChannel, mDisposeData);
7446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        mDisposeCallback = NULL;
7546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        mDisposeData = NULL;
7646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
7746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
7846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic NativeInputChannel* android_view_InputChannel_getNativeInputChannel(JNIEnv* env,
8246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        jobject inputChannelObj) {
8346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint intPtr = env->GetIntField(inputChannelObj, gInputChannelClassInfo.mPtr);
8446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return reinterpret_cast<NativeInputChannel*>(intPtr);
8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_setNativeInputChannel(JNIEnv* env, jobject inputChannelObj,
8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        NativeInputChannel* nativeInputChannel) {
8946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetIntField(inputChannelObj, gInputChannelClassInfo.mPtr,
9046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown             reinterpret_cast<jint>(nativeInputChannel));
9146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
9246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownsp<InputChannel> android_view_InputChannel_getInputChannel(JNIEnv* env, jobject inputChannelObj) {
9446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    NativeInputChannel* nativeInputChannel =
9546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            android_view_InputChannel_getNativeInputChannel(env, inputChannelObj);
9646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return nativeInputChannel != NULL ? nativeInputChannel->getInputChannel() : NULL;
9746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
9846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChannelObj,
10046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        InputChannelObjDisposeCallback callback, void* data) {
10146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    NativeInputChannel* nativeInputChannel =
10246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            android_view_InputChannel_getNativeInputChannel(env, inputChannelObj);
10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (nativeInputChannel == NULL) {
1048564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Cannot set dispose callback because input channel object has not been initialized.");
10546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    } else {
10646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nativeInputChannel->setDisposeCallback(callback, data);
10746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
10846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
10946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic jobject android_view_InputChannel_createInputChannel(JNIEnv* env,
11146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        NativeInputChannel* nativeInputChannel) {
11246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jobject inputChannelObj = env->NewObject(gInputChannelClassInfo.clazz,
11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            gInputChannelClassInfo.ctor);
114cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (inputChannelObj) {
115cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        android_view_InputChannel_setNativeInputChannel(env, inputChannelObj, nativeInputChannel);
116cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    }
11746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return inputChannelObj;
11846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
11946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
12046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic jobjectArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* env,
12146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        jclass clazz, jstring nameObj) {
12246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    const char* nameChars = env->GetStringUTFChars(nameObj, NULL);
12346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    String8 name(nameChars);
12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->ReleaseStringUTFChars(nameObj, nameChars);
12546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1265c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    sp<InputChannel> serverChannel;
1275c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    sp<InputChannel> clientChannel;
1285c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
12946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
13046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (result) {
131cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        String8 message;
132cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        message.appendFormat("Could not open input channel pair.  status=%d", result);
133cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        jniThrowRuntimeException(env, message.string());
134cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        return NULL;
135cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    }
136cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
137cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    jobjectArray channelPair = env->NewObjectArray(2, gInputChannelClassInfo.clazz, NULL);
138cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (env->ExceptionCheck()) {
13946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return NULL;
14046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
14146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
14246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jobject serverChannelObj = android_view_InputChannel_createInputChannel(env,
14346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            new NativeInputChannel(serverChannel));
144cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (env->ExceptionCheck()) {
145cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        return NULL;
146cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    }
147cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
14846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jobject clientChannelObj = android_view_InputChannel_createInputChannel(env,
14946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            new NativeInputChannel(clientChannel));
150cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (env->ExceptionCheck()) {
151cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        return NULL;
152cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    }
15346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
15446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetObjectArrayElement(channelPair, 0, serverChannelObj);
15546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    env->SetObjectArrayElement(channelPair, 1, clientChannelObj);
15646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return channelPair;
15746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
15946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_nativeDispose(JNIEnv* env, jobject obj, jboolean finalized) {
16046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    NativeInputChannel* nativeInputChannel =
16146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            android_view_InputChannel_getNativeInputChannel(env, obj);
16246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (nativeInputChannel) {
16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (finalized) {
1648564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Input channel object '%s' was finalized without being disposed!",
16546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    nativeInputChannel->getInputChannel()->getName().string());
16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nativeInputChannel->invokeAndRemoveDisposeCallback(env, obj);
16946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        android_view_InputChannel_setNativeInputChannel(env, obj, NULL);
17146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        delete nativeInputChannel;
17246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
17346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
17446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_nativeTransferTo(JNIEnv* env, jobject obj,
17646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        jobject otherObj) {
177cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (android_view_InputChannel_getNativeInputChannel(env, otherObj) != NULL) {
17846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        jniThrowException(env, "java/lang/IllegalStateException",
17946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                "Other object already has a native input channel.");
18046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return;
18146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
18246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    NativeInputChannel* nativeInputChannel =
18446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            android_view_InputChannel_getNativeInputChannel(env, obj);
18546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    android_view_InputChannel_setNativeInputChannel(env, otherObj, nativeInputChannel);
18646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    android_view_InputChannel_setNativeInputChannel(env, obj, NULL);
18746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
18846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_nativeReadFromParcel(JNIEnv* env, jobject obj,
19046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        jobject parcelObj) {
191cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (android_view_InputChannel_getNativeInputChannel(env, obj) != NULL) {
19246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        jniThrowException(env, "java/lang/IllegalStateException",
19346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                "This object already has a native input channel.");
19446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return;
19546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
19646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
19746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    Parcel* parcel = parcelForJavaObject(env, parcelObj);
19846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (parcel) {
19946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        bool isInitialized = parcel->readInt32();
20046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (isInitialized) {
20146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            String8 name = parcel->readString8();
20202cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            int32_t parcelAshmemFd = parcel->readFileDescriptor();
20302cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            int32_t ashmemFd = dup(parcelAshmemFd);
20402cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            if (ashmemFd < 0) {
20502cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown                LOGE("Error %d dup ashmem fd %d.", errno, parcelAshmemFd);
20602cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            }
20702cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            int32_t parcelReceivePipeFd = parcel->readFileDescriptor();
20802cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            int32_t receivePipeFd = dup(parcelReceivePipeFd);
20902cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            if (receivePipeFd < 0) {
21002cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown                LOGE("Error %d dup receive pipe fd %d.", errno, parcelReceivePipeFd);
21102cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            }
21202cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            int32_t parcelSendPipeFd = parcel->readFileDescriptor();
21302cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            int32_t sendPipeFd = dup(parcelSendPipeFd);
21402cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            if (sendPipeFd < 0) {
21502cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown                LOGE("Error %d dup send pipe fd %d.", errno, parcelSendPipeFd);
21602cafc9f6ec018ae31ca9032be67a2d8d410736aJeff Brown            }
21746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            if (ashmemFd < 0 || receivePipeFd < 0 || sendPipeFd < 0) {
21846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                if (ashmemFd >= 0) ::close(ashmemFd);
21946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                if (receivePipeFd >= 0) ::close(receivePipeFd);
22046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                if (sendPipeFd >= 0) ::close(sendPipeFd);
22146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                jniThrowRuntimeException(env,
22246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "Could not read input channel file descriptors from parcel.");
22346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                return;
22446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
22546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            InputChannel* inputChannel = new InputChannel(name, ashmemFd,
22746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    receivePipeFd, sendPipeFd);
22846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            NativeInputChannel* nativeInputChannel = new NativeInputChannel(inputChannel);
22946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            android_view_InputChannel_setNativeInputChannel(env, obj, nativeInputChannel);
23146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
23246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
23346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
23446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_view_InputChannel_nativeWriteToParcel(JNIEnv* env, jobject obj,
23646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        jobject parcelObj) {
23746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    Parcel* parcel = parcelForJavaObject(env, parcelObj);
23846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (parcel) {
23946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        NativeInputChannel* nativeInputChannel =
24046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                android_view_InputChannel_getNativeInputChannel(env, obj);
24146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (nativeInputChannel) {
24246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            sp<InputChannel> inputChannel = nativeInputChannel->getInputChannel();
24346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
24446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            parcel->writeInt32(1);
24546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            parcel->writeString8(inputChannel->getName());
24646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            parcel->writeDupFileDescriptor(inputChannel->getAshmemFd());
24746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            parcel->writeDupFileDescriptor(inputChannel->getReceivePipeFd());
24846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            parcel->writeDupFileDescriptor(inputChannel->getSendPipeFd());
24946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        } else {
25046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            parcel->writeInt32(0);
25146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
25246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
25346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
25446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic jstring android_view_InputChannel_nativeGetName(JNIEnv* env, jobject obj) {
25646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    NativeInputChannel* nativeInputChannel =
25746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            android_view_InputChannel_getNativeInputChannel(env, obj);
25846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (! nativeInputChannel) {
25946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return NULL;
26046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
26146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
26246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jstring name = env->NewStringUTF(nativeInputChannel->getInputChannel()->getName().string());
26346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return name;
26446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
26546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
26646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
26746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
26846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic JNINativeMethod gInputChannelMethods[] = {
26946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /* name, signature, funcPtr */
27046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { "nativeOpenInputChannelPair", "(Ljava/lang/String;)[Landroid/view/InputChannel;",
27146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            (void*)android_view_InputChannel_nativeOpenInputChannelPair },
27246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { "nativeDispose", "(Z)V",
27346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            (void*)android_view_InputChannel_nativeDispose },
27446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { "nativeTransferTo", "(Landroid/view/InputChannel;)V",
27546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            (void*)android_view_InputChannel_nativeTransferTo },
27646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { "nativeReadFromParcel", "(Landroid/os/Parcel;)V",
27746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            (void*)android_view_InputChannel_nativeReadFromParcel },
27846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { "nativeWriteToParcel", "(Landroid/os/Parcel;)V",
27946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            (void*)android_view_InputChannel_nativeWriteToParcel },
28046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { "nativeGetName", "()Ljava/lang/String;",
28146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            (void*)android_view_InputChannel_nativeGetName },
28246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown};
28346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
28446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define FIND_CLASS(var, className) \
28546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->FindClass(className); \
28646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find class " className); \
28746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = jclass(env->NewGlobalRef(var));
28846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
28946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
29046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
29146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find method " methodName);
29246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
29346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
29446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
29546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
29646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
29746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_InputChannel(JNIEnv* env) {
29846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    int res = jniRegisterNativeMethods(env, "android/view/InputChannel",
29946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            gInputChannelMethods, NELEM(gInputChannelMethods));
30046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
30146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    FIND_CLASS(gInputChannelClassInfo.clazz, "android/view/InputChannel");
30346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gInputChannelClassInfo.mPtr, gInputChannelClassInfo.clazz,
30546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mPtr", "I");
30646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_METHOD_ID(gInputChannelClassInfo.ctor, gInputChannelClassInfo.clazz,
30846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "<init>", "()V");
30946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
31046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return 0;
31146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
31246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
31346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
314