#!/usr/bin/env python
# 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.

"""Tests for jni_generator.py.

This test suite contains various tests for the JNI generator.
It exercises the low-level parser all the way up to the
code generator and ensures the output matches a golden
file.
"""

import difflib
import os
import sys
import unittest
import jni_generator
from jni_generator import CalledByNative, NativeMethod, Param


class TestGenerator(unittest.TestCase):
  def assertObjEquals(self, first, second):
    dict_first = first.__dict__
    dict_second = second.__dict__
    self.assertEquals(dict_first.keys(), dict_second.keys())
    for key, value in dict_first.iteritems():
      if (type(value) is list and len(value) and
          isinstance(type(value[0]), object)):
        self.assertListEquals(value, second.__getattribute__(key))
      else:
        actual = second.__getattribute__(key)
        self.assertEquals(value, actual,
                          'Key ' + key + ': ' + str(value) + '!=' + str(actual))

  def assertListEquals(self, first, second):
    self.assertEquals(len(first), len(second))
    for i in xrange(len(first)):
      if isinstance(first[i], object):
        self.assertObjEquals(first[i], second[i])
      else:
        self.assertEquals(first[i], second[i])

  def assertTextEquals(self, golden_text, generated_text):
    stripped_golden = [l.strip() for l in golden_text.split('\n')]
    stripped_generated = [l.strip() for l in generated_text.split('\n')]
    if stripped_golden != stripped_generated:
      print self.id()
      for line in difflib.context_diff(stripped_golden, stripped_generated):
        print line
      print '\n\nGenerated'
      print '=' * 80
      print generated_text
      print '=' * 80
      self.fail('Golden text mismatch')

  def testNatives(self):
    test_data = """"
    interface OnFrameAvailableListener {}
    private native int nativeInit();
    private native void nativeDestroy(int nativeChromeBrowserProvider);
    private native long nativeAddBookmark(
            int nativeChromeBrowserProvider,
            String url, String title, boolean isFolder, long parentId);
    private static native String nativeGetDomainAndRegistry(String url);
    private static native void nativeCreateHistoricalTabFromState(
            byte[] state, int tab_index);
    private native byte[] nativeGetStateAsByteArray(View view);
    private static native String[] nativeGetAutofillProfileGUIDs();
    private native void nativeSetRecognitionResults(
            int sessionId, String[] results);
    private native long nativeAddBookmarkFromAPI(
            int nativeChromeBrowserProvider,
            String url, Long created, Boolean isBookmark,
            Long date, byte[] favicon, String title, Integer visits);
    native int nativeFindAll(String find);
    private static native OnFrameAvailableListener nativeGetInnerClass();
    private native Bitmap nativeQueryBitmap(
            int nativeChromeBrowserProvider,
            String[] projection, String selection,
            String[] selectionArgs, String sortOrder);
    private native void nativeGotOrientation(
            int nativeDataFetcherImplAndroid,
            double alpha, double beta, double gamma);
    """
    jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data)
    natives = jni_generator.ExtractNatives(test_data)
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init',
                     params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=False, name='Destroy',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='long', static=False, name='AddBookmark',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String',
                                   name='url'),
                             Param(datatype='String',
                                   name='title'),
                             Param(datatype='boolean',
                                   name='isFolder'),
                             Param(datatype='long',
                                   name='parentId')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='String', static=True,
                     name='GetDomainAndRegistry',
                     params=[Param(datatype='String',
                                   name='url')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=True,
                     name='CreateHistoricalTabFromState',
                     params=[Param(datatype='byte[]',
                                   name='state'),
                             Param(datatype='int',
                                   name='tab_index')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='byte[]', static=False,
                     name='GetStateAsByteArray',
                     params=[Param(datatype='View', name='view')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='String[]', static=True,
                     name='GetAutofillProfileGUIDs', params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=False,
                     name='SetRecognitionResults',
                     params=[Param(datatype='int', name='sessionId'),
                             Param(datatype='String[]', name='results')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='long', static=False,
                     name='AddBookmarkFromAPI',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String',
                                   name='url'),
                             Param(datatype='Long',
                                   name='created'),
                             Param(datatype='Boolean',
                                   name='isBookmark'),
                             Param(datatype='Long',
                                   name='date'),
                             Param(datatype='byte[]',
                                   name='favicon'),
                             Param(datatype='String',
                                   name='title'),
                             Param(datatype='Integer',
                                   name='visits')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='int', static=False,
                     name='FindAll',
                     params=[Param(datatype='String',
                                   name='find')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='OnFrameAvailableListener', static=True,
                     name='GetInnerClass',
                     params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='Bitmap',
                     static=False,
                     name='QueryBitmap',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String[]',
                                   name='projection'),
                             Param(datatype='String',
                                   name='selection'),
                             Param(datatype='String[]',
                                   name='selectionArgs'),
                             Param(datatype='String',
                                   name='sortOrder'),
                            ],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='void', static=False,
                     name='GotOrientation',
                     params=[Param(datatype='int',
                                   name='nativeDataFetcherImplAndroid'),
                             Param(datatype='double',
                                   name='alpha'),
                             Param(datatype='double',
                                   name='beta'),
                             Param(datatype='double',
                                   name='gamma'),
                            ],
                     java_class_name=None,
                     type='method',
                     p0_type='content::DataFetcherImplAndroid'),
    ]
    self.assertListEquals(golden_natives, natives)
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             natives, [])
    golden_content = """\
// 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_tests.py
// For
//     org/chromium/TestJni

#ifndef org_chromium_TestJni_JNI
#define org_chromium_TestJni_JNI

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/logging.h"

using base::android::ScopedJavaLocalRef;

// Step 1: forward declarations.
namespace {
const char kTestJniClassPath[] = "org/chromium/TestJni";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_TestJni_clazz = NULL;
}  // namespace

static jint Init(JNIEnv* env, jobject obj);

static jstring GetDomainAndRegistry(JNIEnv* env, jclass clazz,
    jstring url);

static void CreateHistoricalTabFromState(JNIEnv* env, jclass clazz,
    jbyteArray state,
    jint tab_index);

static jbyteArray GetStateAsByteArray(JNIEnv* env, jobject obj,
    jobject view);

static jobjectArray GetAutofillProfileGUIDs(JNIEnv* env, jclass clazz);

static void SetRecognitionResults(JNIEnv* env, jobject obj,
    jint sessionId,
    jobjectArray results);

static jint FindAll(JNIEnv* env, jobject obj,
    jstring find);

static jobject GetInnerClass(JNIEnv* env, jclass clazz);

// Step 2: method stubs.
static void Destroy(JNIEnv* env, jobject obj,
    jint nativeChromeBrowserProvider) {
  DCHECK(nativeChromeBrowserProvider) << "Destroy";
  ChromeBrowserProvider* native =
      reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider);
  return native->Destroy(env, obj);
}

static jlong AddBookmark(JNIEnv* env, jobject obj,
    jint nativeChromeBrowserProvider,
    jstring url,
    jstring title,
    jboolean isFolder,
    jlong parentId) {
  DCHECK(nativeChromeBrowserProvider) << "AddBookmark";
  ChromeBrowserProvider* native =
      reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider);
  return native->AddBookmark(env, obj, url, title, isFolder, parentId);
}

static jlong AddBookmarkFromAPI(JNIEnv* env, jobject obj,
    jint nativeChromeBrowserProvider,
    jstring url,
    jobject created,
    jobject isBookmark,
    jobject date,
    jbyteArray favicon,
    jstring title,
    jobject visits) {
  DCHECK(nativeChromeBrowserProvider) << "AddBookmarkFromAPI";
  ChromeBrowserProvider* native =
      reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider);
  return native->AddBookmarkFromAPI(env, obj, url, created, isBookmark, date,
      favicon, title, visits);
}

static jobject QueryBitmap(JNIEnv* env, jobject obj,
    jint nativeChromeBrowserProvider,
    jobjectArray projection,
    jstring selection,
    jobjectArray selectionArgs,
    jstring sortOrder) {
  DCHECK(nativeChromeBrowserProvider) << "QueryBitmap";
  ChromeBrowserProvider* native =
      reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider);
  return native->QueryBitmap(env, obj, projection, selection, selectionArgs,
      sortOrder).Release();
}

static void GotOrientation(JNIEnv* env, jobject obj,
    jint nativeDataFetcherImplAndroid,
    jdouble alpha,
    jdouble beta,
    jdouble gamma) {
  DCHECK(nativeDataFetcherImplAndroid) << "GotOrientation";
  DataFetcherImplAndroid* native =
      reinterpret_cast<DataFetcherImplAndroid*>(nativeDataFetcherImplAndroid);
  return native->GotOrientation(env, obj, alpha, beta, gamma);
}

// Step 3: RegisterNatives.

static bool RegisterNativesImpl(JNIEnv* env) {

  g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kTestJniClassPath)));
  static const JNINativeMethod kMethodsTestJni[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
    { "nativeDestroy",
"("
"I"
")"
"V", reinterpret_cast<void*>(Destroy) },
    { "nativeAddBookmark",
"("
"I"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Z"
"J"
")"
"J", reinterpret_cast<void*>(AddBookmark) },
    { "nativeGetDomainAndRegistry",
"("
"Ljava/lang/String;"
")"
"Ljava/lang/String;", reinterpret_cast<void*>(GetDomainAndRegistry) },
    { "nativeCreateHistoricalTabFromState",
"("
"[B"
"I"
")"
"V", reinterpret_cast<void*>(CreateHistoricalTabFromState) },
    { "nativeGetStateAsByteArray",
"("
"Landroid/view/View;"
")"
"[B", reinterpret_cast<void*>(GetStateAsByteArray) },
    { "nativeGetAutofillProfileGUIDs",
"("
")"
"[Ljava/lang/String;", reinterpret_cast<void*>(GetAutofillProfileGUIDs) },
    { "nativeSetRecognitionResults",
"("
"I"
"[Ljava/lang/String;"
")"
"V", reinterpret_cast<void*>(SetRecognitionResults) },
    { "nativeAddBookmarkFromAPI",
"("
"I"
"Ljava/lang/String;"
"Ljava/lang/Long;"
"Ljava/lang/Boolean;"
"Ljava/lang/Long;"
"[B"
"Ljava/lang/String;"
"Ljava/lang/Integer;"
")"
"J", reinterpret_cast<void*>(AddBookmarkFromAPI) },
    { "nativeFindAll",
"("
"Ljava/lang/String;"
")"
"I", reinterpret_cast<void*>(FindAll) },
    { "nativeGetInnerClass",
"("
")"
"Lorg/chromium/example/jni_generator/SampleForTests$OnFrameAvailableListener;",
    reinterpret_cast<void*>(GetInnerClass) },
    { "nativeQueryBitmap",
"("
"I"
"[Ljava/lang/String;"
"Ljava/lang/String;"
"[Ljava/lang/String;"
"Ljava/lang/String;"
")"
"Landroid/graphics/Bitmap;", reinterpret_cast<void*>(QueryBitmap) },
    { "nativeGotOrientation",
"("
"I"
"D"
"D"
"D"
")"
"V", reinterpret_cast<void*>(GotOrientation) },
  };
  const int kMethodsTestJniSize = arraysize(kMethodsTestJni);

  if (env->RegisterNatives(g_TestJni_clazz,
                           kMethodsTestJni,
                           kMethodsTestJniSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  return true;
}

#endif  // org_chromium_TestJni_JNI
"""
    self.assertTextEquals(golden_content, h.GetContent())

  def testInnerClassNatives(self):
    test_data = """
    class MyInnerClass {
      @NativeCall("MyInnerClass")
      private native int nativeInit();
    }
    """
    natives = jni_generator.ExtractNatives(test_data)
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name='MyInnerClass',
                     type='function')
    ]
    self.assertListEquals(golden_natives, natives)
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             natives, [])
    golden_content = """\
// 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_tests.py
// For
//     org/chromium/TestJni

#ifndef org_chromium_TestJni_JNI
#define org_chromium_TestJni_JNI

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/logging.h"

using base::android::ScopedJavaLocalRef;

// Step 1: forward declarations.
namespace {
const char kTestJniClassPath[] = "org/chromium/TestJni";
const char kMyInnerClassClassPath[] = "org/chromium/TestJni$MyInnerClass";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_TestJni_clazz = NULL;
}  // namespace

static jint Init(JNIEnv* env, jobject obj);

// Step 2: method stubs.

// Step 3: RegisterNatives.

static bool RegisterNativesImpl(JNIEnv* env) {

  g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kTestJniClassPath)));
  static const JNINativeMethod kMethodsMyInnerClass[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
  };
  const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass);

  if (env->RegisterNatives(g_MyInnerClass_clazz,
                           kMethodsMyInnerClass,
                           kMethodsMyInnerClassSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  return true;
}

#endif  // org_chromium_TestJni_JNI
"""
    self.assertTextEquals(golden_content, h.GetContent())

  def testInnerClassNativesMultiple(self):
    test_data = """
    class MyInnerClass {
      @NativeCall("MyInnerClass")
      private native int nativeInit();
    }
    class MyOtherInnerClass {
      @NativeCall("MyOtherInnerClass")
      private native int nativeInit();
    }
    """
    natives = jni_generator.ExtractNatives(test_data)
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name='MyInnerClass',
                     type='function'),
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name='MyOtherInnerClass',
                     type='function')
    ]
    self.assertListEquals(golden_natives, natives)
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             natives, [])
    golden_content = """\
// 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_tests.py
// For
//     org/chromium/TestJni

#ifndef org_chromium_TestJni_JNI
#define org_chromium_TestJni_JNI

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/logging.h"

using base::android::ScopedJavaLocalRef;

// Step 1: forward declarations.
namespace {
const char kMyOtherInnerClassClassPath[] =
    "org/chromium/TestJni$MyOtherInnerClass";
const char kTestJniClassPath[] = "org/chromium/TestJni";
const char kMyInnerClassClassPath[] = "org/chromium/TestJni$MyInnerClass";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_TestJni_clazz = NULL;
}  // namespace

static jint Init(JNIEnv* env, jobject obj);

static jint Init(JNIEnv* env, jobject obj);

// Step 2: method stubs.

// Step 3: RegisterNatives.

static bool RegisterNativesImpl(JNIEnv* env) {

  g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kTestJniClassPath)));
  static const JNINativeMethod kMethodsMyOtherInnerClass[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
  };
  const int kMethodsMyOtherInnerClassSize =
      arraysize(kMethodsMyOtherInnerClass);

  if (env->RegisterNatives(g_MyOtherInnerClass_clazz,
                           kMethodsMyOtherInnerClass,
                           kMethodsMyOtherInnerClassSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  static const JNINativeMethod kMethodsMyInnerClass[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
  };
  const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass);

  if (env->RegisterNatives(g_MyInnerClass_clazz,
                           kMethodsMyInnerClass,
                           kMethodsMyInnerClassSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  return true;
}

#endif  // org_chromium_TestJni_JNI
"""
    self.assertTextEquals(golden_content, h.GetContent())

  def testInnerClassNativesBothInnerAndOuter(self):
    test_data = """
    class MyOuterClass {
      private native int nativeInit();
      class MyOtherInnerClass {
        @NativeCall("MyOtherInnerClass")
        private native int nativeInit();
      }
    }
    """
    natives = jni_generator.ExtractNatives(test_data)
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='int', static=False,
                     name='Init', params=[],
                     java_class_name='MyOtherInnerClass',
                     type='function')
    ]
    self.assertListEquals(golden_natives, natives)
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             natives, [])
    golden_content = """\
// 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_tests.py
// For
//     org/chromium/TestJni

#ifndef org_chromium_TestJni_JNI
#define org_chromium_TestJni_JNI

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/logging.h"

using base::android::ScopedJavaLocalRef;

// Step 1: forward declarations.
namespace {
const char kMyOtherInnerClassClassPath[] =
    "org/chromium/TestJni$MyOtherInnerClass";
const char kTestJniClassPath[] = "org/chromium/TestJni";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_TestJni_clazz = NULL;
}  // namespace

static jint Init(JNIEnv* env, jobject obj);

static jint Init(JNIEnv* env, jobject obj);

// Step 2: method stubs.

// Step 3: RegisterNatives.

static bool RegisterNativesImpl(JNIEnv* env) {

  g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kTestJniClassPath)));
  static const JNINativeMethod kMethodsMyOtherInnerClass[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
  };
  const int kMethodsMyOtherInnerClassSize =
      arraysize(kMethodsMyOtherInnerClass);

  if (env->RegisterNatives(g_MyOtherInnerClass_clazz,
                           kMethodsMyOtherInnerClass,
                           kMethodsMyOtherInnerClassSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  static const JNINativeMethod kMethodsTestJni[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
  };
  const int kMethodsTestJniSize = arraysize(kMethodsTestJni);

  if (env->RegisterNatives(g_TestJni_clazz,
                           kMethodsTestJni,
                           kMethodsTestJniSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  return true;
}

#endif  // org_chromium_TestJni_JNI
"""
    self.assertTextEquals(golden_content, h.GetContent())

  def testCalledByNatives(self):
    test_data = """"
    import android.graphics.Bitmap;
    import android.view.View;
    import java.io.InputStream;

    class InnerClass {}

    @CalledByNative
    InnerClass showConfirmInfoBar(int nativeInfoBar,
            String buttonOk, String buttonCancel, String title, Bitmap icon) {
        InfoBar infobar = new ConfirmInfoBar(nativeInfoBar, mContext,
                                             buttonOk, buttonCancel,
                                             title, icon);
        return infobar;
    }
    @CalledByNative
    InnerClass showAutoLoginInfoBar(int nativeInfoBar,
            String realm, String account, String args) {
        AutoLoginInfoBar infobar = new AutoLoginInfoBar(nativeInfoBar, mContext,
                realm, account, args);
        if (infobar.displayedAccountCount() == 0)
            infobar = null;
        return infobar;
    }
    @CalledByNative("InfoBar")
    void dismiss();
    @SuppressWarnings("unused")
    @CalledByNative
    private static boolean shouldShowAutoLogin(View view,
            String realm, String account, String args) {
        AccountManagerContainer accountManagerContainer =
            new AccountManagerContainer((Activity)contentView.getContext(),
            realm, account, args);
        String[] logins = accountManagerContainer.getAccountLogins(null);
        return logins.length != 0;
    }
    @CalledByNative
    static InputStream openUrl(String url) {
        return null;
    }
    @CalledByNative
    private void activateHardwareAcceleration(final boolean activated,
            final int iPid, final int iType,
            final int iPrimaryID, final int iSecondaryID) {
      if (!activated) {
          return
      }
    }
    @CalledByNativeUnchecked
    private void uncheckedCall(int iParam);
    """
    jni_generator.JniParams.SetFullyQualifiedClass('org/chromium/Foo')
    jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data)
    called_by_natives = jni_generator.ExtractCalledByNatives(test_data)
    golden_called_by_natives = [
        CalledByNative(
            return_type='InnerClass',
            system_class=False,
            static=False,
            name='showConfirmInfoBar',
            method_id_var_name='showConfirmInfoBar',
            java_class_name='',
            params=[Param(datatype='int', name='nativeInfoBar'),
                    Param(datatype='String', name='buttonOk'),
                    Param(datatype='String', name='buttonCancel'),
                    Param(datatype='String', name='title'),
                    Param(datatype='Bitmap', name='icon')],
            env_call=('Object', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='InnerClass',
            system_class=False,
            static=False,
            name='showAutoLoginInfoBar',
            method_id_var_name='showAutoLoginInfoBar',
            java_class_name='',
            params=[Param(datatype='int', name='nativeInfoBar'),
                    Param(datatype='String', name='realm'),
                    Param(datatype='String', name='account'),
                    Param(datatype='String', name='args')],
            env_call=('Object', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='void',
            system_class=False,
            static=False,
            name='dismiss',
            method_id_var_name='dismiss',
            java_class_name='InfoBar',
            params=[],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='boolean',
            system_class=False,
            static=True,
            name='shouldShowAutoLogin',
            method_id_var_name='shouldShowAutoLogin',
            java_class_name='',
            params=[Param(datatype='View', name='view'),
                    Param(datatype='String', name='realm'),
                    Param(datatype='String', name='account'),
                    Param(datatype='String', name='args')],
            env_call=('Boolean', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='InputStream',
            system_class=False,
            static=True,
            name='openUrl',
            method_id_var_name='openUrl',
            java_class_name='',
            params=[Param(datatype='String', name='url')],
            env_call=('Object', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='void',
            system_class=False,
            static=False,
            name='activateHardwareAcceleration',
            method_id_var_name='activateHardwareAcceleration',
            java_class_name='',
            params=[Param(datatype='boolean', name='activated'),
                    Param(datatype='int', name='iPid'),
                    Param(datatype='int', name='iType'),
                    Param(datatype='int', name='iPrimaryID'),
                    Param(datatype='int', name='iSecondaryID'),
                   ],
            env_call=('Void', ''),
            unchecked=False,
        ),
        CalledByNative(
            return_type='void',
            system_class=False,
            static=False,
            name='uncheckedCall',
            method_id_var_name='uncheckedCall',
            java_class_name='',
            params=[Param(datatype='int', name='iParam')],
            env_call=('Void', ''),
            unchecked=True,
        ),
    ]
    self.assertListEquals(golden_called_by_natives, called_by_natives)
    h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                             [], called_by_natives)
    golden_content = """\
// 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_tests.py
// For
//     org/chromium/TestJni

#ifndef org_chromium_TestJni_JNI
#define org_chromium_TestJni_JNI

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/logging.h"

using base::android::ScopedJavaLocalRef;

// 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 ScopedJavaLocalRef<jobject> Java_TestJni_showConfirmInfoBar(JNIEnv* env,
    jobject obj, jint nativeInfoBar,
    jstring buttonOk,
    jstring buttonCancel,
    jstring title,
    jobject icon) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_TestJni_clazz);
  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, nativeInfoBar, buttonOk, buttonCancel, title, icon);
  base::android::CheckException(env);
  return ScopedJavaLocalRef<jobject>(env, ret);
}

static base::subtle::AtomicWord g_TestJni_showAutoLoginInfoBar = 0;
static ScopedJavaLocalRef<jobject> Java_TestJni_showAutoLoginInfoBar(JNIEnv*
    env, jobject obj, jint nativeInfoBar,
    jstring realm,
    jstring account,
    jstring args) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_TestJni_clazz);
  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, nativeInfoBar, realm, account, args);
  base::android::CheckException(env);
  return ScopedJavaLocalRef<jobject>(env, ret);
}

static base::subtle::AtomicWord g_InfoBar_dismiss = 0;
static void Java_InfoBar_dismiss(JNIEnv* env, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(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);
  base::android::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()  */
  DCHECK(g_TestJni_clazz);
  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);
  base::android::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_TestJni_openUrl = 0;
static ScopedJavaLocalRef<jobject> Java_TestJni_openUrl(JNIEnv* env, jstring
    url) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_TestJni_clazz);
  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);
  base::android::CheckException(env);
  return ScopedJavaLocalRef<jobject>(env, ret);
}

static base::subtle::AtomicWord g_TestJni_activateHardwareAcceleration = 0;
static void Java_TestJni_activateHardwareAcceleration(JNIEnv* env, jobject obj,
    jboolean activated,
    jint iPid,
    jint iType,
    jint iPrimaryID,
    jint iSecondaryID) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(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, iPid, iType, iPrimaryID, iSecondaryID);
  base::android::CheckException(env);

}

static base::subtle::AtomicWord g_TestJni_uncheckedCall = 0;
static void Java_TestJni_uncheckedCall(JNIEnv* env, jobject obj, jint iParam) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(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, iParam);

}

// Step 3: RegisterNatives.

static bool RegisterNativesImpl(JNIEnv* env) {

  g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kTestJniClassPath)));
  g_InfoBar_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kInfoBarClassPath)));
  return true;
}

#endif  // org_chromium_TestJni_JNI
"""
    self.assertTextEquals(golden_content, h.GetContent())

  def testCalledByNativeParseError(self):
    try:
      jni_generator.ExtractCalledByNatives("""
@CalledByNative
public static int foo(); // This one is fine

@CalledByNative
scooby doo
""")
      self.fail('Expected a ParseError')
    except jni_generator.ParseError, e:
      self.assertEquals(('@CalledByNative', 'scooby doo'), e.context_lines)

  def testFullyQualifiedClassName(self):
    contents = """
// Copyright (c) 2010 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.

package org.chromium.content.browser;

import org.chromium.base.BuildInfo;
"""
    self.assertEquals('org/chromium/content/browser/Foo',
                      jni_generator.ExtractFullyQualifiedJavaClassName(
                          'org/chromium/content/browser/Foo.java', contents))
    self.assertEquals('org/chromium/content/browser/Foo',
                      jni_generator.ExtractFullyQualifiedJavaClassName(
                          'frameworks/Foo.java', contents))
    self.assertRaises(SyntaxError,
                      jni_generator.ExtractFullyQualifiedJavaClassName,
                      'com/foo/Bar', 'no PACKAGE line')

  def testMethodNameMangling(self):
    self.assertEquals('closeV',
        jni_generator.GetMangledMethodName('close', [], 'void'))
    self.assertEquals('readI_AB_I_I',
        jni_generator.GetMangledMethodName('read',
            [Param(name='p1',
                   datatype='byte[]'),
             Param(name='p2',
                   datatype='int'),
             Param(name='p3',
                   datatype='int'),],
             'int'))
    self.assertEquals('openJIIS_JLS',
        jni_generator.GetMangledMethodName('open',
            [Param(name='p1',
                   datatype='java/lang/String'),],
             'java/io/InputStream'))

  def testFromJavaP(self):
    contents = """
public abstract class java.io.InputStream extends java.lang.Object
      implements java.io.Closeable{
    public java.io.InputStream();
    public int available()       throws java.io.IOException;
    public void close()       throws java.io.IOException;
    public void mark(int);
    public boolean markSupported();
    public abstract int read()       throws java.io.IOException;
    public int read(byte[])       throws java.io.IOException;
    public int read(byte[], int, int)       throws java.io.IOException;
    public synchronized void reset()       throws java.io.IOException;
    public long skip(long)       throws java.io.IOException;
}
"""
    jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'), None)
    self.assertEquals(10, len(jni_from_javap.called_by_natives))
    golden_content = """\
// 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_tests.py
// For
//     java/io/InputStream

#ifndef java_io_InputStream_JNI
#define java_io_InputStream_JNI

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/logging.h"

using base::android::ScopedJavaLocalRef;

// Step 1: forward declarations.
namespace {
const char kInputStreamClassPath[] = "java/io/InputStream";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_InputStream_clazz = NULL;
}  // namespace

namespace JNI_InputStream {

// Step 2: method stubs.

static base::subtle::AtomicWord g_InputStream_available = 0;
static jint Java_InputStream_available(JNIEnv* env, jobject obj) __attribute__
    ((unused));
static jint Java_InputStream_available(JNIEnv* env, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "available",

"("
")"
"I",
      &g_InputStream_available);

  jint ret =
    env->CallIntMethod(obj,
      method_id);
  base::android::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_InputStream_close = 0;
static void Java_InputStream_close(JNIEnv* env, jobject obj) __attribute__
    ((unused));
static void Java_InputStream_close(JNIEnv* env, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "close",

"("
")"
"V",
      &g_InputStream_close);

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

}

static base::subtle::AtomicWord g_InputStream_mark = 0;
static void Java_InputStream_mark(JNIEnv* env, jobject obj, jint p0)
    __attribute__ ((unused));
static void Java_InputStream_mark(JNIEnv* env, jobject obj, jint p0) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "mark",

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

  env->CallVoidMethod(obj,
      method_id, p0);
  base::android::CheckException(env);

}

static base::subtle::AtomicWord g_InputStream_markSupported = 0;
static jboolean Java_InputStream_markSupported(JNIEnv* env, jobject obj)
    __attribute__ ((unused));
static jboolean Java_InputStream_markSupported(JNIEnv* env, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "markSupported",

"("
")"
"Z",
      &g_InputStream_markSupported);

  jboolean ret =
    env->CallBooleanMethod(obj,
      method_id);
  base::android::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_InputStream_readI = 0;
static jint Java_InputStream_readI(JNIEnv* env, jobject obj) __attribute__
    ((unused));
static jint Java_InputStream_readI(JNIEnv* env, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "read",

"("
")"
"I",
      &g_InputStream_readI);

  jint ret =
    env->CallIntMethod(obj,
      method_id);
  base::android::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_InputStream_readI_AB = 0;
static jint Java_InputStream_readI_AB(JNIEnv* env, jobject obj, jbyteArray p0)
    __attribute__ ((unused));
static jint Java_InputStream_readI_AB(JNIEnv* env, jobject obj, jbyteArray p0) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "read",

"("
"[B"
")"
"I",
      &g_InputStream_readI_AB);

  jint ret =
    env->CallIntMethod(obj,
      method_id, p0);
  base::android::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_InputStream_readI_AB_I_I = 0;
static jint Java_InputStream_readI_AB_I_I(JNIEnv* env, jobject obj, jbyteArray
    p0,
    jint p1,
    jint p2) __attribute__ ((unused));
static jint Java_InputStream_readI_AB_I_I(JNIEnv* env, jobject obj, jbyteArray
    p0,
    jint p1,
    jint p2) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "read",

"("
"[B"
"I"
"I"
")"
"I",
      &g_InputStream_readI_AB_I_I);

  jint ret =
    env->CallIntMethod(obj,
      method_id, p0, p1, p2);
  base::android::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_InputStream_reset = 0;
static void Java_InputStream_reset(JNIEnv* env, jobject obj) __attribute__
    ((unused));
static void Java_InputStream_reset(JNIEnv* env, jobject obj) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "reset",

"("
")"
"V",
      &g_InputStream_reset);

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

}

static base::subtle::AtomicWord g_InputStream_skip = 0;
static jlong Java_InputStream_skip(JNIEnv* env, jobject obj, jlong p0)
    __attribute__ ((unused));
static jlong Java_InputStream_skip(JNIEnv* env, jobject obj, jlong p0) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "skip",

"("
"J"
")"
"J",
      &g_InputStream_skip);

  jlong ret =
    env->CallLongMethod(obj,
      method_id, p0);
  base::android::CheckException(env);
  return ret;
}

static base::subtle::AtomicWord g_InputStream_Constructor = 0;
static ScopedJavaLocalRef<jobject> Java_InputStream_Constructor(JNIEnv* env)
    __attribute__ ((unused));
static ScopedJavaLocalRef<jobject> Java_InputStream_Constructor(JNIEnv* env) {
  /* Must call RegisterNativesImpl()  */
  DCHECK(g_InputStream_clazz);
  jmethodID method_id =
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_INSTANCE>(
      env, g_InputStream_clazz,
      "<init>",

"("
")"
"V",
      &g_InputStream_Constructor);

  jobject ret =
    env->NewObject(g_InputStream_clazz,
      method_id);
  base::android::CheckException(env);
  return ScopedJavaLocalRef<jobject>(env, ret);
}

// Step 3: RegisterNatives.

static bool RegisterNativesImpl(JNIEnv* env) {

  g_InputStream_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kInputStreamClassPath)));
  return true;
}
}  // namespace JNI_InputStream

#endif  // java_io_InputStream_JNI
"""
    self.assertTextEquals(golden_content, jni_from_javap.GetContent())

  def testREForNatives(self):
    # We should not match "native SyncSetupFlow" inside the comment.
    test_data = """
    /**
     * Invoked when the setup process is complete so we can disconnect from the
     * native-side SyncSetupFlowHandler.
     */
    public void destroy() {
        Log.v(TAG, "Destroying native SyncSetupFlow");
        if (mNativeSyncSetupFlow != 0) {
            nativeSyncSetupEnded(mNativeSyncSetupFlow);
            mNativeSyncSetupFlow = 0;
        }
    }
    private native void nativeSyncSetupEnded(
        int nativeAndroidSyncSetupFlowHandler);
    """
    jni_from_java = jni_generator.JNIFromJavaSource(test_data, 'foo/bar')

  def testRaisesOnNonJNIMethod(self):
    test_data = """
    class MyInnerClass {
      private int Foo(int p0) {
      }
    }
    """
    self.assertRaises(SyntaxError,
                      jni_generator.JNIFromJavaSource,
                      test_data, 'foo/bar')

  def testJniSelfDocumentingExample(self):
    script_dir = os.path.dirname(sys.argv[0])
    content = file(os.path.join(script_dir, 'SampleForTests.java')).read()
    golden_content = file(os.path.join(script_dir,
                                       'golden_sample_for_tests_jni.h')).read()
    jni_from_java = jni_generator.JNIFromJavaSource(
        content, 'org/chromium/example/jni_generator/SampleForTests')
    self.assertTextEquals(golden_content, jni_from_java.GetContent())

  def testNoWrappingPreprocessorLines(self):
    test_data = """
    package com.google.lookhowextremelylongiam.snarf.icankeepthisupallday;

    class ReallyLongClassNamesAreAllTheRage {
        private static native int nativeTest();
    }
    """
    jni_from_java = jni_generator.JNIFromJavaSource(
        test_data, ('com/google/lookhowextremelylongiam/snarf/'
                    'icankeepthisupallday/ReallyLongClassNamesAreAllTheRage'))
    jni_lines = jni_from_java.GetContent().split('\n')
    line = filter(lambda line: line.lstrip().startswith('#ifndef'),
                  jni_lines)[0]
    self.assertTrue(len(line) > 80,
                    ('Expected #ifndef line to be > 80 chars: ', line))

  def testImports(self):
    import_header = """
// 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.

package org.chromium.content.app;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.view.Surface;

import java.util.ArrayList;

import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.content.app.ContentMain;
import org.chromium.content.browser.SandboxedProcessConnection;
import org.chromium.content.common.ISandboxedProcessCallback;
import org.chromium.content.common.ISandboxedProcessService;
import org.chromium.content.common.SurfaceCallback;
import org.chromium.content.common.WillNotRaise.AnException;
import org.chromium.content.common.WillRaise.AnException;

import static org.chromium.Bar.Zoo;

class Foo {
  public static class BookmarkNode implements Parcelable {
  }
  public interface PasswordListObserver {
  }
}
    """
    jni_generator.JniParams.SetFullyQualifiedClass(
        'org/chromium/content/app/Foo')
    jni_generator.JniParams.ExtractImportsAndInnerClasses(import_header)
    self.assertTrue('Lorg/chromium/content/common/ISandboxedProcessService' in
                    jni_generator.JniParams._imports)
    self.assertTrue('Lorg/chromium/Bar/Zoo' in
                    jni_generator.JniParams._imports)
    self.assertTrue('Lorg/chromium/content/app/Foo$BookmarkNode' in
                    jni_generator.JniParams._inner_classes)
    self.assertTrue('Lorg/chromium/content/app/Foo$PasswordListObserver' in
                    jni_generator.JniParams._inner_classes)
    self.assertEquals('Lorg/chromium/content/app/ContentMain$Inner',
                      jni_generator.JniParams.JavaToJni('ContentMain.Inner'))
    self.assertRaises(SyntaxError,
                      jni_generator.JniParams.JavaToJni,
                      'AnException')


if __name__ == '__main__':
  unittest.main()
