// Copyright (c) 2012 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.
jclass g_TestJni_clazz = NULL;
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_InfoBar_clazz = NULL;

}  // namespace

// Step 2: method stubs.

static base::subtle::AtomicWord g_TestJni_showConfirmInfoBar = 0;
static base::android::ScopedJavaLocalRef<jobject>
    Java_TestJni_showConfirmInfoBar(JNIEnv* env, jobject obj, JniIntWrapper
    nativeInfoBar,
    jstring buttonOk,
    jstring buttonCancel,
    jstring title,
    jobject icon) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "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,
          method_id, as_jint(nativeInfoBar), buttonOk, buttonCancel, title,
              icon);
  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, jobject obj, JniIntWrapper
    nativeInfoBar,
    jstring realm,
    jstring account,
    jstring args) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "showAutoLoginInfoBar",

"("
"I"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Ljava/lang/String;"
")"
"Lorg/chromium/Foo$InnerClass;",
      &g_TestJni_showAutoLoginInfoBar);

  jobject ret =
      env->CallObjectMethod(obj,
          method_id, as_jint(nativeInfoBar), realm, account, args);
  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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_InfoBar_clazz);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InfoBar_clazz,
      "dismiss",

"("
")"
"V",
      &g_InfoBar_dismiss);

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

}

static base::subtle::AtomicWord g_TestJni_shouldShowAutoLogin = 0;
static jboolean Java_TestJni_shouldShowAutoLogin(JNIEnv* env, jobject view,
    jstring realm,
    jstring account,
    jstring args) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, g_TestJni_clazz,
      g_TestJni_clazz, false);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
      env, g_TestJni_clazz,
      "shouldShowAutoLogin",

"("
"Landroid/view/View;"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Ljava/lang/String;"
")"
"Z",
      &g_TestJni_shouldShowAutoLogin);

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

static base::subtle::AtomicWord g_TestJni_openUrl = 0;
static base::android::ScopedJavaLocalRef<jobject> Java_TestJni_openUrl(JNIEnv*
    env, jstring url) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, g_TestJni_clazz,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_STATIC>(
      env, g_TestJni_clazz,
      "openUrl",

"("
"Ljava/lang/String;"
")"
"Ljava/io/InputStream;",
      &g_TestJni_openUrl);

  jobject ret =
      env->CallStaticObjectMethod(g_TestJni_clazz,
          method_id, url);
  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, jobject obj,
    jboolean activated,
    JniIntWrapper iPid,
    JniIntWrapper iType,
    JniIntWrapper iPrimaryID,
    JniIntWrapper iSecondaryID) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "activateHardwareAcceleration",

"("
"Z"
"I"
"I"
"I"
"I"
")"
"V",
      &g_TestJni_activateHardwareAcceleration);

     env->CallVoidMethod(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_uncheckedCall = 0;
static void Java_TestJni_uncheckedCall(JNIEnv* env, jobject obj, JniIntWrapper
    iParam) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "uncheckedCall",

"("
"I"
")"
"V",
      &g_TestJni_uncheckedCall);

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

}

static base::subtle::AtomicWord g_TestJni_returnByteArray = 0;
static base::android::ScopedJavaLocalRef<jbyteArray>
    Java_TestJni_returnByteArray(JNIEnv* env, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnByteArray",

"("
")"
"[B",
      &g_TestJni_returnByteArray);

  jbyteArray ret =
      static_cast<jbyteArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnBooleanArray",

"("
")"
"[Z",
      &g_TestJni_returnBooleanArray);

  jbooleanArray ret =
      static_cast<jbooleanArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnCharArray",

"("
")"
"[C",
      &g_TestJni_returnCharArray);

  jcharArray ret =
      static_cast<jcharArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnShortArray",

"("
")"
"[S",
      &g_TestJni_returnShortArray);

  jshortArray ret =
      static_cast<jshortArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnIntArray",

"("
")"
"[I",
      &g_TestJni_returnIntArray);

  jintArray ret =
      static_cast<jintArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnLongArray",

"("
")"
"[J",
      &g_TestJni_returnLongArray);

  jlongArray ret =
      static_cast<jlongArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnDoubleArray",

"("
")"
"[D",
      &g_TestJni_returnDoubleArray);

  jdoubleArray ret =
      static_cast<jdoubleArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnObjectArray",

"("
")"
"[Ljava/lang/Object;",
      &g_TestJni_returnObjectArray);

  jobjectArray ret =
      static_cast<jobjectArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "returnArrayOfByteArray",

"("
")"
"[[B",
      &g_TestJni_returnArrayOfByteArray);

  jobjectArray ret =
      static_cast<jobjectArray>(env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "getCompressFormat",

"("
")"
"Landroid/graphics/Bitmap$CompressFormat;",
      &g_TestJni_getCompressFormat);

  jobject ret =
      env->CallObjectMethod(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, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, obj,
      g_TestJni_clazz, NULL);
  jmethodID method_id =
      base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_TestJni_clazz,
      "getCompressFormatList",

"("
")"
"Ljava/util/List;",
      &g_TestJni_getCompressFormatList);

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

// Step 3: RegisterNatives.

static bool RegisterNativesImpl(JNIEnv* env) {
  g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetClass(env, kTestJniClassPath).obj()));
  g_InfoBar_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetClass(env, kInfoBarClassPath).obj()));

  return true;
}

#endif  // org_chromium_TestJni_JNI
