int register_android_view_MotionEvent(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "android/view/MotionEvent",
            gMotionEventMethods, NELEM(gMotionEventMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
    (void)res;

    FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
    gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));

    GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
            "obtain", "()Landroid/view/MotionEvent;");
    GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
            "recycle", "()V");
    GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
            "mNativePtr", "J");

    jclass clazz;
    FIND_CLASS(clazz, "android/view/MotionEvent$PointerCoords");

    GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, clazz,
            "mPackedAxisBits", "J");
    GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, clazz,
            "mPackedAxisValues", "[F");
    GET_FIELD_ID(gPointerCoordsClassInfo.x, clazz,
            "x", "F");
    GET_FIELD_ID(gPointerCoordsClassInfo.y, clazz,
            "y", "F");
    GET_FIELD_ID(gPointerCoordsClassInfo.pressure, clazz,
            "pressure", "F");
    GET_FIELD_ID(gPointerCoordsClassInfo.size, clazz,
            "size", "F");
    GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, clazz,
            "touchMajor", "F");
    GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, clazz,
            "touchMinor", "F");
    GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, clazz,
            "toolMajor", "F");
    GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, clazz,
            "toolMinor", "F");
    GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz,
            "orientation", "F");

    FIND_CLASS(clazz, "android/view/MotionEvent$PointerProperties");

    GET_FIELD_ID(gPointerPropertiesClassInfo.id, clazz,
            "id", "I");
    GET_FIELD_ID(gPointerPropertiesClassInfo.toolType, clazz,
            "toolType", "I");

    return 0;
}
int register_android_app_NativeActivity(JNIEnv* env)
{
    //ALOGD("register_android_app_NativeActivity");
    jclass clazz;
    FIND_CLASS(clazz, kNativeActivityPathName);

    GET_METHOD_ID(gNativeActivityClassInfo.finish,
            clazz,
            "finish", "()V");
    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags,
            clazz,
            "setWindowFlags", "(II)V");
    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat,
            clazz,
            "setWindowFormat", "(I)V");
    GET_METHOD_ID(gNativeActivityClassInfo.showIme,
            clazz,
            "showIme", "(I)V");
    GET_METHOD_ID(gNativeActivityClassInfo.hideIme,
            clazz,
            "hideIme", "(I)V");

    return AndroidRuntime::registerNativeMethods(
        env, kNativeActivityPathName,
        g_methods, NELEM(g_methods));
}
static void nativeInit(JNIEnv *env, jobject clazz, jobject callbackObj) {
    ALOG(LOG_VERBOSE, LOG_TAG, "nativeInit()\n");
    FIND_CLASS(gFingerprintServiceClassInfo.clazz, FINGERPRINT_SERVICE);
    GET_METHOD_ID(gFingerprintServiceClassInfo.notify, gFingerprintServiceClassInfo.clazz,
           "notify", "(III)V");
    gFingerprintServiceClassInfo.callbackObject = env->NewGlobalRef(callbackObj);
}
int register_android_view_KeyEvent(JNIEnv* env) {
    FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");

    GET_STATIC_METHOD_ID(gKeyEventClassInfo.obtain, gKeyEventClassInfo.clazz,
            "obtain", "(JJIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;");
    GET_METHOD_ID(gKeyEventClassInfo.recycle, gKeyEventClassInfo.clazz,
            "recycle", "()V");

    GET_FIELD_ID(gKeyEventClassInfo.mDeviceId, gKeyEventClassInfo.clazz,
            "mDeviceId", "I");
    GET_FIELD_ID(gKeyEventClassInfo.mSource, gKeyEventClassInfo.clazz,
            "mSource", "I");
    GET_FIELD_ID(gKeyEventClassInfo.mMetaState, gKeyEventClassInfo.clazz,
            "mMetaState", "I");
    GET_FIELD_ID(gKeyEventClassInfo.mAction, gKeyEventClassInfo.clazz,
            "mAction", "I");
    GET_FIELD_ID(gKeyEventClassInfo.mKeyCode, gKeyEventClassInfo.clazz,
            "mKeyCode", "I");
    GET_FIELD_ID(gKeyEventClassInfo.mScanCode, gKeyEventClassInfo.clazz,
            "mScanCode", "I");
    GET_FIELD_ID(gKeyEventClassInfo.mRepeatCount, gKeyEventClassInfo.clazz,
            "mRepeatCount", "I");
    GET_FIELD_ID(gKeyEventClassInfo.mFlags, gKeyEventClassInfo.clazz,
            "mFlags", "I");
    GET_FIELD_ID(gKeyEventClassInfo.mDownTime, gKeyEventClassInfo.clazz,
            "mDownTime", "J");
    GET_FIELD_ID(gKeyEventClassInfo.mEventTime, gKeyEventClassInfo.clazz,
            "mEventTime", "J");
    GET_FIELD_ID(gKeyEventClassInfo.mCharacters, gKeyEventClassInfo.clazz,
            "mCharacters", "Ljava/lang/String;");

    return AndroidRuntime::registerNativeMethods(
        env, "android/view/KeyEvent", g_methods, NELEM(g_methods));
}
int register_android_server_PowerManagerService(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "com/android/server/power/PowerManagerService",
            gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    // Callbacks

    jclass clazz;
    FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.wakeUpFromNative, clazz,
            "wakeUpFromNative", "(J)V");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleepFromNative, clazz,
            "goToSleepFromNative", "(JI)V");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivityFromNative, clazz,
            "userActivityFromNative", "(JII)V");

    // Initialize
    for (int i = 0; i <= USER_ACTIVITY_EVENT_LAST; i++) {
        gLastEventTime[i] = LLONG_MIN;
    }
    gScreenOn = true;
    gScreenBright = true;
    gPowerManagerServiceObj = NULL;
    gPowerModule = NULL;
    return 0;
}
HParsedToken *unwrap_parsed_token(JNIEnv *env, jobject obj)
{
    jclass parsedTokenClass;
    jfieldID parsedTokenInner;
    FIND_CLASS(parsedTokenClass, env, "com/upstandinghackers/hammer/ParsedToken");
    parsedTokenInner =  (*env)->GetFieldID(env, parsedTokenClass, "inner", "J");
    return (HParsedToken *)((*env)->GetLongField(env, obj, parsedTokenInner));
}
HParseResult *unwrap_parse_result(JNIEnv *env, jobject obj)
{
    jclass parseResultClass;
    jfieldID parseResultInner;
    FIND_CLASS(parseResultClass, env, "com/upstandinghackers/hammer/ParseResult");
    parseResultInner =  (*env)->GetFieldID(env, parseResultClass, "inner", "J");
    return (HParseResult *)((*env)->GetLongField(env, obj, parseResultInner));
}
int register_android_server_AssetAtlasService(JNIEnv* env) {
    jclass clazz;

    FIND_CLASS(clazz, "android/graphics/Canvas");
    GET_METHOD_ID(gCanvasClassInfo.setNativeBitmap, clazz, "setNativeBitmap", "(J)V");

    return jniRegisterNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}
int register_android_text_KeyCharacterMap(JNIEnv* env)
{
    FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
    gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));

    jclass clazz;
    FIND_CLASS(clazz, "android/view/KeyCharacterMap$FallbackAction");

    GET_FIELD_ID(gFallbackActionClassInfo.keyCode, clazz,
                 "keyCode", "I");

    GET_FIELD_ID(gFallbackActionClassInfo.metaState, clazz,
                 "metaState", "I");

    return AndroidRuntime::registerNativeMethods(env,
            "android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
}
int register_android_server_fingerprint_FingerprintService(JNIEnv* env) {
    FIND_CLASS(gFingerprintServiceClassInfo.clazz, FINGERPRINT_SERVICE);
    GET_METHOD_ID(gFingerprintServiceClassInfo.notify, gFingerprintServiceClassInfo.clazz, "notify",
            "(III)V");
    int result = AndroidRuntime::registerNativeMethods(
        env, FINGERPRINT_SERVICE, g_methods, NELEM(g_methods));
    ALOG(LOG_VERBOSE, LOG_TAG, "FingerprintManager JNI ready.\n");
    return result;
}
int register_android_view_InputQueue(JNIEnv* env)
{
    jclass clazz;
    FIND_CLASS(clazz, kInputQueuePathName);
    GET_METHOD_ID(gInputQueueClassInfo.finishInputEvent, clazz, "finishInputEvent", "(JZ)V");

    return AndroidRuntime::registerNativeMethods(
        env, kInputQueuePathName,
        g_methods, NELEM(g_methods));
}
int register_android_database_CursorWindow(JNIEnv* env)
{
    jclass clazz;
    FIND_CLASS(clazz, "android/database/CharArrayBuffer");

    GET_FIELD_ID(gCharArrayBufferClassInfo.data, clazz, "data", "[C");
    GET_FIELD_ID(gCharArrayBufferClassInfo.sizeCopied, clazz, "sizeCopied", "I");

    return jniRegisterNativeMethods(env,
    "io/requery/android/database/CursorWindow", sMethods, NELEM(sMethods));
}
static jobject KeyedVectorToHashMap (JNIEnv *env, KeyedVector<String8, String8> const &map) {
    jclass clazz;
    FIND_CLASS(clazz, "java/util/HashMap");
    jobject hashMap = env->NewObject(clazz, gFields.hashmap.init);
    for (size_t i = 0; i < map.size(); ++i) {
        jstring jkey = env->NewStringUTF(map.keyAt(i).string());
        jstring jvalue = env->NewStringUTF(map.valueAt(i).string());
        env->CallObjectMethod(hashMap, gFields.hashmap.put, jkey, jvalue);
        env->DeleteLocalRef(jkey);
        env->DeleteLocalRef(jvalue);
    }
    return hashMap;
}
int register_android_view_InputDevice(JNIEnv* env)
{
    FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
    gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));

    GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
            "<init>", "(IILjava/lang/String;Ljava/lang/String;ZIILandroid/view/KeyCharacterMap;Z)V");

    GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
            "addMotionRange", "(IIFFFFF)V");

    return 0;
}
int register_android_os_MessageQueue(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "android/os/MessageQueue",
            gMessageQueueMethods, NELEM(gMessageQueueMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    jclass clazz;
    FIND_CLASS(clazz, "android/os/MessageQueue");

    GET_FIELD_ID(gMessageQueueClassInfo.mPtr, clazz,
            "mPtr", "J");
    
    return 0;
}
int register_android_view_GraphicBuffer(JNIEnv* env) {
    jclass clazz;
    FIND_CLASS(clazz, "android/view/GraphicBuffer");
    GET_FIELD_ID(gGraphicBufferClassInfo.mNativeObject, clazz, "mNativeObject", "J");

    FIND_CLASS(clazz, "android/graphics/Rect");
    GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
    GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I");
    GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I");
    GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I");
    GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");

    FIND_CLASS(clazz, "android/graphics/Canvas");
    GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer",
            "Landroid/graphics/Canvas$CanvasFinalizer;");
    GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "J");
    GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");

    FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer");
    GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "J");

    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}
int register_android_view_InputChannel(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "android/view/InputChannel",
            gInputChannelMethods, NELEM(gInputChannelMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    FIND_CLASS(gInputChannelClassInfo.clazz, "android/view/InputChannel");

    GET_FIELD_ID(gInputChannelClassInfo.mPtr, gInputChannelClassInfo.clazz,
            "mPtr", "I");
    
    GET_METHOD_ID(gInputChannelClassInfo.ctor, gInputChannelClassInfo.clazz,
            "<init>", "()V");

    return 0;
}
static jobject ListOfVectorsToArrayListOfByteArray(JNIEnv *env,
                                                   List<Vector<uint8_t> > list) {
    jclass clazz;
    FIND_CLASS(clazz, "java/util/ArrayList");
    jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
    List<Vector<uint8_t> >::iterator iter = list.begin();
    while (iter != list.end()) {
        jbyteArray byteArray = VectorToJByteArray(env, *iter);
        env->CallBooleanMethod(arrayList, gFields.arraylist.add, byteArray);
        env->DeleteLocalRef(byteArray);
        iter++;
    }

    return arrayList;
}
int register_android_view_DisplayEventReceiver(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "android/view/DisplayEventReceiver",
            gMethods, NELEM(gMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    FIND_CLASS(gDisplayEventReceiverClassInfo.clazz, "android/view/DisplayEventReceiver");

    GET_METHOD_ID(gDisplayEventReceiverClassInfo.dispatchVsync,
            gDisplayEventReceiverClassInfo.clazz,
            "dispatchVsync", "(JII)V");
    GET_METHOD_ID(gDisplayEventReceiverClassInfo.dispatchHotplug,
            gDisplayEventReceiverClassInfo.clazz,
            "dispatchHotplug", "(J*Z)V");
    return 0;
}
Ejemplo n.º 20
0
static void input_autodetect_get_device_name(void *data, char *buf, size_t size, int id)
{
   struct android_app *android_app = (struct android_app*)data;
   buf[0] = '\0';

   JavaVM *vm = android_app->activity->vm;
   JNIEnv *env = NULL;
   (*vm)->AttachCurrentThread(vm, &env, 0);

   jclass input_device_class = NULL;
   FIND_CLASS(env, input_device_class, "android/view/InputDevice");
   if (!input_device_class)
      goto end;

   jmethodID method = NULL;
   GET_STATIC_METHOD_ID(env, method, input_device_class, "getDevice", "(I)Landroid/view/InputDevice;");
   if (!method)
      goto end;

   jobject device = NULL;
   CALL_OBJ_STATIC_METHOD_PARAM(env, device, input_device_class, method, (jint)id);
   if (!device)
   {
      RARCH_ERR("Failed to find device for ID: %d\n", id);
      goto end;
   }

   jmethodID getName = NULL;
   GET_METHOD_ID(env, getName, input_device_class, "getName", "()Ljava/lang/String;");
   if (!getName)
      goto end;

   jobject name = NULL;
   CALL_OBJ_METHOD(env, name, device, getName);
   if (!name)
   {
      RARCH_ERR("Failed to find name for device ID: %d\n", id);
      goto end;
   }

   const char *str = (*env)->GetStringUTFChars(env, name, 0);
   if (str)
      strlcpy(buf, str, size);
   (*env)->ReleaseStringUTFChars(env, name, str);

end:
   (*vm)->DetachCurrentThread(vm);
}
int register_com_sqlcrypt_database_CursorWindow(JNIEnv * env)
{
    jclass clazz;
    FIND_CLASS(clazz, "com/sqlcrypt/database/CharArrayBuffer");

    GET_FIELD_ID(gCharArrayBufferClassInfo.data, clazz,
            "data", "[C");
    GET_FIELD_ID(gCharArrayBufferClassInfo.sizeCopied, clazz,
            "sizeCopied", "I");

    gEmptyString = jstring(env->NewGlobalRef(env->NewStringUTF("")));
    LOG_FATAL_IF(!gEmptyString, "Unable to create empty string");

    return AndroidRuntime::registerNativeMethods(env, "com/sqlcrypt/database/CursorWindow",
            sMethods, NELEM(sMethods));
}
int register_android_content_res_ObbScanner(JNIEnv* env)
{
    FIND_CLASS(gObbInfoClassInfo.clazz, "android/content/res/ObbInfo");

    GET_FIELD_ID(gObbInfoClassInfo.packageName, gObbInfoClassInfo.clazz,
                 "packageName", "Ljava/lang/String;");
    GET_FIELD_ID(gObbInfoClassInfo.version, gObbInfoClassInfo.clazz,
                 "version", "I");
    GET_FIELD_ID(gObbInfoClassInfo.flags, gObbInfoClassInfo.clazz,
                 "flags", "I");
    GET_FIELD_ID(gObbInfoClassInfo.salt, gObbInfoClassInfo.clazz,
                 "salt", "[B");

    return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
            NELEM(gMethods));
}
int register_android_view_VelocityTracker(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "android/view/VelocityTracker",
            gVelocityTrackerMethods, NELEM(gVelocityTrackerMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    jclass clazz;
    FIND_CLASS(clazz, "android/view/VelocityTracker$Estimator");

    GET_FIELD_ID(gEstimatorClassInfo.xCoeff, clazz,
            "xCoeff", "[F");
    GET_FIELD_ID(gEstimatorClassInfo.yCoeff, clazz,
            "yCoeff", "[F");
    GET_FIELD_ID(gEstimatorClassInfo.degree, clazz,
            "degree", "I");
    GET_FIELD_ID(gEstimatorClassInfo.confidence, clazz,
            "confidence", "F");
    return 0;
}
static KeyedVector<String8, String8> HashMapToKeyedVector(JNIEnv *env, jobject &hashMap) {
    jclass clazz;
    FIND_CLASS(clazz, "java/lang/String");
    KeyedVector<String8, String8> keyedVector;

    jobject entrySet = env->CallObjectMethod(hashMap, gFields.hashmap.entrySet);
    if (entrySet) {
        jobject iterator = env->CallObjectMethod(entrySet, gFields.set.iterator);
        if (iterator) {
            jboolean hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
            while (hasNext) {
                jobject entry = env->CallObjectMethod(iterator, gFields.iterator.next);
                if (entry) {
                    jobject obj = env->CallObjectMethod(entry, gFields.entry.getKey);
                    if (!env->IsInstanceOf(obj, clazz)) {
                        jniThrowException(env, "java/lang/IllegalArgumentException",
                                          "HashMap key is not a String");
                    }
                    jstring jkey = static_cast<jstring>(obj);

                    obj = env->CallObjectMethod(entry, gFields.entry.getValue);
                    if (!env->IsInstanceOf(obj, clazz)) {
                        jniThrowException(env, "java/lang/IllegalArgumentException",
                                          "HashMap value is not a String");
                    }
                    jstring jvalue = static_cast<jstring>(obj);

                    String8 key = JStringToString8(env, jkey);
                    String8 value = JStringToString8(env, jvalue);
                    keyedVector.add(key, value);

                    env->DeleteLocalRef(jkey);
                    env->DeleteLocalRef(jvalue);
                    hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
                }
                env->DeleteLocalRef(entry);
            }
            env->DeleteLocalRef(iterator);
        }
        env->DeleteLocalRef(entrySet);
    }
    return keyedVector;
}
int register_android_server_InputApplicationHandle(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputApplicationHandle",
            gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    jclass clazz;
    FIND_CLASS(clazz, "com/android/server/input/InputApplicationHandle");

    GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz,
            "ptr", "I");

    GET_FIELD_ID(gInputApplicationHandleClassInfo.name, clazz,
            "name", "Ljava/lang/String;");

    GET_FIELD_ID(gInputApplicationHandleClassInfo.dispatchingTimeoutNanos,
            clazz,
            "dispatchingTimeoutNanos", "J");

    return 0;
}
int register_android_server_PowerManagerService(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "com/android/server/PowerManagerService",
            gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    // Callbacks

    FIND_CLASS(gPowerManagerServiceClassInfo.clazz, "com/android/server/PowerManagerService");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, gPowerManagerServiceClassInfo.clazz,
            "goToSleep", "(J)V");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivity, gPowerManagerServiceClassInfo.clazz,
            "userActivity", "(JZIZ)V");

    // Initialize
    for (int i = 0; i < POWER_MANAGER_LAST_EVENT; i++) {
        gLastEventTime[i] = LLONG_MIN;
    }
    gScreenOn = true;
    gScreenBright = true;
    return 0;
}
int register_android_server_tv_TvInputHal(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "com/android/server/tv/TvInputHal",
                                       gTvInputHalMethods, NELEM(gTvInputHalMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
    (void)res; // Don't complain about unused variable in the LOG_NDEBUG case

    jclass clazz;
    FIND_CLASS(clazz, "com/android/server/tv/TvInputHal");

    GET_METHOD_ID(
        gTvInputHalClassInfo.deviceAvailable, clazz,
        "deviceAvailableFromNative", "(Landroid/media/tv/TvInputHardwareInfo;)V");
    GET_METHOD_ID(
        gTvInputHalClassInfo.deviceUnavailable, clazz, "deviceUnavailableFromNative", "(I)V");
    GET_METHOD_ID(
        gTvInputHalClassInfo.streamConfigsChanged, clazz,
        "streamConfigsChangedFromNative", "(I)V");
    GET_METHOD_ID(
        gTvInputHalClassInfo.firstFrameCaptured, clazz,
        "firstFrameCapturedFromNative", "(II)V");

    FIND_CLASS(gTvStreamConfigClassInfo.clazz, "android/media/tv/TvStreamConfig");
    gTvStreamConfigClassInfo.clazz = jclass(env->NewGlobalRef(gTvStreamConfigClassInfo.clazz));

    FIND_CLASS(gTvStreamConfigBuilderClassInfo.clazz, "android/media/tv/TvStreamConfig$Builder");
    gTvStreamConfigBuilderClassInfo.clazz =
        jclass(env->NewGlobalRef(gTvStreamConfigBuilderClassInfo.clazz));

    GET_METHOD_ID(
        gTvStreamConfigBuilderClassInfo.constructor,
        gTvStreamConfigBuilderClassInfo.clazz,
        "<init>", "()V");
    GET_METHOD_ID(
        gTvStreamConfigBuilderClassInfo.streamId,
        gTvStreamConfigBuilderClassInfo.clazz,
        "streamId", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
    GET_METHOD_ID(
        gTvStreamConfigBuilderClassInfo.type,
        gTvStreamConfigBuilderClassInfo.clazz,
        "type", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
    GET_METHOD_ID(
        gTvStreamConfigBuilderClassInfo.maxWidth,
        gTvStreamConfigBuilderClassInfo.clazz,
        "maxWidth", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
    GET_METHOD_ID(
        gTvStreamConfigBuilderClassInfo.maxHeight,
        gTvStreamConfigBuilderClassInfo.clazz,
        "maxHeight", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
    GET_METHOD_ID(
        gTvStreamConfigBuilderClassInfo.generation,
        gTvStreamConfigBuilderClassInfo.clazz,
        "generation", "(I)Landroid/media/tv/TvStreamConfig$Builder;");
    GET_METHOD_ID(
        gTvStreamConfigBuilderClassInfo.build,
        gTvStreamConfigBuilderClassInfo.clazz,
        "build", "()Landroid/media/tv/TvStreamConfig;");

    FIND_CLASS(gTvInputHardwareInfoBuilderClassInfo.clazz,
               "android/media/tv/TvInputHardwareInfo$Builder");
    gTvInputHardwareInfoBuilderClassInfo.clazz =
        jclass(env->NewGlobalRef(gTvInputHardwareInfoBuilderClassInfo.clazz));

    GET_METHOD_ID(
        gTvInputHardwareInfoBuilderClassInfo.constructor,
        gTvInputHardwareInfoBuilderClassInfo.clazz,
        "<init>", "()V");
    GET_METHOD_ID(
        gTvInputHardwareInfoBuilderClassInfo.deviceId,
        gTvInputHardwareInfoBuilderClassInfo.clazz,
        "deviceId", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
    GET_METHOD_ID(
        gTvInputHardwareInfoBuilderClassInfo.type,
        gTvInputHardwareInfoBuilderClassInfo.clazz,
        "type", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
    GET_METHOD_ID(
        gTvInputHardwareInfoBuilderClassInfo.hdmiPortId,
        gTvInputHardwareInfoBuilderClassInfo.clazz,
        "hdmiPortId", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
    GET_METHOD_ID(
        gTvInputHardwareInfoBuilderClassInfo.audioType,
        gTvInputHardwareInfoBuilderClassInfo.clazz,
        "audioType", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
    GET_METHOD_ID(
        gTvInputHardwareInfoBuilderClassInfo.audioAddress,
        gTvInputHardwareInfoBuilderClassInfo.clazz,
        "audioAddress", "(Ljava/lang/String;)Landroid/media/tv/TvInputHardwareInfo$Builder;");
    GET_METHOD_ID(
        gTvInputHardwareInfoBuilderClassInfo.build,
        gTvInputHardwareInfoBuilderClassInfo.clazz,
        "build", "()Landroid/media/tv/TvInputHardwareInfo;");

    return 0;
}
int register_android_server_InputWindowHandle(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputWindowHandle",
            gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    jclass clazz;
    FIND_CLASS(clazz, "com/android/server/input/InputWindowHandle");

    GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, clazz,
            "ptr", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle,
            clazz,
            "inputApplicationHandle", "Lcom/android/server/input/InputApplicationHandle;");

    GET_FIELD_ID(gInputWindowHandleClassInfo.inputChannel, clazz,
            "inputChannel", "Landroid/view/InputChannel;");

    GET_FIELD_ID(gInputWindowHandleClassInfo.name, clazz,
            "name", "Ljava/lang/String;");

    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsFlags, clazz,
            "layoutParamsFlags", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsPrivateFlags, clazz,
            "layoutParamsPrivateFlags", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsType, clazz,
            "layoutParamsType", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.dispatchingTimeoutNanos, clazz,
            "dispatchingTimeoutNanos", "J");

    GET_FIELD_ID(gInputWindowHandleClassInfo.frameLeft, clazz,
            "frameLeft", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.frameTop, clazz,
            "frameTop", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.frameRight, clazz,
            "frameRight", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.frameBottom, clazz,
            "frameBottom", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.scaleFactor, clazz,
            "scaleFactor", "F");

    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
            "touchableRegion", "Landroid/graphics/Region;");

    GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
            "visible", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.canReceiveKeys, clazz,
            "canReceiveKeys", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.hasFocus, clazz,
            "hasFocus", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
            "hasWallpaper", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
            "paused", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.layer, clazz,
            "layer", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
            "ownerPid", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerUid, clazz,
            "ownerUid", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
            "inputFeatures", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
            "displayId", "I");
    return 0;
}