// 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/TestJni

#ifndef org_chromium_TestJni_JNI
#define org_chromium_TestJni_JNI

#include <jni.h>

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

#include "base/android/jni_int_wrapper.h"

// Step 1: forward declarations.
namespace {
const char kTestJniClassPath[] = "org/chromium/TestJni";
const char kInfoBarClassPath[] = "org/chromium/TestJni$InfoBar";
// Leaking this jclass as we cannot use LazyInstance from some threads.
base::subtle::AtomicWord g_TestJni_clazz __attribute__((unused)) = 0;
#define TestJni_clazz(env) base::android::LazyGetClass(env, kTestJniClassPath, &g_TestJni_clazz)
// Leaking this jclass as we cannot use LazyInstance from some threads.
base::subtle::AtomicWord g_InfoBar_clazz __attribute__((unused)) = 0;
#define InfoBar_clazz(env) base::android::LazyGetClass(env, kInfoBarClassPath, &g_InfoBar_clazz)

}  // namespace

// Step 2: method stubs.

static base::subtle::AtomicWord g_TestJni_showConfirmInfoBar = 0;
static base::android::ScopedJavaLocalRef<jobject>
    Java_TestJni_showConfirmInfoBar(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper nativeInfoBar,
    const base::android::JavaRefOrBare<jstring>& buttonOk,
    const base::android::JavaRefOrBare<jstring>& buttonCancel,
    const base::android::JavaRefOrBare<jstring>& title,
    const base::android::JavaRefOrBare<jobject>& icon) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "showConfirmInfoBar",
"("
"I"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Landroid/graphics/Bitmap;"
")"
"Lorg/chromium/Foo$InnerClass;",
      &g_TestJni_showConfirmInfoBar);

  jobject ret =
      env->CallObjectMethod(obj.obj(),
          method_id, as_jint(nativeInfoBar), buttonOk.obj(), buttonCancel.obj(),
              title.obj(), icon.obj());
  jni_generator::CheckException(env);
  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
}

static base::subtle::AtomicWord g_TestJni_showAutoLoginInfoBar = 0;
static base::android::ScopedJavaLocalRef<jobject>
    Java_TestJni_showAutoLoginInfoBar(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper nativeInfoBar,
    const base::android::JavaRefOrBare<jstring>& realm,
    const base::android::JavaRefOrBare<jstring>& account,
    const base::android::JavaRefOrBare<jstring>& args) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "showAutoLoginInfoBar",
"("
"I"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Ljava/lang/String;"
")"
"Lorg/chromium/Foo$InnerClass;",
      &g_TestJni_showAutoLoginInfoBar);

  jobject ret =
      env->CallObjectMethod(obj.obj(),
          method_id, as_jint(nativeInfoBar), realm.obj(), account.obj(),
              args.obj());
  jni_generator::CheckException(env);
  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
}

static base::subtle::AtomicWord g_InfoBar_dismiss = 0;
static void Java_InfoBar_dismiss(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      InfoBar_clazz(env));
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, InfoBar_clazz(env),
      "dismiss",
"("
")"
"V",
      &g_InfoBar_dismiss);

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

static base::subtle::AtomicWord g_TestJni_shouldShowAutoLogin = 0;
static jboolean Java_TestJni_shouldShowAutoLogin(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& view,
    const base::android::JavaRefOrBare<jstring>& realm,
    const base::android::JavaRefOrBare<jstring>& account,
    const base::android::JavaRefOrBare<jstring>& args) {
  CHECK_CLAZZ(env, TestJni_clazz(env),
      TestJni_clazz(env), false);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
      env, TestJni_clazz(env),
      "shouldShowAutoLogin",
"("
"Landroid/view/View;"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Ljava/lang/String;"
")"
"Z",
      &g_TestJni_shouldShowAutoLogin);

  jboolean ret =
      env->CallStaticBooleanMethod(TestJni_clazz(env),
          method_id, view.obj(), realm.obj(), account.obj(), args.obj());
  jni_generator::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_TestJni_openUrl = 0;
static base::android::ScopedJavaLocalRef<jobject> Java_TestJni_openUrl(JNIEnv*
    env, const base::android::JavaRefOrBare<jstring>& url) {
  CHECK_CLAZZ(env, TestJni_clazz(env),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
      env, TestJni_clazz(env),
      "openUrl",
"("
"Ljava/lang/String;"
")"
"Ljava/io/InputStream;",
      &g_TestJni_openUrl);

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

static base::subtle::AtomicWord g_TestJni_activateHardwareAcceleration = 0;
static void Java_TestJni_activateHardwareAcceleration(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj, jboolean activated,
    JniIntWrapper iPid,
    JniIntWrapper iType,
    JniIntWrapper iPrimaryID,
    JniIntWrapper iSecondaryID) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env));
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "activateHardwareAcceleration",
"("
"Z"
"I"
"I"
"I"
"I"
")"
"V",
      &g_TestJni_activateHardwareAcceleration);

     env->CallVoidMethod(obj.obj(),
          method_id, activated, as_jint(iPid), as_jint(iType),
              as_jint(iPrimaryID), as_jint(iSecondaryID));
  jni_generator::CheckException(env);
}

static base::subtle::AtomicWord g_TestJni_updateStatus = 0;
static jint Java_TestJni_updateStatus(JNIEnv* env, JniIntWrapper status) {
  CHECK_CLAZZ(env, TestJni_clazz(env),
      TestJni_clazz(env), 0);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
      env, TestJni_clazz(env),
      "updateStatus",
"("
"I"
")"
"I",
      &g_TestJni_updateStatus);

  jint ret =
      env->CallStaticIntMethod(TestJni_clazz(env),
          method_id, as_jint(status));
  jni_generator::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_TestJni_uncheckedCall = 0;
static void Java_TestJni_uncheckedCall(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj, JniIntWrapper iParam) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env));
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "uncheckedCall",
"("
"I"
")"
"V",
      &g_TestJni_uncheckedCall);

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

static base::subtle::AtomicWord g_TestJni_returnByteArray = 0;
static base::android::ScopedJavaLocalRef<jbyteArray>
    Java_TestJni_returnByteArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnByteArray",
"("
")"
"[B",
      &g_TestJni_returnByteArray);

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

static base::subtle::AtomicWord g_TestJni_returnBooleanArray = 0;
static base::android::ScopedJavaLocalRef<jbooleanArray>
    Java_TestJni_returnBooleanArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnBooleanArray",
"("
")"
"[Z",
      &g_TestJni_returnBooleanArray);

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

static base::subtle::AtomicWord g_TestJni_returnCharArray = 0;
static base::android::ScopedJavaLocalRef<jcharArray>
    Java_TestJni_returnCharArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnCharArray",
"("
")"
"[C",
      &g_TestJni_returnCharArray);

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

static base::subtle::AtomicWord g_TestJni_returnShortArray = 0;
static base::android::ScopedJavaLocalRef<jshortArray>
    Java_TestJni_returnShortArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnShortArray",
"("
")"
"[S",
      &g_TestJni_returnShortArray);

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

static base::subtle::AtomicWord g_TestJni_returnIntArray = 0;
static base::android::ScopedJavaLocalRef<jintArray>
    Java_TestJni_returnIntArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnIntArray",
"("
")"
"[I",
      &g_TestJni_returnIntArray);

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

static base::subtle::AtomicWord g_TestJni_returnLongArray = 0;
static base::android::ScopedJavaLocalRef<jlongArray>
    Java_TestJni_returnLongArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnLongArray",
"("
")"
"[J",
      &g_TestJni_returnLongArray);

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

static base::subtle::AtomicWord g_TestJni_returnDoubleArray = 0;
static base::android::ScopedJavaLocalRef<jdoubleArray>
    Java_TestJni_returnDoubleArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnDoubleArray",
"("
")"
"[D",
      &g_TestJni_returnDoubleArray);

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

static base::subtle::AtomicWord g_TestJni_returnObjectArray = 0;
static base::android::ScopedJavaLocalRef<jobjectArray>
    Java_TestJni_returnObjectArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnObjectArray",
"("
")"
"[Ljava/lang/Object;",
      &g_TestJni_returnObjectArray);

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

static base::subtle::AtomicWord g_TestJni_returnArrayOfByteArray = 0;
static base::android::ScopedJavaLocalRef<jobjectArray>
    Java_TestJni_returnArrayOfByteArray(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "returnArrayOfByteArray",
"("
")"
"[[B",
      &g_TestJni_returnArrayOfByteArray);

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

static base::subtle::AtomicWord g_TestJni_getCompressFormat = 0;
static base::android::ScopedJavaLocalRef<jobject>
    Java_TestJni_getCompressFormat(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "getCompressFormat",
"("
")"
"Landroid/graphics/Bitmap$CompressFormat;",
      &g_TestJni_getCompressFormat);

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

static base::subtle::AtomicWord g_TestJni_getCompressFormatList = 0;
static base::android::ScopedJavaLocalRef<jobject>
    Java_TestJni_getCompressFormatList(JNIEnv* env, const
    base::android::JavaRefOrBare<jobject>& obj) {
  CHECK_CLAZZ(env, obj.obj(),
      TestJni_clazz(env), NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, TestJni_clazz(env),
      "getCompressFormatList",
"("
")"
"Ljava/util/List;",
      &g_TestJni_getCompressFormatList);

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

// Step 3: RegisterNatives.

#endif  // org_chromium_TestJni_JNI
