// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.


// This file is autogenerated by
//     base/android/jni_generator/jni_generator.py
// For
//     org/chromium/example/jni_generator/SampleForTests

#ifndef org_chromium_example_jni_generator_SampleForTests_JNI
#define org_chromium_example_jni_generator_SampleForTests_JNI

#include <jni.h>

#include "base/android/jni_generator/jni_generator_helper.h"


// Step 1: Forward declarations.

JNI_REGISTRATION_EXPORT extern const char
    kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA[];
const char kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA[] =
    "org/chromium/example/jni_generator/SampleForTests$InnerStructA";

JNI_REGISTRATION_EXPORT extern const char
    kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerClass[];
const char kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerClass[] =
    "org/chromium/example/jni_generator/SampleForTests$InnerClass";

JNI_REGISTRATION_EXPORT extern const char
    kClassPath_org_chromium_example_jni_1generator_SampleForTests[];
const char kClassPath_org_chromium_example_jni_1generator_SampleForTests[] =
    "org/chromium/example/jni_generator/SampleForTests";

JNI_REGISTRATION_EXPORT extern const char
    kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB[];
const char kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB[] =
    "org/chromium/example/jni_generator/SampleForTests$InnerStructB";
// Leaking this jclass as we cannot use LazyInstance from some threads.
JNI_REGISTRATION_EXPORT std::atomic<jclass>
    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(nullptr);
#ifndef org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz_defined
#define org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz_defined
inline jclass org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(JNIEnv*
    env) {
  return base::android::LazyGetClass(env,
      kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA,
      &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz);
}
#endif
// Leaking this jclass as we cannot use LazyInstance from some threads.
JNI_REGISTRATION_EXPORT std::atomic<jclass>
    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerClass_clazz(nullptr);
#ifndef org_chromium_example_jni_1generator_SampleForTests_00024InnerClass_clazz_defined
#define org_chromium_example_jni_1generator_SampleForTests_00024InnerClass_clazz_defined
inline jclass org_chromium_example_jni_1generator_SampleForTests_00024InnerClass_clazz(JNIEnv* env)
    {
  return base::android::LazyGetClass(env,
      kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerClass,
      &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerClass_clazz);
}
#endif
// Leaking this jclass as we cannot use LazyInstance from some threads.
JNI_REGISTRATION_EXPORT std::atomic<jclass>
    g_org_chromium_example_jni_1generator_SampleForTests_clazz(nullptr);
#ifndef org_chromium_example_jni_1generator_SampleForTests_clazz_defined
#define org_chromium_example_jni_1generator_SampleForTests_clazz_defined
inline jclass org_chromium_example_jni_1generator_SampleForTests_clazz(JNIEnv* env) {
  return base::android::LazyGetClass(env,
      kClassPath_org_chromium_example_jni_1generator_SampleForTests,
      &g_org_chromium_example_jni_1generator_SampleForTests_clazz);
}
#endif
// Leaking this jclass as we cannot use LazyInstance from some threads.
JNI_REGISTRATION_EXPORT std::atomic<jclass>
    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(nullptr);
#ifndef org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz_defined
#define org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz_defined
inline jclass org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(JNIEnv*
    env) {
  return base::android::LazyGetClass(env,
      kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB,
      &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz);
}
#endif


// Step 2: Constants (optional).


// Step 3: Method stubs.
namespace base {
namespace android {

static jlong JNI_SampleForTests_Init(JNIEnv* env, const base::android::JavaParamRef<jobject>&
    jcaller,
    const base::android::JavaParamRef<jstring>& param);

JNI_GENERATOR_EXPORT jlong Java_org_chromium_example_jni_1generator_SampleForTests_nativeInit(
    JNIEnv* env,
    jobject jcaller,
    jstring param) {
  return JNI_SampleForTests_Init(env, base::android::JavaParamRef<jobject>(env, jcaller),
      base::android::JavaParamRef<jstring>(env, param));
}

JNI_GENERATOR_EXPORT void Java_org_chromium_example_jni_1generator_SampleForTests_nativeDestroy(
    JNIEnv* env,
    jobject jcaller,
    jlong nativeCPPClass) {
  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
  CHECK_NATIVE_PTR(env, jcaller, native, "Destroy");
  return native->Destroy(env, base::android::JavaParamRef<jobject>(env, jcaller));
}

static jdouble JNI_SampleForTests_GetDoubleFunction(JNIEnv* env, const
    base::android::JavaParamRef<jobject>& jcaller);

JNI_GENERATOR_EXPORT jdouble
    Java_org_chromium_example_jni_1generator_SampleForTests_nativeGetDoubleFunction(
    JNIEnv* env,
    jobject jcaller) {
  return JNI_SampleForTests_GetDoubleFunction(env, base::android::JavaParamRef<jobject>(env,
      jcaller));
}

static jfloat JNI_SampleForTests_GetFloatFunction(JNIEnv* env, const
    base::android::JavaParamRef<jclass>& jcaller);

JNI_GENERATOR_EXPORT jfloat
    Java_org_chromium_example_jni_1generator_SampleForTests_nativeGetFloatFunction(
    JNIEnv* env,
    jclass jcaller) {
  return JNI_SampleForTests_GetFloatFunction(env, base::android::JavaParamRef<jclass>(env,
      jcaller));
}

static void JNI_SampleForTests_SetNonPODDatatype(JNIEnv* env, const
    base::android::JavaParamRef<jobject>& jcaller,
    const base::android::JavaParamRef<jobject>& rect);

JNI_GENERATOR_EXPORT void
    Java_org_chromium_example_jni_1generator_SampleForTests_nativeSetNonPODDatatype(
    JNIEnv* env,
    jobject jcaller,
    jobject rect) {
  return JNI_SampleForTests_SetNonPODDatatype(env, base::android::JavaParamRef<jobject>(env,
      jcaller), base::android::JavaParamRef<jobject>(env, rect));
}

static base::android::ScopedJavaLocalRef<jobject> JNI_SampleForTests_GetNonPODDatatype(JNIEnv* env,
    const base::android::JavaParamRef<jobject>& jcaller);

JNI_GENERATOR_EXPORT jobject
    Java_org_chromium_example_jni_1generator_SampleForTests_nativeGetNonPODDatatype(
    JNIEnv* env,
    jobject jcaller) {
  return JNI_SampleForTests_GetNonPODDatatype(env, base::android::JavaParamRef<jobject>(env,
      jcaller)).Release();
}

JNI_GENERATOR_EXPORT jint Java_org_chromium_example_jni_1generator_SampleForTests_nativeMethod(
    JNIEnv* env,
    jobject jcaller,
    jlong nativeCPPClass) {
  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
  CHECK_NATIVE_PTR(env, jcaller, native, "Method", 0);
  return native->Method(env, base::android::JavaParamRef<jobject>(env, jcaller));
}

JNI_GENERATOR_EXPORT jdouble
    Java_org_chromium_example_jni_1generator_SampleForTests_nativeMethodOtherP0(
    JNIEnv* env,
    jobject jcaller,
    jlong nativePtr) {
  CPPClass::InnerClass* native = reinterpret_cast<CPPClass::InnerClass*>(nativePtr);
  CHECK_NATIVE_PTR(env, jcaller, native, "MethodOtherP0", 0);
  return native->MethodOtherP0(env, base::android::JavaParamRef<jobject>(env, jcaller));
}

JNI_GENERATOR_EXPORT void Java_org_chromium_example_jni_1generator_SampleForTests_nativeAddStructB(
    JNIEnv* env,
    jobject jcaller,
    jlong nativeCPPClass,
    jobject b) {
  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
  CHECK_NATIVE_PTR(env, jcaller, native, "AddStructB");
  return native->AddStructB(env, base::android::JavaParamRef<jobject>(env, jcaller),
      base::android::JavaParamRef<jobject>(env, b));
}

JNI_GENERATOR_EXPORT void
    Java_org_chromium_example_jni_1generator_SampleForTests_nativeIterateAndDoSomethingWithStructB(
    JNIEnv* env,
    jobject jcaller,
    jlong nativeCPPClass) {
  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
  CHECK_NATIVE_PTR(env, jcaller, native, "IterateAndDoSomethingWithStructB");
  return native->IterateAndDoSomethingWithStructB(env, base::android::JavaParamRef<jobject>(env,
      jcaller));
}

JNI_GENERATOR_EXPORT jstring
    Java_org_chromium_example_jni_1generator_SampleForTests_nativeReturnAString(
    JNIEnv* env,
    jobject jcaller,
    jlong nativeCPPClass) {
  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
  CHECK_NATIVE_PTR(env, jcaller, native, "ReturnAString", NULL);
  return native->ReturnAString(env, base::android::JavaParamRef<jobject>(env, jcaller)).Release();
}

static jint JNI_InnerClass_GetInnerIntFunction(JNIEnv* env, const
    base::android::JavaParamRef<jclass>& jcaller);

JNI_GENERATOR_EXPORT jint
    Java_org_chromium_example_jni_1generator_SampleForTests_00024InnerClass_nativeGetInnerIntFunction(
    JNIEnv* env,
    jclass jcaller) {
  return JNI_InnerClass_GetInnerIntFunction(env, base::android::JavaParamRef<jclass>(env, jcaller));
}


static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_javaMethod(nullptr);
static jint Java_SampleForTests_javaMethod(JNIEnv* env, const base::android::JavaRef<jobject>& obj,
    JniIntWrapper foo,
    JniIntWrapper bar) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env), 0);
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "javaMethod",
          "(II)I",
          &g_org_chromium_example_jni_1generator_SampleForTests_javaMethod);

  jint ret =
      env->CallIntMethod(obj.obj(),
          method_id, as_jint(foo), as_jint(bar));
  jni_generator::CheckException(env);
  return ret;
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_staticJavaMethod(nullptr);
static jboolean Java_SampleForTests_staticJavaMethod(JNIEnv* env) {
  CHECK_CLAZZ(env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env), false);
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "staticJavaMethod",
          "()Z",
          &g_org_chromium_example_jni_1generator_SampleForTests_staticJavaMethod);

  jboolean ret =
      env->CallStaticBooleanMethod(org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          method_id);
  jni_generator::CheckException(env);
  return ret;
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_packagePrivateJavaMethod(nullptr);
static void Java_SampleForTests_packagePrivateJavaMethod(JNIEnv* env, const
    base::android::JavaRef<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "packagePrivateJavaMethod",
          "()V",
          &g_org_chromium_example_jni_1generator_SampleForTests_packagePrivateJavaMethod);

     env->CallVoidMethod(obj.obj(),
          method_id);
  jni_generator::CheckException(env);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_methodWithGenericParams(nullptr);
static void Java_SampleForTests_methodWithGenericParams(JNIEnv* env, const
    base::android::JavaRef<jobject>& obj, const base::android::JavaRef<jobject>& foo,
    const base::android::JavaRef<jobject>& bar) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "methodWithGenericParams",
          "(Ljava/util/Map;Ljava/util/LinkedList;)V",
          &g_org_chromium_example_jni_1generator_SampleForTests_methodWithGenericParams);

     env->CallVoidMethod(obj.obj(),
          method_id, foo.obj(), bar.obj());
  jni_generator::CheckException(env);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_Constructor(nullptr);
static base::android::ScopedJavaLocalRef<jobject> Java_SampleForTests_Constructor(JNIEnv* env,
    JniIntWrapper foo,
    JniIntWrapper bar) {
  CHECK_CLAZZ(env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env), NULL);
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "<init>",
          "(II)V",
          &g_org_chromium_example_jni_1generator_SampleForTests_Constructor);

  jobject ret =
      env->NewObject(org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          method_id, as_jint(foo), as_jint(bar));
  jni_generator::CheckException(env);
  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_methodThatThrowsException(nullptr);
static void Java_SampleForTests_methodThatThrowsException(JNIEnv* env, const
    base::android::JavaRef<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "methodThatThrowsException",
          "()V",
          &g_org_chromium_example_jni_1generator_SampleForTests_methodThatThrowsException);

     env->CallVoidMethod(obj.obj(),
          method_id);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_javaMethodWithAnnotatedParam(nullptr);
static void Java_SampleForTests_javaMethodWithAnnotatedParam(JNIEnv* env, const
    base::android::JavaRef<jobject>& obj, JniIntWrapper foo) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "javaMethodWithAnnotatedParam",
          "(I)V",
          &g_org_chromium_example_jni_1generator_SampleForTests_javaMethodWithAnnotatedParam);

     env->CallVoidMethod(obj.obj(),
          method_id, as_jint(foo));
  jni_generator::CheckException(env);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_create(nullptr);
static base::android::ScopedJavaLocalRef<jobject> Java_InnerStructA_create(JNIEnv* env, jlong l,
    JniIntWrapper i,
    const base::android::JavaRef<jstring>& s) {
  CHECK_CLAZZ(env, org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(env),
      org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(env), NULL);
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
          env, org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(env),
          "create",
          "(JILjava/lang/String;)Lorg/chromium/example/jni_generator/SampleForTests$InnerStructA;",
          &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_create);

  jobject ret =
env->CallStaticObjectMethod(org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(env),
          method_id, l, as_jint(i), s.obj());
  jni_generator::CheckException(env);
  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_addStructA(nullptr);
static void Java_SampleForTests_addStructA(JNIEnv* env, const base::android::JavaRef<jobject>& obj,
    const base::android::JavaRef<jobject>& a) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "addStructA",
          "(Lorg/chromium/example/jni_generator/SampleForTests$InnerStructA;)V",
          &g_org_chromium_example_jni_1generator_SampleForTests_addStructA);

     env->CallVoidMethod(obj.obj(),
          method_id, a.obj());
  jni_generator::CheckException(env);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomething(nullptr);
static void Java_SampleForTests_iterateAndDoSomething(JNIEnv* env, const
    base::android::JavaRef<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "iterateAndDoSomething",
          "()V",
          &g_org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomething);

     env->CallVoidMethod(obj.obj(),
          method_id);
  jni_generator::CheckException(env);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getKey(nullptr);
static jlong Java_InnerStructB_getKey(JNIEnv* env, const base::android::JavaRef<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env), 0);
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env),
          "getKey",
          "()J",
          &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getKey);

  jlong ret =
      env->CallLongMethod(obj.obj(),
          method_id);
  jni_generator::CheckException(env);
  return ret;
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getValue(nullptr);
static base::android::ScopedJavaLocalRef<jstring> Java_InnerStructB_getValue(JNIEnv* env, const
    base::android::JavaRef<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env), NULL);
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
          env, org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env),
          "getValue",
          "()Ljava/lang/String;",
          &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getValue);

  jstring ret =
      static_cast<jstring>(env->CallObjectMethod(obj.obj(),
          method_id));
  jni_generator::CheckException(env);
  return base::android::ScopedJavaLocalRef<jstring>(env, ret);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_getInnerInterface(nullptr);
static base::android::ScopedJavaLocalRef<jobject> Java_SampleForTests_getInnerInterface(JNIEnv* env)
    {
  CHECK_CLAZZ(env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env), NULL);
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "getInnerInterface",
          "()Lorg/chromium/example/jni_generator/SampleForTests$InnerInterface;",
          &g_org_chromium_example_jni_1generator_SampleForTests_getInnerInterface);

  jobject ret =
      env->CallStaticObjectMethod(org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          method_id);
  jni_generator::CheckException(env);
  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
}

static std::atomic<jmethodID>
    g_org_chromium_example_jni_1generator_SampleForTests_getInnerEnum(nullptr);
static base::android::ScopedJavaLocalRef<jobject> Java_SampleForTests_getInnerEnum(JNIEnv* env) {
  CHECK_CLAZZ(env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
      org_chromium_example_jni_1generator_SampleForTests_clazz(env), NULL);
  jmethodID method_id = base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
          env, org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          "getInnerEnum",
          "()Lorg/chromium/example/jni_generator/SampleForTests$InnerEnum;",
          &g_org_chromium_example_jni_1generator_SampleForTests_getInnerEnum);

  jobject ret =
      env->CallStaticObjectMethod(org_chromium_example_jni_1generator_SampleForTests_clazz(env),
          method_id);
  jni_generator::CheckException(env);
  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
}

}  // namespace android
}  // namespace base

#endif  // org_chromium_example_jni_generator_SampleForTests_JNI
