sp<NativeInputWindowHandle> android_server_InputWindowHandle_getHandle(
        JNIEnv* env, jobject inputWindowHandleObj) {
    if (!inputWindowHandleObj) {
        return NULL;
    }

    AutoMutex _l(gHandleMutex);

    int ptr = env->GetIntField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr);
    NativeInputWindowHandle* handle;
    if (ptr) {
        handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
    } else {
        jobject inputApplicationHandleObj = env->GetObjectField(inputWindowHandleObj,
                gInputWindowHandleClassInfo.inputApplicationHandle);
        sp<InputApplicationHandle> inputApplicationHandle =
                android_server_InputApplicationHandle_getHandle(env, inputApplicationHandleObj);
        env->DeleteLocalRef(inputApplicationHandleObj);

        jweak objWeak = env->NewWeakGlobalRef(inputWindowHandleObj);
        handle = new NativeInputWindowHandle(inputApplicationHandle, objWeak);
        handle->incStrong((void*)android_server_InputWindowHandle_getHandle);
        env->SetIntField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr,
                reinterpret_cast<int>(handle));
    }
    return handle;
}
android::sp<NativeInputWindowHandle> GetNativeInputWindowHandle(
    /* [in] */ InputWindowHandle* inputWindowHandleObj)
{
    if (!inputWindowHandleObj) {
        return NULL;
    }

    android::AutoMutex _l(gHandleMutex);

    Int64 ptr = inputWindowHandleObj->mPtr;
    NativeInputWindowHandle* handle;
    if (ptr) {
        handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
    }
    else {
        InputApplicationHandle* inputApplicationHandleObj = inputWindowHandleObj->mInputApplicationHandle;
        android::sp<android::InputApplicationHandle> inputApplicationHandle =
                GetNativeInputApplicationHandle(inputApplicationHandleObj);

        AutoPtr<IWeakReference> objWeak;
        inputWindowHandleObj->GetWeakReference((IWeakReference**)&objWeak);
        handle = new NativeInputWindowHandle(inputApplicationHandle, objWeak);
        handle->incStrong((void*)GetNativeInputWindowHandle);
        inputWindowHandleObj->mPtr = reinterpret_cast<Int64>(handle);
    }
    return handle;
}
static void android_server_InputWindowHandle_nativeDispose(JNIEnv* env, jobject obj) {
    AutoMutex _l(gHandleMutex);

    int ptr = env->GetIntField(obj, gInputWindowHandleClassInfo.ptr);
    if (ptr) {
        env->SetIntField(obj, gInputWindowHandleClassInfo.ptr, 0);

        NativeInputWindowHandle* handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
        handle->decStrong((void*)android_server_InputWindowHandle_getHandle);
    }
}
void InputWindowHandle::NativeDispose()
{
    android::AutoMutex _l(gHandleMutex);

    if (mPtr) {
        mPtr = 0;

        NativeInputWindowHandle* handle = reinterpret_cast<NativeInputWindowHandle*>(mPtr);
        handle->decStrong((void*)GetNativeInputWindowHandle);
    }
}
android::sp<android::InputWindowHandle> InputWindowHandle::GetHandle(
    /* [in] */ InputWindowHandle* inputWindowHandleObj)
{
    if (inputWindowHandleObj == NULL) {
        return NULL;
    }

    android::AutoMutex _l(gHandleMutex);

    NativeInputWindowHandle* handle = inputWindowHandleObj->mNative;
    if (handle == NULL) {
        InputApplicationHandle* inputApplicationHandleObj = inputWindowHandleObj->mInputApplicationHandle;
        android::sp<android::InputApplicationHandle> inputApplicationHandle =
                InputApplicationHandle::GetHandle(inputApplicationHandleObj);

        handle = new NativeInputWindowHandle(inputApplicationHandle, inputWindowHandleObj);
        handle->incStrong(inputWindowHandleObj);
        inputWindowHandleObj->mNative = handle;
    }
    return handle;
}