Bug 1406168 - 1. Remove JNI.jsm; r?sebastian draft
authorJim Chen <nchen@mozilla.com>
Tue, 31 Oct 2017 11:43:07 -0400
changeset 689462 9bb12713021d15a85987a1554b2ce4b93d865869
parent 689353 371e44e0034771ec8a5ac3c5a6518ef608227b99
child 689463 62be054900379962223c845092e9e6ba5c33d2fc
push id87029
push userbmo:nchen@mozilla.com
push dateTue, 31 Oct 2017 15:44:03 +0000
reviewerssebastian
bugs1406168
milestone58.0a1
Bug 1406168 - 1. Remove JNI.jsm; r?sebastian Remove JNI.jsm. Convert code that used JNI.jsm to the equivalent using EventDispatcher. MozReview-Commit-ID: JQdCubcTBAR
mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
mobile/android/base/java/org/mozilla/gecko/Tabs.java
mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
mobile/android/chrome/content/browser.js
mobile/android/components/DirectoryProvider.js
mobile/android/components/HelperAppDialog.js
mobile/android/modules/JNI.jsm
mobile/android/modules/moz.build
mobile/android/tests/browser/chrome/chrome.ini
mobile/android/tests/browser/chrome/test_jni.html
mobile/android/tests/browser/chrome/test_restricted_profiles.html
tools/lint/eslint/modules.json
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
@@ -284,16 +284,19 @@ public class GeckoApplication extends Ap
         NotificationHelper.getInstance(context).init();
 
         MulticastDNSManager.getInstance(context).init();
 
         GeckoService.register();
 
         IntentHelper.init();
 
+        EventDispatcher.getInstance().registerGeckoThreadListener(mListener,
+                "Distribution:GetDirectories",
+                null);
         EventDispatcher.getInstance().registerUiThreadListener(mListener,
                 "Gecko:Exited",
                 "RuntimePermissions:Check",
                 "Snackbar:Show",
                 "Share:Text",
                 null);
         EventDispatcher.getInstance().registerBackgroundThreadListener(mListener,
                 "Profile:Create",
@@ -302,16 +305,19 @@ public class GeckoApplication extends Ap
         super.onCreate();
     }
 
     /**
      * May be called when a new GeckoApplication object
      * replaces an old one due to assets change.
      */
     private void onDestroy() {
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(mListener,
+                "Distribution:GetDirectories",
+                null);
         EventDispatcher.getInstance().unregisterUiThreadListener(mListener,
                 "Gecko:Exited",
                 "RuntimePermissions:Check",
                 "Snackbar:Show",
                 "Share:Text",
                 null);
         EventDispatcher.getInstance().unregisterBackgroundThreadListener(mListener,
                 "Profile:Create",
@@ -489,16 +495,19 @@ public class GeckoApplication extends Ap
                         callback.sendError("No activity");
                     }
                     return;
                 }
                 SnackbarBuilder.builder(currentActivity)
                         .fromEvent(message)
                         .callback(callback)
                         .buildAndShow();
+
+            } else if ("Distribution:GetDirectories".equals(event)) {
+                callback.sendSuccess(Distribution.getDistributionDirectories());
             }
         }
     }
 
     public boolean isApplicationInBackground() {
         return mInBackground;
     }
 
--- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java
@@ -11,17 +11,16 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import android.content.SharedPreferences;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
-import org.mozilla.gecko.annotation.JNITarget;
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.distribution.PartnerBrowserCustomizationsClient;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.mozglue.SafeIntent;
 import org.mozilla.gecko.notifications.WhatsNewReceiver;
 import org.mozilla.gecko.preferences.GeckoPreferences;
 import org.mozilla.gecko.reader.ReaderModeUtils;
@@ -138,16 +137,20 @@ public class Tabs implements BundleEvent
                 db.getTabsAccessor().persistLocalTabs(context.getContentResolver(), tabs);
             } catch (SQLiteException e) {
                 Log.w(LOGTAG, "Error persisting local tabs", e);
             }
         }
     };
 
     private Tabs() {
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
+            "Tab:GetNextTabId",
+            null);
+
         EventDispatcher.getInstance().registerUiThreadListener(this,
             "Content:LocationChange",
             "Content:SubframeNavigation",
             "Content:SecurityChange",
             "Content:StateChange",
             "Content:LoadError",
             "Content:PageShow",
             "Content:DOMTitleChanged",
@@ -688,16 +691,19 @@ public class Tabs implements BundleEvent
                 notifyListeners(tab, TabEvents.MEDIA_PLAYING_RESUME);
             } else {
                 tab.setIsMediaPlaying(status.equals("start"));
                 notifyListeners(tab, TabEvents.MEDIA_PLAYING_CHANGE);
             }
 
         } else if ("Tab:SetParentId".equals(event)) {
             tab.setParentId(message.getInt("parentID", INVALID_TAB_ID));
+
+        } else if ("Tab:GetNextTabId".equals(event)) {
+            callback.sendSuccess(getNextTabId());
         }
     }
 
     public void refreshThumbnails() {
         final BrowserDB db = BrowserDB.from(mAppContext);
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
             public void run() {
@@ -1113,18 +1119,17 @@ public class Tabs implements BundleEvent
         }
 
         loadUrl(url, null, parentId, flags);
     }
 
     /**
      * Gets the next tab ID.
      */
-    @JNITarget
-    public static int getNextTabId() {
+    private static int getNextTabId() {
         return sTabId.getAndIncrement();
     }
 
     private int getTabColor(Tab tab) {
         if (tab != null) {
             return tab.isPrivate() ? mPrivateClearColor : Color.WHITE;
         }
 
--- a/mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
+++ b/mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
@@ -39,17 +39,16 @@ import org.json.JSONException;
 import org.json.JSONObject;
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoApplication;
 import org.mozilla.gecko.GeckoSharedPrefs;
 import org.mozilla.gecko.Telemetry;
-import org.mozilla.gecko.annotation.JNITarget;
 import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.ProxySelector;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.app.Activity;
 import android.content.Context;
@@ -921,17 +920,16 @@ public class Distribution {
 
         return null;
     }
 
     private String getDataDir() {
         return context.getApplicationInfo().dataDir;
     }
 
-    @JNITarget
     public static String[] getDistributionDirectories() {
         final Context context = GeckoAppShell.getApplicationContext();
 
         final String[] dataDirectories = getDataDistributionDirectories(context);
         final String[] systemDirectories = getSystemDistributionDirectories(context);
 
         final String[] directories = new String[dataDirectories.length + systemDirectories.length];
 
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -26,19 +26,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/AsyncPrefs.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Manifests",
                                   "resource://gre/modules/Manifest.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "JNI",
-                                  "resource://gre/modules/JNI.jsm");
-
 XPCOMUtils.defineLazyModuleGetter(this, "UITelemetry",
                                   "resource://gre/modules/UITelemetry.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
                                   "resource://gre/modules/PluralForm.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                                   "resource://gre/modules/Downloads.jsm");
@@ -3621,24 +3618,20 @@ Tab.prototype = {
     // Java and new tabs from Gecko.
     let stub = false;
 
     if (!aParams.zombifying) {
       if ("tabID" in aParams) {
         this.id = aParams.tabID;
         stub = true;
       } else {
-        let jenv = JNI.GetForThread();
-        let jTabs = JNI.LoadClass(jenv, "org.mozilla.gecko.Tabs", {
-          static_methods: [
-            { name: "getNextTabId", sig: "()I" }
-          ],
+        // Send a synchronous Gecko thread event.
+        GlobalEventDispatcher.dispatch("Tab:GetNextTabId", null, {
+          onSuccess: response => this.id = response,
         });
-        this.id = jTabs.getNextTabId();
-        JNI.UnloadClasses(jenv);
       }
 
       this.desktopMode = ("desktopMode" in aParams) ? aParams.desktopMode : false;
       this._parentId = ("parentId" in aParams && typeof aParams.parentId == "number")
                       ? aParams.parentId : -1;
 
       let message = {
         type: "Tab:Added",
--- a/mobile/android/components/DirectoryProvider.js
+++ b/mobile/android/components/DirectoryProvider.js
@@ -1,22 +1,23 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "JNI", "resource://gre/modules/JNI.jsm");
+XPCOMUtils.defineLazyModuleGetters(this, {
+  AppConstants: "resource://gre/modules/AppConstants.jsm",
+  FileUtils: "resource://gre/modules/FileUtils.jsm",
+  Services: "resource://gre/modules/Services.jsm",
+});
 
 // -----------------------------------------------------------------------
 // Directory Provider for special browser folders and files
 // -----------------------------------------------------------------------
 
 const NS_APP_CACHE_PARENT_DIR = "cachePDir";
 const NS_APP_SEARCH_DIR       = "SrchPlugns";
 const NS_APP_SEARCH_DIR_LIST  = "SrchPluginsDL";
@@ -173,37 +174,20 @@ DirectoryProvider.prototype = {
       getNext: function() {
         return result.shift();
       }
     };
   },
 
   _getDistributionDirectories: function() {
     let directories = [];
-    let jenv = null;
 
-    try {
-      jenv = JNI.GetForThread();
-
-      let jDistribution = JNI.LoadClass(jenv, "org.mozilla.gecko.distribution.Distribution", {
-        static_methods: [
-          { name: "getDistributionDirectories", sig: "()[Ljava/lang/String;" }
-        ],
-      });
-
-      let jDirectories = jDistribution.getDistributionDirectories();
-
-      for (let i = 0; i < jDirectories.length; i++) {
-        directories.push(new FileUtils.File(
-          JNI.ReadString(jenv, jDirectories.get(i))
-        ));
-      }
-    } finally {
-      if (jenv) {
-        JNI.UnloadClasses(jenv);
-      }
-    }
+    // Send a synchronous Gecko thread event.
+    EventDispatcher.instance.dispatch("Distribution:GetDirectories", null, {
+      onSuccess: response =>
+        directories = response.map(dir => new FileUtils.File(dir)),
+    });
 
     return directories;
   }
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]);
--- a/mobile/android/components/HelperAppDialog.js
+++ b/mobile/android/components/HelperAppDialog.js
@@ -12,28 +12,29 @@ const APK_MIME_TYPE = "application/vnd.a
 const OMA_DOWNLOAD_DESCRIPTOR_MIME_TYPE = "application/vnd.oma.dd+xml";
 const OMA_DRM_MESSAGE_MIME = "application/vnd.oma.drm.message";
 const OMA_DRM_CONTENT_MIME = "application/vnd.oma.drm.content";
 const OMA_DRM_RIGHTS_MIME = "application/vnd.oma.drm.rights+wbxml";
 
 const PREF_BD_USEDOWNLOADDIR = "browser.download.useDownloadDir";
 const URI_GENERIC_ICON_DOWNLOAD = "drawable://alert_download";
 
-Cu.import("resource://gre/modules/Downloads.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/HelperApps.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "RuntimePermissions", "resource://gre/modules/RuntimePermissions.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "EventDispatcher", "resource://gre/modules/Messaging.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Snackbars", "resource://gre/modules/Snackbars.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "JNI", "resource://gre/modules/JNI.jsm");
+XPCOMUtils.defineLazyModuleGetters(this, {
+  Downloads: "resource://gre/modules/Downloads.jsm",
+  EventDispatcher: "resource://gre/modules/Messaging.jsm",
+  FileUtils: "resource://gre/modules/FileUtils.jsm",
+  HelperApps: "resource://gre/modules/HelperApps.jsm",
+  NetUtil: "resource://gre/modules/NetUtil.jsm",
+  RuntimePermissions: "resource://gre/modules/RuntimePermissions.jsm",
+  Services: "resource://gre/modules/Services.jsm",
+  Snackbars: "resource://gre/modules/Snackbars.jsm",
+  Task: "resource://gre/modules/Task.jsm",
+});
 
 // -----------------------------------------------------------------------
 // HelperApp Launcher Dialog
 // -----------------------------------------------------------------------
 
 XPCOMUtils.defineLazyGetter(this, "ContentAreaUtils", function() {
   let ContentAreaUtils = {};
   Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", ContentAreaUtils);
@@ -236,35 +237,17 @@ HelperAppLauncherDialog.prototype = {
     });
   },
 
   /**
    * In the system app chooser, the order of the "Always" and "Just once" buttons has been swapped
    * around starting from Lollipop.
    */
   _useNewButtonOrder: function() {
-    let useNewButtonOrder = true;
-    let jenv = null;
-
-    try {
-      jenv = JNI.GetForThread();
-      let jAppConstants = JNI.LoadClass(jenv, "org.mozilla.gecko.AppConstants$Versions", {
-        static_fields: [
-          { name: "feature21Plus", sig: "Z" }
-        ],
-      });
-
-      useNewButtonOrder = jAppConstants.feature21Plus;
-    } finally {
-      if (jenv) {
-        JNI.UnloadClasses(jenv);
-      }
-    }
-
-    return useNewButtonOrder;
+    return Services.sysinfo.getPropertyAsUint32("version") >= 21;
   },
 
   _refuseDownload: function(aLauncher) {
     aLauncher.cancel(Cr.NS_BINDING_ABORTED);
 
     Services.console.logStringMessage("Refusing download of non-downloadable file.");
 
     let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
deleted file mode 100644
--- a/mobile/android/modules/JNI.jsm
+++ /dev/null
@@ -1,1167 +0,0 @@
-// JavaScript to Java bridge via the Java Native Interface
-// Allows calling into Android SDK from JavaScript in Firefox Add-On.
-// Released into the public domain.
-//  C. Scott Ananian <cscott@laptop.org> (http://cscott.net)
-
-// NOTE: All changes to this file should first be pushed to the repo at:
-// https://github.com/cscott/skeleton-addon-fxandroid/tree/jni
-
-var EXPORTED_SYMBOLS = ["JNI", "android_log"];
-
-Components.utils.import("resource://gre/modules/ctypes.jsm");
-
-var liblog = ctypes.open("liblog.so");
-var android_log = liblog.declare("__android_log_write",
-                             ctypes.default_abi,
-                             ctypes.int32_t,
-                             ctypes.int32_t,
-                             ctypes.char.ptr,
-                             ctypes.char.ptr);
-
-var libxul = ctypes.open("libxul.so");
-
-var jenvptr = ctypes.voidptr_t;
-var jclass = ctypes.voidptr_t;
-var jobject = ctypes.voidptr_t;
-var jvalue = ctypes.voidptr_t;
-var jmethodid = ctypes.voidptr_t;
-var jfieldid = ctypes.voidptr_t;
-
-var jboolean = ctypes.uint8_t;
-var jbyte = ctypes.int8_t;
-var jchar = ctypes.uint16_t;
-var jshort = ctypes.int16_t;
-var jint = ctypes.int32_t;
-var jlong = ctypes.int64_t;
-var jfloat = ctypes.float32_t;
-var jdouble = ctypes.float64_t;
-
-var jsize = jint;
-var jstring = jobject;
-var jarray = jobject;
-var jthrowable = jobject;
-
-var JNINativeInterface = new ctypes.StructType(
-    "JNINativeInterface",
-    [{reserved0: ctypes.voidptr_t},
-     {reserved1: ctypes.voidptr_t},
-     {reserved2: ctypes.voidptr_t},
-     {reserved3: ctypes.voidptr_t},
-     {GetVersion: new ctypes.FunctionType(ctypes.default_abi,
-                                          ctypes.int32_t,
-                                          [ctypes.voidptr_t]).ptr},
-     {DefineClass: new ctypes.FunctionType(ctypes.default_abi,
-                                           jclass,
-                                           [jenvptr, ctypes.char.ptr, jobject,
-                                            jbyte.array(), jsize]).ptr},
-     {FindClass: new ctypes.FunctionType(ctypes.default_abi,
-                                         jclass,
-                                         [jenvptr,
-                                          ctypes.char.ptr]).ptr},
-     {FromReflectedMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                   jmethodid,
-                                                   [jenvptr, jobject]).ptr},
-     {FromReflectedField: new ctypes.FunctionType(ctypes.default_abi,
-                                                  jfieldid,
-                                                  [jenvptr, jobject]).ptr},
-     {ToReflectedMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                 jobject,
-                                                 [jenvptr, jclass,
-                                                  jmethodid]).ptr},
-     {GetSuperclass: new ctypes.FunctionType(ctypes.default_abi,
-                                             jclass, [jenvptr, jclass]).ptr},
-     {IsAssignableFrom: new ctypes.FunctionType(ctypes.default_abi,
-                                                jboolean,
-                                                [jenvptr, jclass, jclass]).ptr},
-     {ToReflectedField: new ctypes.FunctionType(ctypes.default_abi,
-                                                jobject,
-                                                [jenvptr, jclass,
-                                                 jfieldid]).ptr},
-     {Throw: new ctypes.FunctionType(ctypes.default_abi,
-                                     jint, [jenvptr, jthrowable]).ptr},
-     {ThrowNew: new ctypes.FunctionType(ctypes.default_abi,
-                                        jint, [jenvptr, jclass,
-                                               ctypes.char.ptr]).ptr},
-     {ExceptionOccurred: new ctypes.FunctionType(ctypes.default_abi,
-                                                 jthrowable, [jenvptr]).ptr},
-     {ExceptionDescribe: new ctypes.FunctionType(ctypes.default_abi,
-                                                 ctypes.void_t, [jenvptr]).ptr},
-     {ExceptionClear: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t, [jenvptr]).ptr},
-     {FatalError: new ctypes.FunctionType(ctypes.default_abi,
-                                          ctypes.void_t,
-                                          [jenvptr,
-                                           ctypes.char.ptr]).ptr},
-     {PushLocalFrame: new ctypes.FunctionType(ctypes.default_abi,
-                                              jint,
-                                              [jenvptr, jint]).ptr},
-     {PopLocalFrame: new ctypes.FunctionType(ctypes.default_abi,
-                                             jobject,
-                                             [jenvptr, jobject]).ptr},
-     {NewGlobalRef: new ctypes.FunctionType(ctypes.default_abi,
-                                            jobject, [jenvptr, jobject]).ptr},
-     {DeleteGlobalRef: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr,
-                                               jobject]).ptr},
-     {DeleteLocalRef: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr,
-                                               jobject]).ptr},
-     {IsSameObject: new ctypes.FunctionType(ctypes.default_abi,
-                                            jboolean,
-                                            [jenvptr, jobject, jobject]).ptr},
-     {NewLocalRef: new ctypes.FunctionType(ctypes.default_abi,
-                                            jobject, [jenvptr, jobject]).ptr},
-     {EnsureLocalCapacity: new ctypes.FunctionType(ctypes.default_abi,
-                                                   jint, [jenvptr, jint]).ptr},
-     {AllocObject: new ctypes.FunctionType(ctypes.default_abi,
-                                           jobject, [jenvptr, jclass]).ptr},
-     {NewObject: new ctypes.FunctionType(ctypes.default_abi,
-                                         jobject,
-                                         [jenvptr,
-                                          jclass,
-                                          jmethodid,
-                                          "..."]).ptr},
-     {NewObjectV: ctypes.voidptr_t},
-     {NewObjectA: ctypes.voidptr_t},
-     {GetObjectClass: new ctypes.FunctionType(ctypes.default_abi,
-                                              jclass,
-                                              [jenvptr, jobject]).ptr},
-     {IsInstanceOf: new ctypes.FunctionType(ctypes.default_abi,
-                                            jboolean,
-                                            [jenvptr, jobject, jclass]).ptr},
-     {GetMethodID: new ctypes.FunctionType(ctypes.default_abi,
-                                           jmethodid,
-                                           [jenvptr,
-                                            jclass,
-                                            ctypes.char.ptr,
-                                            ctypes.char.ptr]).ptr},
-     {CallObjectMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                jobject,
-                                                [jenvptr, jobject, jmethodid,
-                                                 "..."]).ptr},
-     {CallObjectMethodV: ctypes.voidptr_t},
-     {CallObjectMethodA: ctypes.voidptr_t},
-     {CallBooleanMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                 jboolean,
-                                                 [jenvptr,
-                                                  jobject,
-                                                  jmethodid,
-                                                  "..."]).ptr},
-     {CallBooleanMethodV: ctypes.voidptr_t},
-     {CallBooleanMethodA: ctypes.voidptr_t},
-     {CallByteMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                              jbyte,
-                                              [jenvptr,
-                                               jobject,
-                                               jmethodid,
-                                               "..."]).ptr},
-     {CallByteMethodV: ctypes.voidptr_t},
-     {CallByteMethodA: ctypes.voidptr_t},
-     {CallCharMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                              jchar,
-                                              [jenvptr,
-                                               jobject,
-                                               jmethodid,
-                                               "..."]).ptr},
-     {CallCharMethodV: ctypes.voidptr_t},
-     {CallCharMethodA: ctypes.voidptr_t},
-     {CallShortMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                               jshort,
-                                               [jenvptr,
-                                                jobject,
-                                                jmethodid,
-                                                "..."]).ptr},
-     {CallShortMethodV: ctypes.voidptr_t},
-     {CallShortMethodA: ctypes.voidptr_t},
-     {CallIntMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                             jint,
-                                             [jenvptr,
-                                              jobject,
-                                              jmethodid,
-                                              "..."]).ptr},
-     {CallIntMethodV: ctypes.voidptr_t},
-     {CallIntMethodA: ctypes.voidptr_t},
-     {CallLongMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                              jlong,
-                                              [jenvptr,
-                                               jobject,
-                                               jmethodid,
-                                               "..."]).ptr},
-     {CallLongMethodV: ctypes.voidptr_t},
-     {CallLongMethodA: ctypes.voidptr_t},
-     {CallFloatMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                               jfloat,
-                                               [jenvptr,
-                                                jobject,
-                                                jmethodid,
-                                                "..."]).ptr},
-     {CallFloatMethodV: ctypes.voidptr_t},
-     {CallFloatMethodA: ctypes.voidptr_t},
-     {CallDoubleMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                jdouble,
-                                                [jenvptr,
-                                                 jobject,
-                                                 jmethodid,
-                                                 "..."]).ptr},
-     {CallDoubleMethodV: ctypes.voidptr_t},
-     {CallDoubleMethodA: ctypes.voidptr_t},
-     {CallVoidMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr,
-                                               jobject,
-                                               jmethodid,
-                                               "..."]).ptr},
-     {CallVoidMethodV: ctypes.voidptr_t},
-     {CallVoidMethodA: ctypes.voidptr_t},
-     {CallNonvirtualObjectMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                          jobject,
-                                                          [jenvptr, jobject,
-                                                           jclass, jmethodid,
-                                                           "..."]).ptr},
-     {CallNonvirtualObjectMethodV: ctypes.voidptr_t},
-     {CallNonvirtualObjectMethodA: ctypes.voidptr_t},
-     {CallNonvirtualBooleanMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                           jboolean,
-                                                           [jenvptr, jobject,
-                                                            jclass, jmethodid,
-                                                            "..."]).ptr},
-     {CallNonvirtualBooleanMethodV: ctypes.voidptr_t},
-     {CallNonvirtualBooleanMethodA: ctypes.voidptr_t},
-     {CallNonvirtualByteMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                        jbyte,
-                                                        [jenvptr, jobject,
-                                                         jclass, jmethodid,
-                                                         "..."]).ptr},
-     {CallNonvirtualByteMethodV: ctypes.voidptr_t},
-     {CallNonvirtualByteMethodA: ctypes.voidptr_t},
-     {CallNonvirtualCharMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                        jchar,
-                                                        [jenvptr, jobject,
-                                                         jclass, jmethodid,
-                                                         "..."]).ptr},
-     {CallNonvirtualCharMethodV: ctypes.voidptr_t},
-     {CallNonvirtualCharMethodA: ctypes.voidptr_t},
-     {CallNonvirtualShortMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                         jshort,
-                                                         [jenvptr, jobject,
-                                                          jclass, jmethodid,
-                                                          "..."]).ptr},
-     {CallNonvirtualShortMethodV: ctypes.voidptr_t},
-     {CallNonvirtualShortMethodA: ctypes.voidptr_t},
-     {CallNonvirtualIntMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                       jint,
-                                                       [jenvptr, jobject,
-                                                        jclass, jmethodid,
-                                                        "..."]).ptr},
-     {CallNonvirtualIntMethodV: ctypes.voidptr_t},
-     {CallNonvirtualIntMethodA: ctypes.voidptr_t},
-     {CallNonvirtualLongMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                        jlong,
-                                                        [jenvptr, jobject,
-                                                         jclass, jmethodid,
-                                                         "..."]).ptr},
-     {CallNonvirtualLongMethodV: ctypes.voidptr_t},
-     {CallNonvirtualLongMethodA: ctypes.voidptr_t},
-     {CallNonvirtualFloatMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                         jfloat,
-                                                         [jenvptr, jobject,
-                                                          jclass, jmethodid,
-                                                          "..."]).ptr},
-     {CallNonvirtualFloatMethodV: ctypes.voidptr_t},
-     {CallNonvirtualFloatMethodA: ctypes.voidptr_t},
-     {CallNonvirtualDoubleMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                          jdouble,
-                                                          [jenvptr, jobject,
-                                                           jclass, jmethodid,
-                                                           "..."]).ptr},
-     {CallNonvirtualDoubleMethodV: ctypes.voidptr_t},
-     {CallNonvirtualDoubleMethodA: ctypes.voidptr_t},
-     {CallNonvirtualVoidMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                        ctypes.void_t,
-                                                        [jenvptr, jobject,
-                                                         jclass, jmethodid,
-                                                         "..."]).ptr},
-     {CallNonvirtualVoidMethodV: ctypes.voidptr_t},
-     {CallNonvirtualVoidMethodA: ctypes.voidptr_t},
-     {GetFieldID: new ctypes.FunctionType(ctypes.default_abi,
-                                          jfieldid,
-                                          [jenvptr, jclass,
-                                           ctypes.char.ptr,
-                                           ctypes.char.ptr]).ptr},
-     {GetObjectField: new ctypes.FunctionType(ctypes.default_abi,
-                                              jobject,
-                                              [jenvptr, jobject,
-                                               jfieldid]).ptr},
-     {GetBooleanField: new ctypes.FunctionType(ctypes.default_abi,
-                                               jboolean,
-                                               [jenvptr, jobject,
-                                                jfieldid]).ptr},
-     {GetByteField: new ctypes.FunctionType(ctypes.default_abi,
-                                            jbyte,
-                                            [jenvptr, jobject,
-                                             jfieldid]).ptr},
-     {GetCharField: new ctypes.FunctionType(ctypes.default_abi,
-                                            jchar,
-                                            [jenvptr, jobject,
-                                             jfieldid]).ptr},
-     {GetShortField: new ctypes.FunctionType(ctypes.default_abi,
-                                             jshort,
-                                             [jenvptr, jobject,
-                                              jfieldid]).ptr},
-     {GetIntField: new ctypes.FunctionType(ctypes.default_abi,
-                                           jint,
-                                           [jenvptr, jobject,
-                                            jfieldid]).ptr},
-     {GetLongField: new ctypes.FunctionType(ctypes.default_abi,
-                                            jlong,
-                                            [jenvptr, jobject,
-                                             jfieldid]).ptr},
-     {GetFloatField: new ctypes.FunctionType(ctypes.default_abi,
-                                             jfloat,
-                                             [jenvptr, jobject,
-                                              jfieldid]).ptr},
-     {GetDoubleField: new ctypes.FunctionType(ctypes.default_abi,
-                                              jdouble,
-                                              [jenvptr, jobject,
-                                               jfieldid]).ptr},
-     {SetObjectField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jobject]).ptr},
-     {SetBooleanField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jboolean]).ptr},
-     {SetByteField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jbyte]).ptr},
-     {SetCharField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jchar]).ptr},
-     {SetShortField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jshort]).ptr},
-     {SetIntField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jint]).ptr},
-     {SetLongField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jlong]).ptr},
-     {SetFloatField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jfloat]).ptr},
-     {SetDoubleField: new ctypes.FunctionType(ctypes.default_abi,
-                                              ctypes.void_t,
-                                              [jenvptr, jobject,
-                                               jfieldid, jdouble]).ptr},
-     {GetStaticMethodID: new ctypes.FunctionType(ctypes.default_abi,
-                                           jmethodid,
-                                           [jenvptr,
-                                            jclass,
-                                            ctypes.char.ptr,
-                                            ctypes.char.ptr]).ptr},
-     {CallStaticObjectMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                      jobject,
-                                                      [jenvptr, jclass,
-                                                       jmethodid,
-                                                       "..."]).ptr},
-     {CallStaticObjectMethodV: ctypes.voidptr_t},
-     {CallStaticObjectMethodA: ctypes.voidptr_t},
-     {CallStaticBooleanMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                       jboolean,
-                                                       [jenvptr, jclass,
-                                                        jmethodid,
-                                                        "..."]).ptr},
-     {CallStaticBooleanMethodV: ctypes.voidptr_t},
-     {CallStaticBooleanMethodA: ctypes.voidptr_t},
-     {CallStaticByteMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                    jbyte,
-                                                    [jenvptr, jclass,
-                                                     jmethodid,
-                                                     "..."]).ptr},
-     {CallStaticByteMethodV: ctypes.voidptr_t},
-     {CallStaticByteMethodA: ctypes.voidptr_t},
-     {CallStaticCharMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                    jchar,
-                                                    [jenvptr, jclass,
-                                                     jmethodid,
-                                                     "..."]).ptr},
-     {CallStaticCharMethodV: ctypes.voidptr_t},
-     {CallStaticCharMethodA: ctypes.voidptr_t},
-     {CallStaticShortMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                     jshort,
-                                                     [jenvptr, jclass,
-                                                      jmethodid,
-                                                      "..."]).ptr},
-     {CallStaticShortMethodV: ctypes.voidptr_t},
-     {CallStaticShortMethodA: ctypes.voidptr_t},
-     {CallStaticIntMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                   jint,
-                                                   [jenvptr, jclass,
-                                                    jmethodid,
-                                                    "..."]).ptr},
-     {CallStaticIntMethodV: ctypes.voidptr_t},
-     {CallStaticIntMethodA: ctypes.voidptr_t},
-     {CallStaticLongMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                    jlong,
-                                                    [jenvptr, jclass,
-                                                     jmethodid,
-                                                     "..."]).ptr},
-     {CallStaticLongMethodV: ctypes.voidptr_t},
-     {CallStaticLongMethodA: ctypes.voidptr_t},
-     {CallStaticFloatMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                     jfloat,
-                                                     [jenvptr, jclass,
-                                                      jmethodid,
-                                                      "..."]).ptr},
-     {CallStaticFloatMethodV: ctypes.voidptr_t},
-     {CallStaticFloatMethodA: ctypes.voidptr_t},
-     {CallStaticDoubleMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                      jdouble,
-                                                      [jenvptr, jclass,
-                                                       jmethodid,
-                                                       "..."]).ptr},
-     {CallStaticDoubleMethodV: ctypes.voidptr_t},
-     {CallStaticDoubleMethodA: ctypes.voidptr_t},
-     {CallStaticVoidMethod: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jmethodid,
-                                                     "..."]).ptr},
-     {CallStaticVoidMethodV: ctypes.voidptr_t},
-     {CallStaticVoidMethodA: ctypes.voidptr_t},
-     {GetStaticFieldID: new ctypes.FunctionType(ctypes.default_abi,
-                                                jfieldid,
-                                                [jenvptr, jclass,
-                                                 ctypes.char.ptr,
-                                                 ctypes.char.ptr]).ptr},
-     {GetStaticObjectField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    jobject,
-                                                    [jenvptr, jclass,
-                                                     jfieldid]).ptr},
-     {GetStaticBooleanField: new ctypes.FunctionType(ctypes.default_abi,
-                                                     jboolean,
-                                                     [jenvptr, jclass,
-                                                      jfieldid]).ptr},
-     {GetStaticByteField: new ctypes.FunctionType(ctypes.default_abi,
-                                                  jbyte,
-                                                  [jenvptr, jclass,
-                                                   jfieldid]).ptr},
-     {GetStaticCharField: new ctypes.FunctionType(ctypes.default_abi,
-                                                  jchar,
-                                                  [jenvptr, jclass,
-                                                   jfieldid]).ptr},
-     {GetStaticShortField: new ctypes.FunctionType(ctypes.default_abi,
-                                                   jshort,
-                                                   [jenvptr, jclass,
-                                                    jfieldid]).ptr},
-     {GetStaticIntField: new ctypes.FunctionType(ctypes.default_abi,
-                                                 jint,
-                                                 [jenvptr, jclass,
-                                                  jfieldid]).ptr},
-     {GetStaticLongField: new ctypes.FunctionType(ctypes.default_abi,
-                                                  jlong,
-                                                  [jenvptr, jclass,
-                                                   jfieldid]).ptr},
-     {GetStaticFloatField: new ctypes.FunctionType(ctypes.default_abi,
-                                                   jfloat,
-                                                   [jenvptr, jclass,
-                                                    jfieldid]).ptr},
-     {GetStaticDoubleField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    jdouble,
-                                                    [jenvptr, jclass,
-                                                     jfieldid]).ptr},
-     {SetStaticObjectField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jobject]).ptr},
-     {SetStaticBooleanField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jboolean]).ptr},
-     {SetStaticByteField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jbyte]).ptr},
-     {SetStaticCharField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jchar]).ptr},
-     {SetStaticShortField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jshort]).ptr},
-     {SetStaticIntField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jint]).ptr},
-     {SetStaticLongField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jlong]).ptr},
-     {SetStaticFloatField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jfloat]).ptr},
-     {SetStaticDoubleField: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jclass,
-                                                     jfieldid, jdouble]).ptr},
-
-     {NewString: new ctypes.FunctionType(ctypes.default_abi,
-                                         jstring,
-                                         [jenvptr, jchar.ptr, jsize]).ptr},
-     {GetStringLength: new ctypes.FunctionType(ctypes.default_abi,
-                                               jsize,
-                                               [jenvptr, jstring]).ptr},
-     {GetStringChars: new ctypes.FunctionType(ctypes.default_abi,
-                                              jchar.ptr,
-                                              [jenvptr, jstring,
-                                               jboolean.ptr]).ptr},
-     {ReleaseStringChars: new ctypes.FunctionType(ctypes.default_abi,
-                                                  ctypes.void_t,
-                                                  [jenvptr, jstring,
-                                                   jchar.ptr]).ptr},
-
-     {NewStringUTF: new ctypes.FunctionType(ctypes.default_abi,
-                                            jstring,
-                                            [jenvptr,
-                                             ctypes.char.ptr]).ptr},
-     {GetStringUTFLength: new ctypes.FunctionType(ctypes.default_abi,
-                                                  jsize,
-                                                  [jenvptr, jstring]).ptr},
-     {GetStringUTFChars: new ctypes.FunctionType(ctypes.default_abi,
-                                                 ctypes.char.ptr,
-                                                 [jenvptr, jstring,
-                                                  jboolean.ptr]).ptr},
-     {ReleaseStringUTFChars: new ctypes.FunctionType(ctypes.default_abi,
-                                                     ctypes.void_t,
-                                                     [jenvptr, jstring,
-                                                      ctypes.char.ptr]).ptr},
-     {GetArrayLength: new ctypes.FunctionType(ctypes.default_abi,
-                                              jsize,
-                                              [jenvptr, jarray]).ptr},
-     {NewObjectArray: new ctypes.FunctionType(ctypes.default_abi,
-                                              jarray,
-                                              [jenvptr, jsize,
-                                               jclass, jobject]).ptr},
-     {GetObjectArrayElement: new ctypes.FunctionType(ctypes.default_abi,
-                                                     jobject,
-                                                     [jenvptr, jarray,
-                                                      jsize]).ptr},
-     {SetObjectArrayElement: new ctypes.FunctionType(ctypes.default_abi,
-                                                     ctypes.void_t,
-                                                     [jenvptr, jarray,
-                                                      jsize, jobject]).ptr},
-     {NewBooleanArray: new ctypes.FunctionType(ctypes.default_abi,
-                                               jarray,
-                                               [jenvptr, jsize]).ptr},
-     {NewByteArray: new ctypes.FunctionType(ctypes.default_abi,
-                                            jarray,
-                                            [jenvptr, jsize]).ptr},
-     {NewCharArray: new ctypes.FunctionType(ctypes.default_abi,
-                                            jarray,
-                                            [jenvptr, jsize]).ptr},
-     {NewShortArray: new ctypes.FunctionType(ctypes.default_abi,
-                                             jarray,
-                                             [jenvptr, jsize]).ptr},
-     {NewIntArray: new ctypes.FunctionType(ctypes.default_abi,
-                                           jarray,
-                                           [jenvptr, jsize]).ptr},
-     {NewLongArray: new ctypes.FunctionType(ctypes.default_abi,
-                                            jarray,
-                                            [jenvptr, jsize]).ptr},
-     {NewFloatArray: new ctypes.FunctionType(ctypes.default_abi,
-                                             jarray,
-                                             [jenvptr, jsize]).ptr},
-     {NewDoubleArray: new ctypes.FunctionType(ctypes.default_abi,
-                                              jarray,
-                                              [jenvptr, jsize]).ptr},
-     {GetBooleanArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                       jboolean.ptr,
-                                                       [jenvptr, jarray,
-                                                        jboolean.ptr]).ptr},
-     {GetByteArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                    jbyte.ptr,
-                                                    [jenvptr, jarray,
-                                                     jboolean.ptr]).ptr},
-     {GetCharArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                    jchar.ptr,
-                                                    [jenvptr, jarray,
-                                                     jboolean.ptr]).ptr},
-     {GetShortArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                     jshort.ptr,
-                                                     [jenvptr, jarray,
-                                                      jboolean.ptr]).ptr},
-     {GetIntArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                   jint.ptr,
-                                                   [jenvptr, jarray,
-                                                    jboolean.ptr]).ptr},
-     {GetLongArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                    jlong.ptr,
-                                                    [jenvptr, jarray,
-                                                     jboolean.ptr]).ptr},
-     {GetFloatArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                     jfloat.ptr,
-                                                     [jenvptr, jarray,
-                                                      jboolean.ptr]).ptr},
-     {GetDoubleArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                      jdouble.ptr,
-                                                      [jenvptr, jarray,
-                                                       jboolean.ptr]).ptr},
-     {ReleaseBooleanArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                           ctypes.void_t,
-                                                           [jenvptr, jarray,
-                                                            jboolean.ptr,
-                                                            jint]).ptr},
-     {ReleaseByteArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                        ctypes.void_t,
-                                                        [jenvptr, jarray,
-                                                         jbyte.ptr,
-                                                         jint]).ptr},
-     {ReleaseCharArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                        ctypes.void_t,
-                                                        [jenvptr, jarray,
-                                                         jchar.ptr,
-                                                         jint]).ptr},
-     {ReleaseShortArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                         ctypes.void_t,
-                                                         [jenvptr, jarray,
-                                                          jshort.ptr,
-                                                          jint]).ptr},
-     {ReleaseIntArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                       ctypes.void_t,
-                                                       [jenvptr, jarray,
-                                                        jint.ptr,
-                                                        jint]).ptr},
-     {ReleaseLongArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                        ctypes.void_t,
-                                                        [jenvptr, jarray,
-                                                         jlong.ptr,
-                                                         jint]).ptr},
-     {ReleaseFloatArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                         ctypes.void_t,
-                                                         [jenvptr, jarray,
-                                                          jfloat.ptr,
-                                                          jint]).ptr},
-     {ReleaseDoubleArrayElements: new ctypes.FunctionType(ctypes.default_abi,
-                                                          ctypes.void_t,
-                                                          [jenvptr, jarray,
-                                                           jdouble.ptr,
-                                                           jint]).ptr},
-     {GetBooleanArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                     ctypes.void_t,
-                                                     [jenvptr, jarray,
-                                                      jsize, jsize,
-                                                      jboolean.array()]).ptr},
-     {GetByteArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                     ctypes.void_t,
-                                                     [jenvptr, jarray,
-                                                      jsize, jsize,
-                                                      jbyte.array()]).ptr},
-     {GetCharArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                  ctypes.void_t,
-                                                  [jenvptr, jarray,
-                                                   jsize, jsize,
-                                                   jchar.array()]).ptr},
-     {GetShortArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                   ctypes.void_t,
-                                                   [jenvptr, jarray,
-                                                    jsize, jsize,
-                                                    jshort.array()]).ptr},
-     {GetIntArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                 ctypes.void_t,
-                                                 [jenvptr, jarray,
-                                                  jsize, jsize,
-                                                  jint.array()]).ptr},
-     {GetLongArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                  ctypes.void_t,
-                                                  [jenvptr, jarray,
-                                                   jsize, jsize,
-                                                   jlong.array()]).ptr},
-     {GetFloatArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                   ctypes.void_t,
-                                                   [jenvptr, jarray,
-                                                    jsize, jsize,
-                                                    jfloat.array()]).ptr},
-     {GetDoubleArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jarray,
-                                                     jsize, jsize,
-                                                     jdouble.array()]).ptr},
-     {SetBooleanArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                     ctypes.void_t,
-                                                     [jenvptr, jarray,
-                                                      jsize, jsize,
-                                                      jboolean.array()]).ptr},
-     {SetByteArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                  ctypes.void_t,
-                                                  [jenvptr, jarray,
-                                                   jsize, jsize,
-                                                   jbyte.array()]).ptr},
-     {SetCharArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                  ctypes.void_t,
-                                                  [jenvptr, jarray,
-                                                   jsize, jsize,
-                                                   jchar.array()]).ptr},
-     {SetShortArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                   ctypes.void_t,
-                                                   [jenvptr, jarray,
-                                                    jsize, jsize,
-                                                    jshort.array()]).ptr},
-     {SetIntArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                 ctypes.void_t,
-                                                 [jenvptr, jarray,
-                                                  jsize, jsize,
-                                                  jint.array()]).ptr},
-     {SetLongArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                  ctypes.void_t,
-                                                  [jenvptr, jarray,
-                                                   jsize, jsize,
-                                                   jlong.array()]).ptr},
-     {SetFloatArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                   ctypes.void_t,
-                                                   [jenvptr, jarray,
-                                                    jsize, jsize,
-                                                    jfloat.array()]).ptr},
-     {SetDoubleArrayRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                    ctypes.void_t,
-                                                    [jenvptr, jarray,
-                                                     jsize, jsize,
-                                                     jdouble.array()]).ptr},
-     {RegisterNatives: ctypes.voidptr_t},
-     {UnregisterNatives: ctypes.voidptr_t},
-     {MonitorEnter: new ctypes.FunctionType(ctypes.default_abi,
-                                            jint, [jenvptr, jobject]).ptr},
-     {MonitorExit: new ctypes.FunctionType(ctypes.default_abi,
-                                            jint, [jenvptr, jobject]).ptr},
-     {GetJavaVM: ctypes.voidptr_t},
-     {GetStringRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                               ctypes.void_t,
-                                               [jenvptr, jstring,
-                                                jsize, jsize,
-                                                jchar.array()]).ptr},
-     {GetStringUTFRegion: new ctypes.FunctionType(ctypes.default_abi,
-                                                  ctypes.void_t,
-                                                  [jenvptr, jstring,
-                                                   jsize, jsize,
-                                                   ctypes.char.array()]).ptr},
-     {GetPrimitiveArrayCritical: ctypes.voidptr_t},
-     {ReleasePrimitiveArrayCritical: ctypes.voidptr_t},
-     {GetStringCritical: ctypes.voidptr_t},
-     {ReleaseStringCritical: ctypes.voidptr_t},
-     {NewWeakGlobalRef: ctypes.voidptr_t},
-     {DeleteWeakGlobalRef: ctypes.voidptr_t},
-     {ExceptionCheck: new ctypes.FunctionType(ctypes.default_abi,
-                                              jboolean, [jenvptr]).ptr},
-     {NewDirectByteBuffer: ctypes.voidptr_t},
-     {GetDirectBufferAddress: ctypes.voidptr_t},
-     {GetDirectBufferCapacity: ctypes.voidptr_t},
-     {GetObjectRefType: ctypes.voidptr_t}]
-);
-
-var GetJNIForThread = libxul.declare("GetJNIForThread",
-                                     ctypes.default_abi,
-                                     JNINativeInterface.ptr.ptr);
-
-var registry = Object.create(null);
-var classes = Object.create(null);
-
-function JNIUnloadClasses(jenv) {
-  Object.getOwnPropertyNames(registry).forEach(function(classname) {
-    var jcls = unwrap(registry[classname]);
-    jenv.contents.contents.DeleteGlobalRef(jenv, jcls);
-
-    // Purge the registry, so we don't try to reuse stale global references
-    // in JNI calls and we garbage-collect the JS global reference objects.
-    delete registry[classname];
-  });
-
-  // The refs also get added to the 'classes' object, so we should purge it too.
-  // That object is a hierarchical data structure organized by class path parts,
-  // but deleting its own properties should be sufficient to break its refs.
-  Object.getOwnPropertyNames(classes).forEach(function(topLevelPart) {
-    delete classes[topLevelPart];
-  });
-}
-
-var PREFIX = "js#";
-// this regex matches one component of a type signature:
-// any number of array modifiers, followed by either a
-// primitive type character or L<classname>;
-var sigRegex = () => /\[*([VZBCSIJFD]|L([^.\/;]+(\/[^.\/;]+)*);)/g;
-var ensureSig = function(classname_or_signature) {
-    // convert a classname into a signature,
-    // leaving unchanged signatures.  We assume that
-    // anything not a valid signature is a classname.
-  var m = sigRegex().exec(classname_or_signature);
-  return (m && m[0] === classname_or_signature) ? classname_or_signature :
-    "L" + classname_or_signature.replace(/\./g, "/") + ";";
-};
-var wrap = function(obj, classSig) {
-  if (!classSig) { return obj; }
-  // don't wrap primitive types.
-  if (classSig.charAt(0) !== "L" &&
-      classSig.charAt(0) !== "[") { return obj; }
-  var proto = registry[classSig][PREFIX + "proto"];
-  return new proto(obj);
-};
-var unwrap = function(obj, opt_jenv, opt_ctype) {
-  if (obj && typeof(obj) === "object" && (PREFIX + "obj") in obj) {
-    return obj[PREFIX + "obj"];
-  } else if (opt_jenv && opt_ctype) {
-    if (opt_ctype !== jobject)
-      return opt_ctype(obj); // cast to given primitive ctype
-    if (typeof(obj) === "string")
-      return unwrap(JNINewString(opt_jenv, obj)); // create Java String
-  }
-  return obj;
-};
-var ensureLoaded = function(jenv, classSig) {
-  if (!Object.hasOwnProperty.call(registry, classSig)) {
-    JNILoadClass(jenv, classSig);
-  }
-  return registry[classSig];
-};
-
-function JNINewString(jenv, value) {
-  var s = jenv.contents.contents.NewStringUTF(jenv, ctypes.char.array()(value));
-  ensureLoaded(jenv, "Ljava/lang/String;");
-  return wrap(s, "Ljava/lang/String;");
-}
-
-function JNIReadString(jenv, jstring_value) {
-  var val = unwrap(jstring_value);
-  if ((!val) || val.isNull()) { return null; }
-  var chars = jenv.contents.contents.GetStringUTFChars(jenv, val, null);
-  var result = chars.readString();
-  jenv.contents.contents.ReleaseStringUTFChars(jenv, val, chars);
-  return result;
-}
-
-var sigInfo = {
-  "V": { name: "Void", longName: "Void", ctype: ctypes.void_t },
-  "Z": { name: "Boolean", longName: "Boolean", ctype: jboolean },
-  "B": { name: "Byte", longName: "Byte", ctype: jbyte },
-  "C": { name: "Char", longName: "Char", ctype: jchar },
-  "S": { name: "Short", longName: "Short", ctype: jshort },
-  "I": { name: "Int", longName: "Integer", ctype: jint },
-  "J": { name: "Long", longName: "Long", ctype: jlong },
-  "F": { name: "Float", longName: "Float", ctype: jfloat },
-  "D": { name: "Double", longName: "Double", ctype: jdouble },
-  "L": { name: "Object", longName: "Object", ctype: jobject },
-  "[": { name: "Object", longName: "Object", ctype: jarray }
-};
-
-var sig2type = function(sig) { return sigInfo[sig.charAt(0)].name; };
-var sig2ctype = function(sig) { return sigInfo[sig.charAt(0)].ctype; };
-var sig2prim = function(sig) { return sigInfo[sig.charAt(0)].longName; };
-
-// return the class object for a signature string.
-// allocates 1 or 2 local refs
-function JNIClassObj(jenv, classSig) {
-    var jenvpp = function() { return jenv.contents.contents; };
-    // Deal with funny calling convention of JNI FindClass method.
-    // Classes get the leading & trailing chars stripped; primitives
-    // have to be looked up via their wrapper type.
-    var prim = function(ty) {
-        var jcls = jenvpp().FindClass(jenv, "java/lang/" + ty);
-        var jfld = jenvpp().GetStaticFieldID(jenv, jcls, "TYPE",
-                                             "Ljava/lang/Class;");
-        return jenvpp().GetStaticObjectField(jenv, jcls, jfld);
-    };
-    switch (classSig.charAt(0)) {
-    case "[":
-        return jenvpp().FindClass(jenv, classSig);
-    case "L":
-        classSig = classSig.substring(1, classSig.indexOf(";"));
-        return jenvpp().FindClass(jenv, classSig);
-    default:
-      return prim(sig2prim(classSig));
-    }
-}
-
-// return the signature string for a Class object.
-// allocates 2 local refs
-function JNIClassSig(jenv, jcls) {
-  var jenvpp = function() { return jenv.contents.contents; };
-  var jclscls = jenvpp().FindClass(jenv, "java/lang/Class");
-  var jmtd = jenvpp().GetMethodID(jenv, jclscls,
-                                  "getName", "()Ljava/lang/String;");
-  var name = jenvpp().CallObjectMethod(jenv, jcls, jmtd);
-  name = JNIReadString(jenv, name);
-  // API is weird.  Make sure we're using slashes not dots
-  name = name.replace(/\./g, "/");
-  // special case primitives, arrays
-  if (name.charAt(0) === "[") return name;
-  switch (name) {
-  case "void": return "V";
-  case "boolean": return "Z";
-  case "byte": return "B";
-  case "char": return "C";
-  case "short": return "S";
-  case "int": return "I";
-  case "long": return "J";
-  case "float": return "F";
-  case "double": return "D";
-  default:
-    return "L" + name + ";";
-  }
-}
-
-// create dispatch method
-// we resolve overloaded methods only by # of arguments.  If you need
-// further resolution, use the 'long form' of the method name, ie:
-//    obj['toString()Ljava/lang/String'].call(obj);
-var overloadFunc = function(basename) {
-  return function() {
-    return this[basename + "(" + arguments.length + ")"].apply(this, arguments);
-  };
-};
-
-// Create appropriate wrapper fields/methods for a Java class.
-function JNILoadClass(jenv, classSig, opt_props) {
-  var jenvpp = function() { return jenv.contents.contents; };
-  var props = opt_props || {};
-
-  // allocate a local reference frame with enough space
-  // this class (1 or 2 local refs) plus superclass (3 refs)
-  // plus array element class (1 or 2 local refs)
-  var numLocals = 7;
-  jenvpp().PushLocalFrame(jenv, numLocals);
-
-  var jcls;
-  if (Object.hasOwnProperty.call(registry, classSig)) {
-    jcls = unwrap(registry[classSig]);
-  } else {
-    jcls = jenvpp().NewGlobalRef(jenv, JNIClassObj(jenv, classSig));
-
-    // get name of superclass
-    var jsuper = jenvpp().GetSuperclass(jenv, jcls);
-    if (jsuper.isNull()) {
-      jsuper = null;
-    } else {
-      jsuper = JNIClassSig(jenv, jsuper);
-    }
-
-    registry[classSig] = Object.create(jsuper ? ensureLoaded(jenv, jsuper) : null);
-    registry[classSig][PREFIX + "obj"] = jcls; // global ref, persistent.
-    registry[classSig][PREFIX + "proto"] =
-      function(o) { this[PREFIX + "obj"] = o; };
-    registry[classSig][PREFIX + "proto"].prototype =
-      Object.create(jsuper ?
-                    ensureLoaded(jenv, jsuper)[PREFIX + "proto"].prototype :
-                    null);
-    // Add a __cast__ method to the wrapper corresponding to the class
-    registry[classSig].__cast__ = function(obj) {
-      return wrap(unwrap(obj), classSig);
-    };
-
-    // make wrapper accessible via the classes object.
-    var path = sig2type(classSig).toLowerCase();
-    if (classSig.charAt(0) === "L") {
-      path = classSig.substring(1, classSig.length - 1);
-    }
-    if (classSig.charAt(0) !== "[") {
-      var root = classes, i;
-      var parts = path.split("/");
-      for (i = 0; i < parts.length - 1; i++) {
-        if (!Object.hasOwnProperty.call(root, parts[i])) {
-          root[parts[i]] = Object.create(null);
-        }
-        root = root[parts[i]];
-      }
-      root[parts[parts.length - 1]] = registry[classSig];
-    }
-  }
-
-  var r = registry[classSig];
-  var rpp = r[PREFIX + "proto"].prototype;
-
-  if (classSig.charAt(0) === "[") {
-    // add 'length' field for arrays
-    Object.defineProperty(rpp, "length", {
-      get: function() {
-        return jenvpp().GetArrayLength(jenv, unwrap(this));
-      }
-    });
-    // add 'get' and 'set' methods, 'new' constructor
-    var elemSig = classSig.substring(1);
-    ensureLoaded(jenv, elemSig);
-
-    registry[elemSig].__array__ = r;
-    if (!Object.hasOwnProperty.call(registry[elemSig], "array"))
-      registry[elemSig].array = r;
-
-    if (elemSig.charAt(0) === "L" || elemSig.charAt(0) === "[") {
-      var elemClass = unwrap(registry[elemSig]);
-
-      rpp.get = function(idx) {
-        return wrap(jenvpp().GetObjectArrayElement(jenv, unwrap(this), idx),
-                    elemSig);
-      };
-      rpp.set = function(idx, value) {
-        jenvpp().SetObjectArrayElement(jenv, unwrap(this), idx,
-                                       unwrap(value, jenv, jobject));
-      };
-      rpp.getElements = function(start, len) {
-        var i, r = [];
-        for (i = 0; i < len; i++) { r.push(this.get(start + i)); }
-        return r;
-      };
-      rpp.setElements = function(start, vals) {
-        vals.forEach((v, i) => { this.set(start + i, v); });
-      };
-      r.new = function(length) {
-        return wrap(jenvpp().NewObjectArray(jenv, length, elemClass, null),
-                    classSig);
-      };
-    } else {
-      var ty = sig2type(elemSig), ctype = sig2ctype(elemSig);
-      var constructor = "New" + ty + "Array";
-      var getter = "Get" + ty + "ArrayRegion";
-      var setter = "Set" + ty + "ArrayRegion";
-      rpp.get = function(idx) { return this.getElements(idx, 1)[0]; };
-      rpp.set = function(idx, val) { this.setElements(idx, [val]); };
-      rpp.getElements = function(start, len) {
-        var j = jenvpp();
-        var buf = new (ctype.array())(len);
-        j[getter].call(j, jenv, unwrap(this), start, len, buf);
-        return buf;
-      };
-      rpp.setElements = function(start, vals) {
-        var j = jenvpp();
-        j[setter].call(j, jenv, unwrap(this), start, vals.length,
-                       ctype.array()(vals));
-      };
-      r.new = function(length) {
-        var j = jenvpp();
-        return wrap(j[constructor].call(j, jenv, length), classSig);
-      };
-    }
-  }
-
-  (props.static_fields || []).forEach(function(fld) {
-    var jfld = jenvpp().GetStaticFieldID(jenv, jcls, fld.name, fld.sig);
-    var ty = sig2type(fld.sig), nm = fld.sig;
-    var getter = "GetStatic" + ty + "Field", setter = "SetStatic" + ty + "Field";
-    ensureLoaded(jenv, nm);
-    var props =  {
-      get: function() {
-        var j = jenvpp();
-        return wrap(j[getter].call(j, jenv, jcls, jfld), nm);
-      },
-      set: function(newValue) {
-        var j = jenvpp();
-        j[setter].call(j, jenv, jcls, jfld, unwrap(newValue));
-      }
-    };
-    Object.defineProperty(r, fld.name, props);
-    // add static fields to object instances, too.
-    Object.defineProperty(rpp, fld.name, props);
-  });
-  (props.static_methods || []).forEach(function(mtd) {
-    var jmtd = jenvpp().GetStaticMethodID(jenv, jcls, mtd.name, mtd.sig);
-    var argctypes = mtd.sig.match(sigRegex()).map(s => sig2ctype(s));
-    var returnSig = mtd.sig.substring(mtd.sig.indexOf(")") + 1);
-    var ty = sig2type(returnSig), nm = returnSig;
-    var call = "CallStatic" + ty + "Method";
-    ensureLoaded(jenv, nm);
-    r[mtd.name] = rpp[mtd.name] = overloadFunc(mtd.name);
-    r[mtd.name + mtd.sig] = r[mtd.name + "(" + (argctypes.length - 1) + ")"] =
-    // add static methods to object instances, too.
-    rpp[mtd.name + mtd.sig] = rpp[mtd.name + "(" + (argctypes.length - 1) + ")"] = function() {
-      var i, j = jenvpp();
-      var args = [jenv, jcls, jmtd];
-      for (i = 0; i < arguments.length; i++) {
-        args.push(unwrap(arguments[i], jenv, argctypes[i]));
-      }
-      return wrap(j[call].apply(j, args), nm);
-    };
-  });
-  (props.constructors || []).forEach(function(mtd) {
-    mtd.name = "<init>";
-    var jmtd = jenvpp().GetMethodID(jenv, jcls, mtd.name, mtd.sig);
-    var argctypes = mtd.sig.match(sigRegex()).map(s => sig2ctype(s));
-    var returnSig = mtd.sig.substring(mtd.sig.indexOf(")") + 1);
-
-    r.new = overloadFunc("new");
-    r["new" + mtd.sig] = r["new(" + (argctypes.length - 1) + ")"] = function() {
-      var i, j = jenvpp();
-      var args = [jenv, jcls, jmtd];
-      for (i = 0; i < arguments.length; i++) {
-        args.push(unwrap(arguments[i], jenv, argctypes[i]));
-      }
-      return wrap(j.NewObject.apply(j, args), classSig);
-    };
-  });
-  (props.fields || []).forEach(function(fld) {
-    var jfld = jenvpp().GetFieldID(jenv, jcls, fld.name, fld.sig);
-    var ty = sig2type(fld.sig), nm = fld.sig;
-    var getter = "Get" + ty + "Field", setter = "Set" + ty + "Field";
-    ensureLoaded(jenv, nm);
-    Object.defineProperty(rpp, fld.name, {
-      get: function() {
-        var j = jenvpp();
-        return wrap(j[getter].call(j, jenv, unwrap(this), jfld), nm);
-      },
-      set: function(newValue) {
-        var j = jenvpp();
-        j[setter].call(j, jenv, unwrap(this), jfld, unwrap(newValue));
-      }
-    });
-  });
-  (props.methods || []).forEach(function(mtd) {
-    var jmtd = jenvpp().GetMethodID(jenv, jcls, mtd.name, mtd.sig);
-    var argctypes = mtd.sig.match(sigRegex()).map(s => sig2ctype(s));
-    var returnSig = mtd.sig.substring(mtd.sig.indexOf(")") + 1);
-    var ty = sig2type(returnSig), nm = returnSig;
-    var call = "Call" + ty + "Method";
-    ensureLoaded(jenv, nm);
-    rpp[mtd.name] = overloadFunc(mtd.name);
-    rpp[mtd.name + mtd.sig] = rpp[mtd.name + "(" + (argctypes.length - 1) + ")"] = function() {
-      var i, j = jenvpp();
-      var args = [jenv, unwrap(this), jmtd];
-      for (i = 0; i < arguments.length; i++) {
-        args.push(unwrap(arguments[i], jenv, argctypes[i]));
-      }
-      return wrap(j[call].apply(j, args), nm);
-    };
-  });
-  jenvpp().PopLocalFrame(jenv, null);
-  return r;
-}
-
-// exported object
-var JNI = {
-  // primitive types
-  jboolean: jboolean,
-  jbyte: jbyte,
-  jchar: jchar,
-  jshort: jshort,
-  jint: jint,
-  jlong: jlong,
-  jfloat: jfloat,
-  jdouble: jdouble,
-  jsize: jsize,
-
-  // class registry
-  classes: classes,
-
-  // methods
-  GetForThread: GetJNIForThread,
-  NewString: JNINewString,
-  ReadString: JNIReadString,
-  LoadClass: function(jenv, classname_or_signature, props) {
-    return JNILoadClass(jenv, ensureSig(classname_or_signature), props);
-  },
-  UnloadClasses: JNIUnloadClasses
-};
--- a/mobile/android/modules/moz.build
+++ b/mobile/android/modules/moz.build
@@ -27,17 +27,16 @@ EXTRA_JS_MODULES += [
     'DelayedInit.jsm',
     'DownloadNotifications.jsm',
     'FormAssistant.jsm',
     'FxAccountsWebChannel.jsm',
     'HelperApps.jsm',
     'Home.jsm',
     'HomeProvider.jsm',
     'InputWidgetHelper.jsm',
-    'JNI.jsm',
     'LightweightThemeConsumer.jsm',
     'MediaPlayerApp.jsm',
     'NetErrorHelper.jsm',
     'Notifications.jsm',
     'PageActions.jsm',
     'Prompt.jsm',
     'RuntimePermissions.jsm',
     'Sanitizer.jsm',
--- a/mobile/android/tests/browser/chrome/chrome.ini
+++ b/mobile/android/tests/browser/chrome/chrome.ini
@@ -29,17 +29,16 @@ support-files =
 skip-if = debug
 [test_debugger_server.html]
 [test_desktop_useragent.html]
 [test_device_search_engine.html]
 [test_get_last_visited.html]
 [test_home_provider.html]
 [test_hidden_select_option.html]
 [test_identity_mode.html]
-[test_jni.html]
 [test_media_playback.html]
 [test_migrate_ui.html]
 [test_network_manager.html]
 [test_offline_page.html]
 skip-if = true # Bug 1241478
 [test_reader_view.html]
 [test_resource_substitutions.html]
 [test_restricted_profiles.html]
deleted file mode 100644
--- a/mobile/android/tests/browser/chrome/test_jni.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=873569
-Migrated from Robocop: https://bugzilla.mozilla.org/show_bug.cgi?id=1184186
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 873569</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-  <script type="application/javascript">
-
-  Components.utils.import("resource://gre/modules/ctypes.jsm");
-  Components.utils.import("resource://gre/modules/JNI.jsm");
-
-  function test_JNI() {
-    var jenv = null;
-    try {
-      jenv = JNI.GetForThread();
-
-      // Test a simple static method.
-      var geckoAppShell = JNI.LoadClass(jenv, "org.mozilla.gecko.GeckoAppShell", {
-        static_methods: [
-          { name: "getPreferredIconSize", sig: "()I" },
-          { name: "getApplicationContext", sig: "()Landroid/content/Context;" },
-        ],
-      });
-
-      let iconSize = -1;
-      iconSize = geckoAppShell.getPreferredIconSize();
-      isnot(iconSize, -1, "icon size is valid");
-
-      // Test GeckoNetworkManager methods that are accessed by PaymentsUI.js.
-      // The return values can vary, so we can't test for equivalence, but we
-      // can ensure that the method calls return values of the correct type.
-      let jGeckoNetworkManager = JNI.LoadClass(jenv, "org/mozilla/gecko/GeckoNetworkManager", {
-        static_methods: [
-          { name: "getMNC", sig: "()I" },
-          { name: "getMCC", sig: "()I" },
-        ],
-      });
-      is(typeof jGeckoNetworkManager.getMNC(), "number", "typeof getMNC is number");
-      is(typeof jGeckoNetworkManager.getMCC(), "number", "typeof getMCC is number");
-
-      // Test retrieving the context's class's name, which tests dynamic method
-      // invocation as well as converting a Java string to JavaScript.
-      JNI.LoadClass(jenv, "android.content.Context", {
-        methods: [
-          { name: "getClass", sig: "()Ljava/lang/Class;" },
-        ],
-      });
-      JNI.LoadClass(jenv, "java.lang.Class", {
-        methods: [
-          { name: "getName", sig: "()Ljava/lang/String;" },
-        ],
-      });
-      is("org.mozilla.gecko.GeckoApplication", JNI.ReadString(jenv, geckoAppShell.getApplicationContext().getClass().getName()), "class name is correct");
-    } finally {
-      if (jenv) {
-        JNI.UnloadClasses(jenv);
-      }
-    }
-  }
-
-  test_JNI();
-
-  </script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=873569">Mozilla Bug 873569</a>
-<br>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1184186">Migrated from Robocop testJNI</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-</pre>
-</body>
-</html>
--- a/mobile/android/tests/browser/chrome/test_restricted_profiles.html
+++ b/mobile/android/tests/browser/chrome/test_restricted_profiles.html
@@ -9,20 +9,16 @@ Migrated from Robocop: https://bugzilla.
   <title>Test for Bug 1042715</title>
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
   const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
-  Cu.import("resource://gre/modules/ctypes.jsm");
-  Cu.import("resource://gre/modules/JNI.jsm");
-  Cu.import("resource://gre/modules/Task.jsm");
-
   function test_isUserRestricted() {
     // Make sure the parental controls service is available
     ok("@mozilla.org/parental-controls-service;1" in Cc);
 
     let pc = Cc["@mozilla.org/parental-controls-service;1"].createInstance(Ci.nsIParentalControlsService);
 
     // In an admin profile, like the tests: enabled = false
     // In a restricted profile: enabled = true
--- a/tools/lint/eslint/modules.json
+++ b/tools/lint/eslint/modules.json
@@ -102,17 +102,16 @@
   "HelperApps.jsm": ["App", "HelperApps"],
   "history.js": ["HistoryEngine", "HistoryRec"],
   "history.jsm": ["HistoryEntry", "DumpHistory"],
   "Http.jsm": ["httpRequest", "percentEncode"],
   "httpd.js": ["HTTP_400", "HTTP_401", "HTTP_402", "HTTP_403", "HTTP_404", "HTTP_405", "HTTP_406", "HTTP_407", "HTTP_408", "HTTP_409", "HTTP_410", "HTTP_411", "HTTP_412", "HTTP_413", "HTTP_414", "HTTP_415", "HTTP_417", "HTTP_500", "HTTP_501", "HTTP_502", "HTTP_503", "HTTP_504", "HTTP_505", "HttpError", "HttpServer"],
   "import_module.jsm": ["MODULE_IMPORTED", "MODULE_URI", "SUBMODULE_IMPORTED", "same_scope", "SUBMODULE_IMPORTED_TO_SCOPE"],
   "import_sub_module.jsm": ["SUBMODULE_IMPORTED", "test_obj"],
   "InlineSpellChecker.jsm": ["InlineSpellChecker", "SpellCheckHelper"],
-  "JNI.jsm": ["JNI", "android_log"],
   "JSDOMParser.js": ["JSDOMParser"],
   "jsdebugger.jsm": ["addDebuggerToGlobal"],
   "json2.js": ["JSON"],
   "keys.js": ["BulkKeyBundle", "SyncKeyBundle"],
   "KeyValueParser.jsm": ["parseKeyValuePairsFromLines", "parseKeyValuePairs", "parseKeyValuePairsFromFile", "parseKeyValuePairsFromFileAsync"],
   "kinto-http-client.js": ["KintoHttpClient"],
   "kinto-offline-client.js": ["Kinto"],
   "kinto-storage-adapter.js": ["FirefoxAdapter"],