Back out bug 718760, bug 725052, bug 732069 because of broken Android build
authorMatt Brubeck <mbrubeck@mozilla.com>
Mon, 12 Mar 2012 10:37:22 -0700
changeset 90349 a536d22f312c3dc17c0aa6d2e2d9fe2cd5d31f6f
parent 90348 e2d129062b2b13e7cd6ef44806c7b7b53ed7ef86
child 90350 5b2ba557ec83475f5a30e616809b273bd33d5a35
push idunknown
push userunknown
push dateunknown
bugs718760, 725052, 732069
milestone13.0a1
Back out bug 718760, bug 725052, bug 732069 because of broken Android build
embedding/android/GeckoAppShell.java
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/GeckoMessageReceiver.java
mobile/android/base/GeckoThread.java
mobile/android/base/Makefile.in
mobile/android/base/NSSBridge.java
mobile/android/base/db/BrowserContract.java.in
mobile/android/base/db/DBUtils.java
mobile/android/base/db/FormHistoryProvider.java.in
mobile/android/base/db/GeckoProvider.java.in
mobile/android/base/db/PasswordsProvider.java.in
mobile/android/base/sqlite/MatrixBlobCursor.java
mobile/android/base/tests/BaseTest.java.in
mobile/android/base/tests/robocop.ini
mobile/android/base/tests/testPasswordEncrypt.java.in
mobile/android/base/tests/testPasswordProvider.java.in
mobile/android/base/tests/testPasswordUndeletion.java.in
mozglue/android/APKOpen.cpp
mozglue/android/APKOpen.h
mozglue/android/Makefile.in
mozglue/android/NSSBridge.cpp
mozglue/android/NSSBridge.h
mozglue/android/SQLiteBridge.cpp
other-licenses/android/dlfcn.c
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -109,18 +109,17 @@ public class GeckoAppShell
     // helper methods
     public static native void setSurfaceView(GeckoSurfaceView sv);
     public static native void putenv(String map);
     public static native void onResume();
     public static native void onLowMemory();
     public static native void callObserver(String observerKey, String topic, String data);
     public static native void removeObserver(String observerKey);
     public static native void loadGeckoLibsNative(String apkName);
-    public static native void loadSQLiteLibsNative(String apkName);
-    public static native void loadNSSLibsNative(String apkName);
+    public static native void loadSQLiteLibsNative(String apkName, boolean shouldExtract);
     public static native void onChangeNetworkLinkStatus(String status);
     public static native void reportJavaCrash(String stack);
 
     public static native void processNextNativeEvent();
 
     public static native void notifyBatteryChange(double aLevel, boolean aCharging, double aRemainingTime);
 
     public static native void notifySmsReceived(String aSender, String aBody, long aTimestamp);
@@ -393,18 +392,17 @@ public class GeckoAppShell
                 Iterator cacheFiles = Arrays.asList(files).iterator();
                 while (cacheFiles.hasNext()) {
                     File libFile = (File)cacheFiles.next();
                     if (libFile.getName().endsWith(".so"))
                         libFile.delete();
                 }
             }
         }
-        loadSQLiteLibsNative(apkName);
-        loadNSSLibsNative(apkName);
+        loadSQLiteLibsNative(apkName, extractLibs);
         loadGeckoLibsNative(apkName);
     }
 
     private static void putLocaleEnv() {
         GeckoAppShell.putenv("LANG=" + Locale.getDefault().toString());
         NumberFormat nf = NumberFormat.getInstance();
         if (nf instanceof DecimalFormat) {
             DecimalFormat df = (DecimalFormat)nf;
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -18,17 +18,16 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>
     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
 
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     <uses-permission android:name="android.permission.VIBRATE"/>
-    <uses-permission android:name="@ANDROID_PACKAGE_NAME@.permissions.PASSWORD_PROVIDER"/>
 
 #ifdef MOZ_WEBSMS_BACKEND
     <!-- WebSMS -->
     <uses-permission android:name="android.permission.SEND_SMS"/>
     <uses-permission android:name="android.permission.RECEIVE_SMS"/>
     <uses-permission android:name="android.permission.WRITE_SMS"/>
     <uses-permission android:name="android.permission.READ_SMS"/>
 #endif
@@ -112,23 +111,16 @@
 
         <receiver android:name="NotificationHandler">
             <intent-filter>
                 <action android:name="org.mozilla.gecko.ACTION_ALERT_CLICK" />
                 <action android:name="org.mozilla.gecko.ACTION_ALERT_CLEAR" />
             </intent-filter>
         </receiver>
 
-        <receiver android:name="org.mozilla.gecko.GeckoMessageReceiver"
-                  android:permission="@ANDROID_PACKAGE_NAME@.permissions.PASSWORD_PROVIDER">
-            <intent-filter>
-                  <action android:name="org.mozilla.gecko.INIT_PW"></action>
-            </intent-filter>
-        </receiver>
-
         <activity android:name="Restarter"
                   android:process="@ANDROID_PACKAGE_NAME@Restarter"
                   android:theme="@style/Gecko"
                   android:excludeFromRecents="true">
           <intent-filter>
             <action android:name="org.mozilla.gecko.restart"/>
             <action android:name="org.mozilla.gecko.restart_update"/>
           </intent-filter>
@@ -178,33 +170,30 @@
                   android:excludeFromRecents="true"/>
 
         <provider android:name="@ANDROID_PACKAGE_NAME@.db.BrowserProvider"
                   android:authorities="@ANDROID_PACKAGE_NAME@.db.browser"
                   android:permission="@ANDROID_PACKAGE_NAME@.permissions.BROWSER_PROVIDER"/>
 
         <provider android:name="@ANDROID_PACKAGE_NAME@.db.PasswordsProvider"
                   android:authorities="@ANDROID_PACKAGE_NAME@.db.passwords"
-                  android:permission="@ANDROID_PACKAGE_NAME@.permissions.PASSWORD_PROVIDER"
-                  android:process="org.mozilla.gecko.PasswordsProvider"/>
+                  android:permission="@ANDROID_PACKAGE_NAME@.permissions.BROWSER_PROVIDER"
+                  android:protectionLevel="signature"/>
 
         <provider android:name="@ANDROID_PACKAGE_NAME@.db.FormHistoryProvider"
                   android:authorities="@ANDROID_PACKAGE_NAME@.db.formhistory"
                   android:permission="@ANDROID_PACKAGE_NAME@.permissions.FORMHISTORY_PROVIDER"
                   android:protectionLevel="signature"/>
 
         <provider android:name="@ANDROID_PACKAGE_NAME@.db.TabsProvider"
                   android:authorities="@ANDROID_PACKAGE_NAME@.db.tabs"
                   android:permission="@ANDROID_PACKAGE_NAME@.permissions.BROWSER_PROVIDER"/>
 
 #include ../sync/manifests/SyncAndroidManifest_services.xml.in
     </application>
 
     <permission android:name="@ANDROID_PACKAGE_NAME@.permissions.BROWSER_PROVIDER"
                 android:protectionLevel="signature"/>
 
-    <permission android:name="@ANDROID_PACKAGE_NAME@.permissions.PASSWORD_PROVIDER"
-                android:protectionLevel="signature"/>
-
     <permission android:name="@ANDROID_PACKAGE_NAME@.permissions.FORMHISTORY_PROVIDER"
                 android:protectionLevel="signature"/>
 
 </manifest> 
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -104,17 +104,16 @@ abstract public class GeckoApp
 
     public static final String ACTION_ALERT_CLICK   = "org.mozilla.gecko.ACTION_ALERT_CLICK";
     public static final String ACTION_ALERT_CLEAR   = "org.mozilla.gecko.ACTION_ALERT_CLEAR";
     public static final String ACTION_WEBAPP        = "org.mozilla.gecko.WEBAPP";
     public static final String ACTION_DEBUG         = "org.mozilla.gecko.DEBUG";
     public static final String ACTION_BOOKMARK      = "org.mozilla.gecko.BOOKMARK";
     public static final String ACTION_LOAD          = "org.mozilla.gecko.LOAD";
     public static final String ACTION_UPDATE        = "org.mozilla.gecko.UPDATE";
-    public static final String ACTION_INIT_PW       = "org.mozilla.gecko.INIT_PW";
     public static final String SAVED_STATE_URI      = "uri";
     public static final String SAVED_STATE_TITLE    = "title";
     public static final String SAVED_STATE_VIEWPORT = "viewport";
     public static final String SAVED_STATE_SCREEN   = "screen";
     public static final String SAVED_STATE_SESSION  = "session";
 
     StartupMode mStartupMode = null;
     private LinearLayout mMainLayout;
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -107,17 +107,16 @@ public class GeckoAppShell
     static public final int WPL_STATE_IS_DOCUMENT = 0x00020000;
     static public final int WPL_STATE_IS_NETWORK = 0x00040000;
 
     static private File sCacheFile = null;
     static private int sFreeSpace = -1;
     static File sHomeDir = null;
     static private int sDensityDpi = 0;
     private static Boolean sSQLiteLibsLoaded = false;
-    private static Boolean sNSSLibsLoaded = false;
     private static Boolean sLibsSetup = false;
     private static File sGREDir = null;
 
     private static HashMap<String, ArrayList<GeckoEventListener>> mEventListeners;
 
     /* Is the value in sVibrationEndTime valid? */
     private static boolean sVibrationMaybePlaying = false;
 
@@ -136,18 +135,17 @@ public class GeckoAppShell
     //    public static native void setSurfaceView(GeckoSurfaceView sv);
     public static native void setSoftwareLayerClient(GeckoSoftwareLayerClient client);
     public static native void putenv(String map);
     public static native void onResume();
     public static native void onLowMemory();
     public static native void callObserver(String observerKey, String topic, String data);
     public static native void removeObserver(String observerKey);
     public static native void loadGeckoLibsNative(String apkName);
-    public static native void loadSQLiteLibsNative(String apkName);
-    public static native void loadNSSLibsNative(String apkName);
+    public static native void loadSQLiteLibsNative(String apkName, boolean shouldExtract);
     public static native void onChangeNetworkLinkStatus(String status);
 
     public static void registerGlobalExceptionHandler() {
         Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
             public void uncaughtException(Thread thread, Throwable e) {
                 Log.e(LOGTAG, ">>> REPORTING UNCAUGHT EXCEPTION FROM THREAD "
                               + thread.getId() + " (\"" + thread.getName() + "\")", e);
                 reportJavaCrash(getStackTraceString(e));
@@ -262,16 +260,25 @@ public class GeckoAppShell
 
         // The package data lib directory isn't placed in ld.so's
         // search path, so we have to manually load libraries that
         // libxul will depend on.  Not ideal.
         GeckoProfile profile = GeckoProfile.get(context);
 
         File cacheFile = getCacheDir(context);
         putenv("GRE_HOME=" + getGREDir(context).getPath());
+        File[] files = cacheFile.listFiles();
+        if (files != null) {
+            Iterator<File> cacheFiles = Arrays.asList(files).iterator();
+            while (cacheFiles.hasNext()) {
+                File libFile = cacheFiles.next();
+                if (libFile.getName().endsWith(".so"))
+                    libFile.delete();
+            }
+        }
 
         // setup the libs cache
         String linkerCache = System.getenv("MOZ_LINKER_CACHE");
         if (System.getenv("MOZ_LINKER_CACHE") == null) {
             GeckoAppShell.putenv("MOZ_LINKER_CACHE=" + cacheFile.getPath());
         }
         sLibsSetup = true;
     }
@@ -354,34 +361,21 @@ public class GeckoAppShell
         if (sSQLiteLibsLoaded)
             return;
         synchronized(sSQLiteLibsLoaded) {
             if (sSQLiteLibsLoaded)
                 return;
             loadMozGlue();
             // the extract libs parameter is being removed in bug 732069
             loadLibsSetup(context);
-            loadSQLiteLibsNative(apkName);
+            loadSQLiteLibsNative(apkName, false);
             sSQLiteLibsLoaded = true;
         }
     }
 
-    public static void loadNSSLibs(Context context, String apkName) {
-        if (sNSSLibsLoaded)
-            return;
-        synchronized(sNSSLibsLoaded) {
-            if (sNSSLibsLoaded)
-                return;
-            loadMozGlue();
-            loadLibsSetup(context);
-            loadNSSLibsNative(apkName);
-            sNSSLibsLoaded = true;
-        }
-    }
-
     public static void loadMozGlue() {
         System.loadLibrary("mozglue");
     }
 
     public static void loadGeckoLibs(String apkName) {
         loadLibsSetup(GeckoApp.mAppContext);
         loadGeckoLibsNative(apkName);
     }
deleted file mode 100644
--- a/mobile/android/base/GeckoMessageReceiver.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/* 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/. */
-
-package org.mozilla.gecko;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-public class GeckoMessageReceiver extends BroadcastReceiver {
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        final String action = intent.getAction();
-        if (GeckoApp.ACTION_INIT_PW.equals(action)) {
-            GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Passwords:Init", null));
-        }
-    }
-}
--- a/mobile/android/base/GeckoThread.java
+++ b/mobile/android/base/GeckoThread.java
@@ -85,17 +85,16 @@ public class GeckoThread extends Thread 
 
         // At some point while loading the gecko libs our default locale gets set
         // so just save it to locale here and reset it as default after the join
         Locale locale = Locale.getDefault();
 
         String resourcePath = app.getApplication().getPackageResourcePath();
         GeckoAppShell.setupGeckoEnvironment(app);
         GeckoAppShell.loadSQLiteLibs(app, resourcePath);
-        GeckoAppShell.loadNSSLibs(app, resourcePath);
         GeckoAppShell.loadGeckoLibs(resourcePath);
 
         Locale.setDefault(locale);
         Resources res = app.getBaseContext().getResources();
         Configuration config = res.getConfiguration();
         config.locale = locale;
         res.updateConfiguration(config, res.getDisplayMetrics());
 
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -83,25 +83,23 @@ FENNEC_JAVA_FILES = \
   GeckoAsyncTask.java \
   GeckoBatteryManager.java \
   GeckoBackgroundThread.java \
   GeckoConnectivityReceiver.java \
   GeckoEvent.java \
   GeckoEventListener.java \
   GeckoEventResponder.java \
   GeckoInputConnection.java \
-	GeckoMessageReceiver.java \
   GeckoPreferences.java \
   GeckoProfile.java \
   GeckoStateListDrawable.java \
   GeckoThread.java \
   GlobalHistory.java \
   LinkPreference.java \
   LinkTextView.java \
-	NSSBridge.java \
   ProfileMigrator.java \
   PromptService.java \
   sqlite/ByteBufferInputStream.java \
   sqlite/MatrixBlobCursor.java \
   sqlite/SQLiteBridge.java \
   sqlite/SQLiteBridgeException.java \
   RemoteTabs.java \
   SetupScreen.java \
deleted file mode 100644
--- a/mobile/android/base/NSSBridge.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/* 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/. */
-
-package org.mozilla.gecko;
-
-import android.app.Activity;
-import android.util.Log;
-import android.content.Context;
-import java.lang.String;
-
-public class NSSBridge {
-    private static final String LOGTAG = "NSSBridge";
-
-    private static native String nativeEncrypt(String aDb, String aValue);
-    private static native String nativeDecrypt(String aDb, String aValue);
-
-    static public String encrypt(Context context, String aValue) {
-        String resourcePath = context.getPackageResourcePath();
-        GeckoAppShell.loadNSSLibs(context, resourcePath);
-
-        String res = "";
-        try {
-            String path = GeckoProfile.get(context).getDir().toString();
-            res = nativeEncrypt(path, aValue);
-        } catch(Exception ex) { }
-        return res;
-    }
-
-    static public String encrypt(Context context, String profilePath, String aValue) {
-        String resourcePath = context.getPackageResourcePath();
-        GeckoAppShell.loadNSSLibs(context, resourcePath);
-
-        String res = "";
-        try {
-            res = nativeEncrypt(profilePath, aValue);
-        } catch(Exception ex) { }
-        return res;
-    }
-
-    static public String decrypt(Context context, String aValue) {
-        String resourcePath = context.getPackageResourcePath();
-        GeckoAppShell.loadNSSLibs(context, resourcePath);
-
-        String res = "";
-        try {
-            String path = GeckoProfile.get(context).getDir().toString();
-            res = nativeDecrypt(path, aValue);
-        } catch(Exception ex) { }
-        return res;
-    }
-
-    static public String decrypt(Context context, String profilePath, String aValue) {
-        String resourcePath = context.getPackageResourcePath();
-        GeckoAppShell.loadNSSLibs(context, resourcePath);
-
-        String res = "";
-        try {
-            res = nativeDecrypt(profilePath, aValue);
-        } catch(Exception ex) { }
-        return res;
-    }
-}
--- a/mobile/android/base/db/BrowserContract.java.in
+++ b/mobile/android/base/db/BrowserContract.java.in
@@ -40,20 +40,25 @@ package org.mozilla.gecko.db;
 
 import android.net.Uri;
 
 public class BrowserContract {
     public static final String AUTHORITY = "@ANDROID_PACKAGE_NAME@.db.browser";
     public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
 
     public static final String PASSWORDS_AUTHORITY = "@ANDROID_PACKAGE_NAME@.db.passwords";
+    public static final String DELETED_PASSWORDS_AUTHORITY = "@ANDROID_PACKAGE_NAME@.db.deleted-passwords";
+
     public static final Uri PASSWORDS_AUTHORITY_URI = Uri.parse("content://" + PASSWORDS_AUTHORITY);
+    public static final Uri DELETED_PASSWORDS_AUTHORITY_URI = Uri.parse("content://" + DELETED_PASSWORDS_AUTHORITY);
 
     public static final String FORM_HISTORY_AUTHORITY = "@ANDROID_PACKAGE_NAME@.db.formhistory";
+    public static final String DELETED_FORM_HISTORY_AUTHORITY = "@ANDROID_PACKAGE_NAME@.db.deleted-formhistory";
     public static final Uri FORM_HISTORY_AUTHORITY_URI = Uri.parse("content://" + FORM_HISTORY_AUTHORITY);
+    public static final Uri DELETED_FORM_HISTORY_AUTHORITY_URI = Uri.parse("content://" + DELETED_FORM_HISTORY_AUTHORITY);
     
     public static final String TABS_AUTHORITY = "@ANDROID_PACKAGE_NAME@.db.tabs";
     public static final Uri TABS_AUTHORITY_URI = Uri.parse("content://" + TABS_AUTHORITY);
 
     public static final String DEFAULT_PROFILE = "default";
     public static final String PARAM_PROFILE = "profile";
     public static final String PARAM_PROFILE_PATH = "profilePath";
     public static final String PARAM_LIMIT = "limit";
@@ -158,17 +163,17 @@ public class BrowserContract {
         public static final String TIME_PASSWORD_CHANGED = "timePasswordChanged";
         public static final String TIMES_USED = "timesUsed";
         public static final String GUID = "guid";
     }
 
     public static final class DeletedPasswords implements DeletedColumns {
         private DeletedPasswords() {}
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/deleted-passwords";
-        public static final Uri CONTENT_URI = Uri.withAppendedPath(PASSWORDS_AUTHORITY_URI, "deleted-passwords");
+        public static final Uri CONTENT_URI = Uri.withAppendedPath(DELETED_PASSWORDS_AUTHORITY_URI, "deleted-formhistory");
     }
 
     public static final class FormHistory {
         private FormHistory() {}
         public static final Uri CONTENT_URI = Uri.withAppendedPath(FORM_HISTORY_AUTHORITY_URI, "formhistory");
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/formhistory";
 
         public static final String ID = "id";
@@ -177,17 +182,17 @@ public class BrowserContract {
         public static final String TIMES_USED = "timesUsed";
         public static final String FIRST_USED = "firstUsed";
         public static final String LAST_USED = "lastUsed";
         public static final String GUID = "guid";
     }
 
     public static final class DeletedFormHistory implements DeletedColumns {
         private DeletedFormHistory() {}
-        public static final Uri CONTENT_URI = Uri.withAppendedPath(FORM_HISTORY_AUTHORITY_URI, "deleted-formhistory");
+        public static final Uri CONTENT_URI = Uri.withAppendedPath(DELETED_FORM_HISTORY_AUTHORITY_URI, "deleted-formhistory");
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/deleted-formhistory";
     }
 
     public static final class Tabs implements CommonColumns {
         private Tabs() {}
         public static final Uri CONTENT_URI = Uri.withAppendedPath(TABS_AUTHORITY_URI, "tabs");
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/tab";
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/tab";
--- a/mobile/android/base/db/DBUtils.java
+++ b/mobile/android/base/db/DBUtils.java
@@ -54,13 +54,13 @@ public class DBUtils {
     public static void replaceKey(ContentValues aValues, String aOriginalKey,
                                   String aNewKey, String aDefault) {
         String value = aDefault;
         if (aOriginalKey != null && aValues.containsKey(aOriginalKey)) {
             value = aValues.get(aOriginalKey).toString();
             aValues.remove(aOriginalKey);
         }
 
-        if (!aValues.containsKey(aNewKey)) {
+        if (!aValues.containsKey(aOriginalKey)) {
             aValues.put(aNewKey, value);
         }
     }
 }
--- a/mobile/android/base/db/FormHistoryProvider.java.in
+++ b/mobile/android/base/db/FormHistoryProvider.java.in
@@ -28,16 +28,19 @@ import org.mozilla.gecko.sqlite.SQLiteBr
 import org.mozilla.gecko.sync.Utils;
 
 import android.content.ContentProvider;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.UriMatcher;
 import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 import android.os.Build;
 import android.text.TextUtils;
 import android.util.Log;
 
 public class FormHistoryProvider extends GeckoProvider {
     static final String TABLE_FORM_HISTORY = "moz_formhistory";
     static final String TABLE_DELETED_FORM_HISTORY = "moz_deleted_formhistory";
@@ -49,23 +52,20 @@ public class FormHistoryProvider extends
 
     private static HashMap<String, String> FORM_HISTORY_PROJECTION_MAP;
     private static HashMap<String, String> DELETED_FORM_HISTORY_PROJECTION_MAP;
 
     // This should be kept in sync with the db version in toolkit/components/satchel/nsFormHistory.js
     private static int DB_VERSION = 4;
     private static String DB_FILENAME = "formhistory.sqlite";
 
-    private static final String WHERE_GUID_IS_NULL = BrowserContract.DeletedFormHistory.GUID + " IS NULL";
-    private static final String WHERE_GUID_IS_VALUE = BrowserContract.DeletedFormHistory.GUID + " = ?";
-
     static {
         URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
         URI_MATCHER.addURI(BrowserContract.FORM_HISTORY_AUTHORITY, "formhistory", FORM_HISTORY);
-        URI_MATCHER.addURI(BrowserContract.FORM_HISTORY_AUTHORITY, "deleted-formhistory", DELETED_FORM_HISTORY);
+        URI_MATCHER.addURI(BrowserContract.DELETED_FORM_HISTORY_AUTHORITY, "deleted-formhistory", DELETED_FORM_HISTORY);
         FORM_HISTORY_PROJECTION_MAP = new HashMap<String, String>();
         DELETED_FORM_HISTORY_PROJECTION_MAP = new HashMap<String, String>();
     }
 
     @Override
     public boolean onCreate() {
         setLogTag("FormHistoryProvider");
         setDBName(DB_FILENAME);
@@ -141,33 +141,9 @@ public class FormHistoryProvider extends
             default:
                 throw new UnsupportedOperationException("Unknown insert URI " + uri);
         }
     }
 
     public void initGecko() {
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FormHistory:Init", null));
     }
-
-    @Override
-    public void onPreInsert(ContentValues values, Uri uri, SQLiteBridge db) {
-        if (!values.containsKey(FormHistory.GUID)) {
-            return;
-        }
-        String guid = values.getAsString(FormHistory.GUID);
-        try {
-            if (guid == null) {
-                db.delete(TABLE_DELETED_FORM_HISTORY, WHERE_GUID_IS_NULL, null);
-                return;
-            }
-            String[] args = new String[] { guid };
-            db.delete(TABLE_DELETED_FORM_HISTORY, WHERE_GUID_IS_VALUE, args);
-        } catch(SQLiteBridgeException ex) {
-            Log.w(getLogTag(), "Error removing entry with GUID " + guid, ex);
-        }
-     }
-
-    @Override
-    public void onPreUpdate(ContentValues values, Uri uri, SQLiteBridge db) { }
-
-    @Override
-    public void onPostQuery(Cursor cursor, Uri uri, SQLiteBridge db) { }
 }
--- a/mobile/android/base/db/GeckoProvider.java.in
+++ b/mobile/android/base/db/GeckoProvider.java.in
@@ -85,17 +85,16 @@ public abstract class GeckoProvider exte
 
     private SQLiteBridge getDB(Context context, final String databasePath) {
         SQLiteBridge bridge = null;
 
         boolean dbNeedsSetup = true;
         try {
             String resourcePath = context.getPackageResourcePath();
             GeckoAppShell.loadSQLiteLibs(context, resourcePath);
-            GeckoAppShell.loadNSSLibs(context, resourcePath);
             bridge = new SQLiteBridge(databasePath);
             int version = bridge.getVersion();
             Log.i(mLogTag, version + " == " + mDBVersion);
             dbNeedsSetup = version != mDBVersion;
         } catch(SQLiteBridgeException ex) {
             // this will throw if the database can't be found
             // we should attempt to set it up if Gecko is running
             dbNeedsSetup = true;
@@ -217,18 +216,16 @@ public abstract class GeckoProvider exte
         // If we can not get a SQLiteBridge instance, its likely that the database
         // has not been set up and Gecko is not running. We return null and expect
         // callers to try again later
         if (db == null)
             return null;
 
         setupDefaults(uri, values);
 
-        onPreInsert(values, uri, db);
-
         try {
             id = db.insert(getTable(uri), null, values);
         } catch(SQLiteBridgeException ex) {
             Log.e(mLogTag, "Error inserting in db", ex);
         }
 
         return ContentUris.withAppendedId(uri, id);
     }
@@ -240,18 +237,16 @@ public abstract class GeckoProvider exte
         final SQLiteBridge db = getDatabase(uri);
 
         // If we can not get a SQLiteBridge instance, its likely that the database
         // has not been set up and Gecko is not running. We return null and expect
         // callers to try again later
         if (db == null)
             return updated;
 
-        onPreUpdate(values, uri, db);
-
         try {
             updated = db.update(getTable(uri), values, selection, selectionArgs);
         } catch(SQLiteBridgeException ex) {
             Log.e(mLogTag, "Error updating table", ex);
         }
 
         return updated;
     }
@@ -267,30 +262,23 @@ public abstract class GeckoProvider exte
         // callers to try again later
         if (db == null)
             return cursor;
 
         sortOrder = getSortOrder(uri, sortOrder);
 
         try {
             cursor = db.query(getTable(uri), projection, selection, selectionArgs, null, null, sortOrder, null);
-            onPostQuery(cursor, uri, db);
         } catch (SQLiteBridgeException ex) {
             Log.e(mLogTag, "Error querying database", ex);
         }
 
         return cursor;
     }
 
     public abstract String getTable(Uri uri);
 
     public abstract String getSortOrder(Uri uri, String aRequested);
 
     public abstract void setupDefaults(Uri uri, ContentValues values);
 
     public abstract void initGecko();
-
-    public abstract void onPreInsert(ContentValues values, Uri uri, SQLiteBridge db);
-
-    public abstract void onPreUpdate(ContentValues values, Uri uri, SQLiteBridge db);
-
-    public abstract void onPostQuery(Cursor cursor, Uri uri, SQLiteBridge db);
 }
--- a/mobile/android/base/db/PasswordsProvider.java.in
+++ b/mobile/android/base/db/PasswordsProvider.java.in
@@ -12,34 +12,35 @@ import java.util.HashMap;
 import java.util.ArrayList;
 import java.util.Random;
 
 import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.GeckoEventListener;
 import org.mozilla.gecko.GeckoProfile;
-import org.mozilla.gecko.NSSBridge;
+import org.mozilla.gecko.db.BrowserContract.CommonColumns;
 import org.mozilla.gecko.db.DBUtils;
 import org.mozilla.gecko.db.BrowserContract.Passwords;
 import org.mozilla.gecko.db.BrowserContract.DeletedPasswords;
 import org.mozilla.gecko.db.BrowserContract.SyncColumns;
 import org.mozilla.gecko.db.BrowserContract;
-import org.mozilla.gecko.sqlite.MatrixBlobCursor;
 import org.mozilla.gecko.sqlite.SQLiteBridge;
 import org.mozilla.gecko.sqlite.SQLiteBridgeException;
 import org.mozilla.gecko.sync.Utils;
 
 import android.content.ContentProvider;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.Intent;
 import android.content.UriMatcher;
 import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 import android.os.Build;
 import android.text.TextUtils;
 import android.util.Log;
 
 public class PasswordsProvider extends GeckoProvider {
     static final String TABLE_PASSWORDS = "moz_logins";
     static final String TABLE_DELETED_PASSWORDS = "moz_deleted_logins";
@@ -54,19 +55,16 @@ public class PasswordsProvider extends G
 
     private static HashMap<String, String> PASSWORDS_PROJECTION_MAP;
     private static HashMap<String, String> DELETED_PASSWORDS_PROJECTION_MAP;
 
     // this should be kept in sync with the version in toolkit/components/passwordmgr/storage-mozStorage.js
     private static final int DB_VERSION = 5;
     private static final String DB_FILENAME = "signons.sqlite";
 
-    private static final String WHERE_GUID_IS_NULL = BrowserContract.DeletedPasswords.GUID + " IS NULL";
-    private static final String WHERE_GUID_IS_VALUE = BrowserContract.DeletedPasswords.GUID + " = ?";
-
     static {
         URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
 
         // content://org.mozilla.gecko.providers.browser/passwords/#
         URI_MATCHER.addURI(BrowserContract.PASSWORDS_AUTHORITY, "passwords", PASSWORDS);
 
         PASSWORDS_PROJECTION_MAP = new HashMap<String, String>();
         PASSWORDS_PROJECTION_MAP.put(Passwords.ID, Passwords.ID);
@@ -79,23 +77,22 @@ public class PasswordsProvider extends G
         PASSWORDS_PROJECTION_MAP.put(Passwords.ENCRYPTED_PASSWORD, Passwords.ENCRYPTED_PASSWORD);
         PASSWORDS_PROJECTION_MAP.put(Passwords.GUID, Passwords.GUID);
         PASSWORDS_PROJECTION_MAP.put(Passwords.ENC_TYPE, Passwords.ENC_TYPE);
         PASSWORDS_PROJECTION_MAP.put(Passwords.TIME_CREATED, Passwords.TIME_CREATED);
         PASSWORDS_PROJECTION_MAP.put(Passwords.TIME_LAST_USED, Passwords.TIME_LAST_USED);
         PASSWORDS_PROJECTION_MAP.put(Passwords.TIME_PASSWORD_CHANGED, Passwords.TIME_PASSWORD_CHANGED);
         PASSWORDS_PROJECTION_MAP.put(Passwords.TIMES_USED, Passwords.TIMES_USED);
 
-        URI_MATCHER.addURI(BrowserContract.PASSWORDS_AUTHORITY, "deleted-passwords", DELETED_PASSWORDS);
+        URI_MATCHER.addURI(BrowserContract.DELETED_PASSWORDS_AUTHORITY, "deleted-passwords", DELETED_PASSWORDS);
 
         DELETED_PASSWORDS_PROJECTION_MAP = new HashMap<String, String>();
         DELETED_PASSWORDS_PROJECTION_MAP.put(DeletedPasswords.ID, DeletedPasswords.ID);
         DELETED_PASSWORDS_PROJECTION_MAP.put(DeletedPasswords.GUID, DeletedPasswords.GUID);
         DELETED_PASSWORDS_PROJECTION_MAP.put(DeletedPasswords.TIME_DELETED, DeletedPasswords.TIME_DELETED);
-        System.loadLibrary("mozglue");
     }
 
     @Override
     public boolean onCreate() {
         setLogTag("GeckoPasswordsProvider");
         setDBName(DB_FILENAME);
         setDBVersion(DB_VERSION);
         return super.onCreate();
@@ -187,100 +184,10 @@ public class PasswordsProvider extends G
             default:
                 throw new UnsupportedOperationException("Unknown URI " + uri);
         }
     }
 
     @Override
     public void initGecko() {
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Passwords:Init", null));
-        Intent initIntent = new Intent(GeckoApp.ACTION_INIT_PW);
-        mContext.sendBroadcast(initIntent);
-    }
-
-    private String doCrypto(String initialValue, Uri uri, Boolean encrypt) {
-        String profilePath = null;
-        if (uri != null) {
-            profilePath = uri.getQueryParameter(BrowserContract.PARAM_PROFILE_PATH);
-        }
-
-        String result = "";
-        if (encrypt) {
-          if (profilePath != null) result = NSSBridge.encrypt(mContext, profilePath, initialValue);
-          else result = NSSBridge.encrypt(mContext, initialValue);
-        } else {
-          if (profilePath != null) result = NSSBridge.decrypt(mContext, profilePath, initialValue);
-          else result = NSSBridge.decrypt(mContext, initialValue);            
-        }
-        return result;
-    }
-
-    @Override
-    public void onPreInsert(ContentValues values, Uri uri, SQLiteBridge db) {
-        if (values.containsKey(Passwords.GUID)) {
-            String guid = values.getAsString(Passwords.GUID);
-            try {
-                if (guid == null) {
-                    db.delete(TABLE_DELETED_PASSWORDS, WHERE_GUID_IS_NULL, null);
-                    return;
-                }
-                String[] args = new String[] { guid };
-                db.delete(TABLE_DELETED_PASSWORDS, WHERE_GUID_IS_VALUE, args);
-            } catch(SQLiteBridgeException ex) {
-                Log.w(getLogTag(), "Error removing entry with GUID " + guid, ex);
-            }
-        }
-
-        if (values.containsKey(Passwords.ENCRYPTED_PASSWORD)) {
-            String res = doCrypto(values.getAsString(Passwords.ENCRYPTED_PASSWORD), uri, true);
-            values.put(Passwords.ENCRYPTED_PASSWORD, res);
-        }
-
-        if (values.containsKey(Passwords.ENCRYPTED_USERNAME)) {
-            String res = doCrypto(values.getAsString(Passwords.ENCRYPTED_USERNAME), uri, true);
-            values.put(Passwords.ENCRYPTED_USERNAME, res);
-        }
-    }
-
-    @Override
-    public void onPreUpdate(ContentValues values, Uri uri, SQLiteBridge db) {
-        if (values.containsKey(Passwords.ENCRYPTED_PASSWORD)) {
-            String res = doCrypto(values.getAsString(Passwords.ENCRYPTED_PASSWORD), uri, true);
-            values.put(Passwords.ENCRYPTED_PASSWORD, res);
-        }
-
-        if (values.containsKey(Passwords.ENCRYPTED_USERNAME)) {
-            String res = doCrypto(values.getAsString(Passwords.ENCRYPTED_USERNAME), uri, true);
-            values.put(Passwords.ENCRYPTED_USERNAME, res);
-        }
-    }
-
-    @Override
-    public void onPostQuery(Cursor cursor, Uri uri, SQLiteBridge db) {
-        int passwordIndex = -1;
-        int usernameIndex = -1;
-        String profilePath = null;
-
-        try {
-            passwordIndex = cursor.getColumnIndexOrThrow(Passwords.ENCRYPTED_PASSWORD);
-        } catch(Exception ex) { }
-        try {
-            usernameIndex = cursor.getColumnIndexOrThrow(Passwords.ENCRYPTED_USERNAME);
-        } catch(Exception ex) { }
-
-        if (passwordIndex > -1 || usernameIndex > -1) {
-            MatrixBlobCursor m = (MatrixBlobCursor)cursor;
-            if (cursor.moveToFirst()) {
-                do {
-                    if (passwordIndex > -1) {
-                        String decrypted = doCrypto(cursor.getString(passwordIndex), uri, false);;
-                        m.set(passwordIndex, decrypted);
-                    }
-
-                    if (usernameIndex > -1) {
-                        String decrypted = doCrypto(cursor.getString(usernameIndex), uri, false);
-                        m.set(usernameIndex, decrypted);
-                    }
-                } while(cursor.moveToNext());
-            }
-        }
     }
 }
--- a/mobile/android/base/sqlite/MatrixBlobCursor.java
+++ b/mobile/android/base/sqlite/MatrixBlobCursor.java
@@ -223,31 +223,18 @@ public class MatrixBlobCursor extends Ab
                         "No more columns left.");
             }
 
             data[index++] = columnValue;
             return this;
         }
     }
 
-    public void set(int column, Object value) {
-        if (column < 0 || column >= columnCount) {
-            throw new CursorIndexOutOfBoundsException("Requested column: "
-                    + column + ", # of columns: " +  columnCount);
-        }
-        if (mPos < 0) {
-            throw new CursorIndexOutOfBoundsException("Before first row.");
-        }
-        if (mPos >= rowCount) {
-            throw new CursorIndexOutOfBoundsException("After last row.");
-        }
-        data[mPos * columnCount + column] = value;
-    }
+    // AbstractCursor implementation.
 
-    // AbstractCursor implementation.
     @Override
     public int getCount() {
         return rowCount;
     }
 
     @Override
     public String[] getColumnNames() {
         return columnNames;
--- a/mobile/android/base/tests/BaseTest.java.in
+++ b/mobile/android/base/tests/BaseTest.java.in
@@ -199,38 +199,9 @@ abstract class BaseTest extends Activity
                 mAsserter.info("Pass","Column value " + c.getString(i) + " ?= " + cv.get(column).toString());
                 if (!cv.get(column).toString().equals(c.getString(i))) {
                     return false;
                 }
             }
         }
         return true;
     }
-
-    @SuppressWarnings({"unchecked", "non-varargs"})
-    public void SqliteCompare(Cursor c, ContentValues[] cvs) {
-        mAsserter.is(c.getCount(), cvs.length, "List is correct length");
-        if (c.moveToFirst()) {
-            do {
-                boolean found = false;
-                for (int i = 0; !found && i < cvs.length; i++) {
-                    if (CursorMatches(c, cvs[i])) {
-                        found = true;
-                    }
-                }
-                mAsserter.is(found, true, "Password was found");
-            } while(c.moveToNext());
-        }
-    }
-
-    public boolean CursorMatches(Cursor c, ContentValues cv) {
-        for (int i = 0; i < c.getColumnCount(); i++) {
-            String column = c.getColumnName(i);
-             if (cv.containsKey(column)) {
-                mAsserter.info("Pass","Column value " + c.getString(i) + " ?= " + cv.get(column).toString());
-                if (!cv.get(column).toString().equals(c.getString(i))) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
 }
--- a/mobile/android/base/tests/robocop.ini
+++ b/mobile/android/base/tests/robocop.ini
@@ -6,15 +6,13 @@
 [testPanCorrectness]
 [test_bug720538]
 # [testFlingCorrectness] # see bug 727351
 [testOverscroll]
 [testAxisLocking]
 [testAboutPage]
 [testWebContentContextMenu]
 [testPasswordProvider]
-[testPasswordEncrypt]
-[testPasswordUndeletion]
 [testFormHistory]
 
 # Used for Talos, please don't use in mochitest
 #[testPan]
 #[testCheck]
deleted file mode 100644
--- a/mobile/android/base/tests/testPasswordEncrypt.java.in
+++ /dev/null
@@ -1,112 +0,0 @@
-#filter substitution
-package @ANDROID_PACKAGE_NAME@.tests;
-
-import @ANDROID_PACKAGE_NAME@.*;
-import android.app.Activity;
-import android.content.ContentValues;
-import android.content.ContentResolver;
-import android.database.Cursor;
-import android.content.Context;
-import android.net.Uri;
-import java.io.File;
-import java.lang.reflect.Method;
-
-public class testPasswordEncrypt extends BaseTest {
-    public void testPasswordEncrypt() {
-      setTestType("mochitest");
-      Context context = (Context)getActivity();
-      ContentResolver cr = context.getContentResolver();
-      ContentValues cvs = new ContentValues();
-
-      Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("Gecko:Ready");
-      contentEventExpecter.blockForEvent();
-
-      File db = new File(mProfile, "signons.sqlite");
-      String dbPath = db.getPath();
-
-      Uri passwordUri;
-      try {
-          ClassLoader classLoader = getActivity().getClassLoader();
-          Class pwds = classLoader.loadClass("org.mozilla.gecko.db.BrowserContract$Passwords");
-          Class nss = classLoader.loadClass("org.mozilla.gecko.NSSBridge");
-          Class contextClass = classLoader.loadClass("android.content.Context");
-          Class stringClass = classLoader.loadClass("java.lang.String");
-          Class appshell = classLoader.loadClass("org.mozilla.gecko.GeckoAppShell");
-
-          Method loadNSSLibs = appshell.getMethod("loadNSSLibs", contextClass, stringClass);
-          Method decrypt = nss.getMethod("decrypt", contextClass, stringClass, stringClass);
-          Method encrypt = nss.getMethod("encrypt", contextClass, stringClass, stringClass);
-  
-          cvs.put("hostname", "http://www.example.com");
-          cvs.put("encryptedUsername", "username");
-          cvs.put("encryptedPassword", "password");
-
-          // Attempt to insert into the db
-          passwordUri = (Uri)pwds.getField("CONTENT_URI").get(null);
-          Uri.Builder builder = passwordUri.buildUpon();
-          passwordUri = builder.appendQueryParameter("profilePath", mProfile).build();
-
-          // This should fail the first time round because there is no pw database
-          // Wait for gecko to reply and then we'll try again
-          contentEventExpecter = mActions.expectGeckoEvent("Passwords:Init:Return");
-          Uri uri = cr.insert(passwordUri, cvs);
-          contentEventExpecter.blockForEvent();
-          mAsserter.is(uri, null, "Insert returned null correctly");
-  
-          uri = cr.insert(passwordUri, cvs);
-          Uri expectedUri = passwordUri.buildUpon().appendPath("1").build();
-          mAsserter.is(uri.toString(), expectedUri.toString(), "Insert returned correct uri");
-
-          Cursor list = mActions.querySql(dbPath, "SELECT encryptedUsername FROM moz_logins");
-          String resourcePath = getActivity().getApplication().getPackageResourcePath();
-          loadNSSLibs.invoke(null, (Context)getActivity(), resourcePath);
-
-          list.moveToFirst();
-          String decryptedU = (String)decrypt.invoke(null, context, mProfile, list.getString(0));
-          mAsserter.is(decryptedU, "username", "Username was encrypted correctly when inserting");
-
-          list = mActions.querySql(dbPath, "SELECT encryptedPassword FROM moz_logins");
-          list.moveToFirst();
-          String decryptedP = (String)decrypt.invoke(null, context, mProfile, list.getString(0));
-          mAsserter.is(decryptedP, "password", "Password was encrypted correctly when inserting");
-  
-          cvs.put("encryptedUsername", "username2");
-          cvs.put("encryptedPassword", "password2");
-          cr.update(passwordUri, cvs, null, null);
-
-          list = mActions.querySql(dbPath, "SELECT encryptedUsername FROM moz_logins");
-          list.moveToFirst();
-          decryptedU = (String)decrypt.invoke(null, context, mProfile, list.getString(0));
-          mAsserter.is(decryptedU, "username2", "Username was encrypted when updating");
-
-          list = mActions.querySql(dbPath, "SELECT encryptedPassword FROM moz_logins");
-          list.moveToFirst();
-          decryptedP = (String)decrypt.invoke(null, context, mProfile, list.getString(0));
-          mAsserter.is(decryptedP, "password2", "Password was encrypted when updating");
-      } catch(ClassNotFoundException ex) {
-          mAsserter.ok(false, "Error getting class", ex.toString());
-          return;
-      } catch(NoSuchFieldException ex) {
-          mAsserter.ok(false, "Error getting field", ex.toString());
-          return;
-      } catch(IllegalAccessException ex) {
-          mAsserter.ok(false, "Error using field", ex.toString());
-          return;
-      } catch(java.lang.NoSuchMethodException ex) {
-          mAsserter.ok(false, "Error getting method", ex.toString());
-          return;
-      } catch(java.lang.reflect.InvocationTargetException ex) {
-          mAsserter.ok(false, "Error invoking method", ex.toString());
-          return;
-      }
-    }
-
-    public void tearDown() throws Exception {
-        super.tearDown();
-  
-        // remove the entire signons.sqlite file
-        File profile = new File(mProfile);
-        File db = new File(profile, "signons.sqlite");
-        db.delete();
-    }
-}
--- a/mobile/android/base/tests/testPasswordProvider.java.in
+++ b/mobile/android/base/tests/testPasswordProvider.java.in
@@ -60,34 +60,31 @@ public class testPasswordProvider extend
         // Trying to inset should fail the first time round because there is no pw database
         // Wait for gecko to reply and then we'll try again
         contentEventExpecter = mActions.expectGeckoEvent("Passwords:Init:Return");
         Uri uri = cr.insert(passwordUri, cvs[0]);
         mAsserter.is(uri, null, "Insert returned null correctly");
         contentEventExpecter.blockForEvent();
   
         uri = cr.insert(passwordUri, cvs[0]);
+        SqliteCompare(DB_NAME, "SELECT * FROM moz_logins", cvs);
         Uri expectedUri = passwordUri.buildUpon().appendPath("1").build();
-        mAsserter.is(uri.toString(), expectedUri.toString(), "Insert returned correct uri");
-        Cursor c = cr.query(passwordUri, null, null, null, null);
-        SqliteCompare(c, cvs);
+        mAsserter.is(expectedUri.toString(), uri.toString(), "Insert returned correct uri");
   
         cvs[0].put("usernameField", "usernameField2");
         cvs[0].put("passwordField", "passwordField2");
   
         int numUpdated = cr.update(passwordUri, cvs[0], null, null);
         mAsserter.is(1, numUpdated, "Correct number updated");
-        c = cr.query(passwordUri, null, null, null, null);
-        SqliteCompare(c, cvs);
+        SqliteCompare(DB_NAME, "SELECT * FROM moz_logins", cvs);
   
         int numDeleted = cr.delete(passwordUri, null, null);
         mAsserter.is(1, numDeleted, "Correct number deleted");
         cvs = new ContentValues[0];
-        c = cr.query(passwordUri, null, null, null, null);
-        SqliteCompare(c, cvs);
+        SqliteCompare(DB_NAME, "SELECT * FROM moz_logins", cvs);
     }
 
     public void tearDown() throws Exception {
         super.tearDown();
   
         // remove the entire signons.sqlite file
         File profile = new File(mProfile);
         File db = new File(profile, "signons.sqlite");
deleted file mode 100644
--- a/mobile/android/base/tests/testPasswordUndeletion.java.in
+++ /dev/null
@@ -1,98 +0,0 @@
-/* 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/. */
- 
-#filter substitution
-package @ANDROID_PACKAGE_NAME@.tests;
-
-import @ANDROID_PACKAGE_NAME@.*;
-import android.app.Activity;
-import android.content.ContentValues;
-import android.content.ContentResolver;
-import android.database.Cursor;
-import android.content.Context;
-import android.net.Uri;
-import java.io.File;
-import android.util.Log;
-import java.util.ArrayList;
-import java.lang.reflect.Method;
-
-public class testPasswordUndeletion extends BaseTest {
-    public void testPasswordUndeletion() {
-        setTestType("mochitest");
-        Context context = (Context) getActivity();
-        ContentResolver cr = context.getContentResolver();
-        ContentValues cvs[] = new ContentValues[1];
-        cvs[0] = new ContentValues();
-  
-        Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("Gecko:Ready");
-        contentEventExpecter.blockForEvent();
-  
-        File db = new File(mProfile, "signons.sqlite");
-        String dbPath = db.getPath();
-  
-        Uri passwordUri;
-        Uri deletedPasswordUri;
-        try {
-            ClassLoader classLoader = getActivity().getClassLoader();
-            Class pwds = classLoader.loadClass("org.mozilla.gecko.db.BrowserContract$Passwords");
-            Class deletedpwds = classLoader.loadClass("org.mozilla.gecko.db.BrowserContract$DeletedPasswords");
-            Class nss = classLoader.loadClass("org.mozilla.gecko.NSSBridge");
-            Class contextClass = classLoader.loadClass("android.content.Context");
-            Class stringClass = classLoader.loadClass("java.lang.String");
-            Class appshell = classLoader.loadClass("org.mozilla.gecko.GeckoAppShell");
-  
-            Method ensureNSSLibsLoaded = appshell.getMethod("ensureNSSLibsLoaded", contextClass, stringClass);
-            Method decrypt = nss.getMethod("decrypt", contextClass, stringClass, stringClass);
-            Method encrypt = nss.getMethod("encrypt", contextClass, stringClass, stringClass);
-    
-            cvs[0].put("guid", "MtaVURdK-eRl");
-  
-            // Attempt to insert into the database.
-            deletedPasswordUri = (Uri) deletedpwds.getField("CONTENT_URI").get(null);
-            deletedPasswordUri = deletedPasswordUri.buildUpon().appendQueryParameter("profilePath", mProfile).build();
-            passwordUri = (Uri) pwds.getField("CONTENT_URI").get(null);
-            passwordUri = passwordUri.buildUpon().appendQueryParameter("profilePath", mProfile).build();
-  
-            Uri uri = cr.insert(deletedPasswordUri, cvs[0]);
-            mAsserter.is(uri, null, "Insert returned null correctly");
-    
-            // This should fail the first time round because there is no pw database.
-            // Wait for gecko to reply and then we'll try again.
-            contentEventExpecter = mActions.expectGeckoEvent("Passwords:Init:Return");
-            contentEventExpecter.blockForEvent();
-            cr.insert(deletedPasswordUri, cvs[0]);
-  
-            // Attempting to insert another item with the same guid should
-            // remove the item from deletedPasswords database.
-            cr.insert(passwordUri, cvs[0]);
-            Cursor c = cr.query(deletedPasswordUri, null, null, null, null);
-            SqliteCompare(c, new ContentValues[0]);
-
-            c = cr.query(passwordUri, null, null, null, null);
-            SqliteCompare(c, cvs);
-  
-        } catch(ClassNotFoundException ex) {
-            mAsserter.ok(false, "Error getting class", ex.toString());
-            return;
-        } catch(NoSuchFieldException ex) {
-            mAsserter.ok(false, "Error getting field", ex.toString());
-            return;
-        } catch(IllegalAccessException ex) {
-            mAsserter.ok(false, "Error using field", ex.toString());
-            return;
-        } catch(java.lang.NoSuchMethodException ex) {
-            mAsserter.ok(false, "Error getting method", ex.toString());
-            return;
-        }
-    }
-
-    public void tearDown() throws Exception {
-        super.tearDown();
-  
-        // remove the entire signons.sqlite file
-        File profile = new File(mProfile);
-        File db = new File(profile, "signons.sqlite");
-        db.delete();
-    }
-}
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -61,29 +61,26 @@
 #endif
 #include "dlfcn.h"
 #include "APKOpen.h"
 #include <sys/time.h>
 #include <sys/resource.h>
 #include "Zip.h"
 #include "sqlite3.h"
 #include "SQLiteBridge.h"
-#include "NSSBridge.h"
 #ifndef MOZ_OLD_LINKER
 #include "ElfLoader.h"
 #endif
 #include "application.ini.h"
 
 /* Android headers don't define RUSAGE_THREAD */
 #ifndef RUSAGE_THREAD
 #define RUSAGE_THREAD 1
 #endif
 
-typedef int mozglueresult;
-
 enum StartupEvent {
 #define mozilla_StartupTimeline_Event(ev, z) ev,
 #include "StartupTimeline.h"
 #undef mozilla_StartupTimeline_Event
 };
 
 using namespace mozilla;
 
@@ -97,33 +94,16 @@ void StartupTimeline_Record(StartupEvent
 static struct mapping_info * lib_mapping = NULL;
 
 NS_EXPORT const struct mapping_info *
 getLibraryMapping()
 {
   return lib_mapping;
 }
 
-void
-JNI_Throw(JNIEnv* jenv, const char* classname, const char* msg)
-{
-    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Throw\n");
-    jclass cls = jenv->FindClass(classname);
-    if (cls == NULL) {
-        __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't find exception class (or exception pending) %s\n", classname);
-        exit(FAILURE);
-    }
-    int rc = jenv->ThrowNew(cls, msg);
-    if (rc < 0) {
-        __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Error throwing exception %s\n", msg);
-        exit(FAILURE);
-    }
-    jenv->DeleteLocalRef(cls);
-}
-
 #ifdef MOZ_OLD_LINKER
 static int
 createAshmem(size_t bytes, const char *name)
 {
   int fd = open("/" ASHMEM_NAME_DEF, O_RDWR, 0600);
   if (fd < 0)
     return -1;
 
@@ -328,20 +308,89 @@ SHELL_WRAPPER3(notifySmsDeleted, jboolea
 SHELL_WRAPPER3(notifySmsDeleteFailed, jint, jint, jlong)
 SHELL_WRAPPER2(notifyNoMessageInList, jint, jlong)
 SHELL_WRAPPER8(notifyListCreated, jint, jint, jstring, jstring, jstring, jlong, jint, jlong)
 SHELL_WRAPPER7(notifyGotNextMessage, jint, jstring, jstring, jstring, jlong, jint, jlong)
 SHELL_WRAPPER3(notifyReadingMessageListFailed, jint, jint, jlong)
 
 static void * xul_handle = NULL;
 static void * sqlite_handle = NULL;
-static void * nss_handle = NULL;
-static void * nspr_handle = NULL;
-static void * plc_handle = NULL;
-static bool simple_linker_initialized = false;
+#ifdef MOZ_OLD_LINKER
+static time_t apk_mtime = 0;
+#ifdef DEBUG
+extern "C" int extractLibs = 1;
+#else
+extern "C" int extractLibs = 0;
+#endif
+
+static void
+extractFile(const char * path, Zip::Stream &s)
+{
+  uint32_t size = s.GetUncompressedSize();
+
+  struct stat status;
+  if (!stat(path, &status) &&
+      status.st_size == size &&
+      apk_mtime < status.st_mtime)
+    return;
+
+  int fd = open(path, O_CREAT | O_NOATIME | O_TRUNC | O_RDWR, S_IRWXU);
+  if (fd == -1) {
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't open %s to decompress library", path);
+    return;
+  }
+
+  if (ftruncate(fd, size) == -1) {
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't ftruncate %s to decompress library", path);
+    close(fd);
+    return;
+  }
+
+  void * buf = mmap(NULL, size, PROT_READ | PROT_WRITE,
+                    MAP_SHARED, fd, 0);
+  if (buf == (void *)-1) {
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't mmap decompression buffer");
+    close(fd);
+    return;
+  }
+
+  z_stream strm = {
+    next_in: (Bytef *)s.GetBuffer(),
+    avail_in: s.GetSize(),
+    total_in: 0,
+
+    next_out: (Bytef *)buf,
+    avail_out: size,
+    total_out: 0
+  };
+
+  int ret;
+  ret = inflateInit2(&strm, -MAX_WBITS);
+  if (ret != Z_OK)
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateInit failed: %s", strm.msg);
+
+  if (inflate(&strm, Z_FINISH) != Z_STREAM_END)
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflate failed: %s", strm.msg);
+
+  if (strm.total_out != size)
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "extracted %d, expected %d!", strm.total_out, size);
+
+  ret = inflateEnd(&strm);
+  if (ret != Z_OK)
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "inflateEnd failed: %s", strm.msg);
+
+  close(fd);
+#ifdef ANDROID_ARM_LINKER
+  /* We just extracted data that is going to be executed in the future.
+   * We thus need to ensure Instruction and Data cache coherency. */
+  cacheflush((unsigned) buf, (unsigned) buf + size, 0);
+#endif
+  munmap(buf, size);
+}
+#endif
 
 #if defined(MOZ_CRASHREPORTER) || defined(MOZ_OLD_LINKER)
 static void
 extractLib(Zip::Stream &s, void * dest)
 {
   z_stream strm = {
     next_in: (Bytef *)s.GetBuffer(),
     avail_in: s.GetSize(),
@@ -456,16 +505,35 @@ static void * mozload(const char * path,
   gettimeofday(&t0, 0);
 #endif
 
   void *handle;
   Zip::Stream s;
   if (!zip->GetStream(path, &s))
     return NULL;
 
+  if (extractLibs) {
+    char fullpath[PATH_MAX];
+    snprintf(fullpath, PATH_MAX, "%s/%s", getenv("MOZ_LINKER_CACHE"), path);
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "resolved %s to %s", path, fullpath);
+    extractFile(fullpath, s);
+    handle = __wrap_dlopen(fullpath, RTLD_LAZY);
+    if (!handle)
+      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", fullpath, __wrap_dlerror());
+#ifdef DEBUG
+    gettimeofday(&t1, 0);
+    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path,
+                        (((long long)t1.tv_sec * 1000000LL) +
+                          (long long)t1.tv_usec) -
+                        (((long long)t0.tv_sec * 1000000LL) +
+                          (long long)t0.tv_usec));
+#endif
+    return handle;
+  }
+
   bool skipLibCache = false;
   int fd;
   void * buf = NULL;
   uint32_t lib_size = s.GetUncompressedSize();
   int cache_fd = 0;
   if (s.GetType() == Zip::Stream::DEFLATE) {
     cache_fd = lookupLibCacheFd(path);
     fd = cache_fd;
@@ -568,21 +636,27 @@ report_mapping(char *name, void *base, u
   if (entry)
     info->file_id = strndup(entry + strlen(name) + 1, 32);
 }
 
 #ifdef MOZ_OLD_LINKER
 extern "C" void simple_linker_init(void);
 #endif
 
-static mozglueresult
+static void
 loadGeckoLibs(const char *apkName)
 {
   chdir(getenv("GRE_HOME"));
 
+#ifdef MOZ_OLD_LINKER
+  struct stat status;
+  if (!stat(apkName, &status))
+    apk_mtime = status.st_mtime;
+#endif
+
   struct timeval t0, t1;
   gettimeofday(&t0, 0);
   struct rusage usage1;
   getrusage(RUSAGE_THREAD, &usage1);
   
   RefPtr<Zip> zip = new Zip(apkName);
 
 #ifdef MOZ_CRASHREPORTER
@@ -594,30 +668,38 @@ loadGeckoLibs(const char *apkName)
   sprintf(file, "%s!/libxpcom.so", apkName);
   __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
   // libxul.so is pulled from libxpcom.so, so we don't need to give the full path
   xul_handle = __wrap_dlopen("libxul.so", RTLD_GLOBAL | RTLD_LAZY);
   delete[] file;
 #else
 #define MOZLOAD(name) mozload("lib" name ".so", zip)
   MOZLOAD("mozalloc");
+  MOZLOAD("nspr4");
+  MOZLOAD("plc4");
+  MOZLOAD("plds4");
+  MOZLOAD("nssutil3");
+  MOZLOAD("nss3");
+  MOZLOAD("ssl3");
+  MOZLOAD("smime3");
   xul_handle = MOZLOAD("xul");
   MOZLOAD("xpcom");
+  MOZLOAD("nssckbi");
+  MOZLOAD("freebl3");
+  MOZLOAD("softokn3");
 #undef MOZLOAD
 #endif
 
 #ifdef MOZ_CRASHREPORTER
   free(file_ids);
   file_ids = NULL;
 #endif
 
-  if (!xul_handle) {
+  if (!xul_handle)
     __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libxul!");
-    return FAILURE;
-  }
 
 #define GETFUNC(name) f_ ## name = (name ## _t) __wrap_dlsym(xul_handle, "Java_org_mozilla_gecko_GeckoAppShell_" #name)
   GETFUNC(nativeInit);
   GETFUNC(notifyGeckoOfEvent);
   GETFUNC(processNextNativeEvent);
   GETFUNC(setSurfaceView);
   GETFUNC(setSoftwareLayerClient);
   GETFUNC(onResume);
@@ -651,34 +733,32 @@ loadGeckoLibs(const char *apkName)
   __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loaded libs in %ldms total, %ldms user, %ldms system, %ld faults",
                       (t1.tv_sec - t0.tv_sec)*1000 + (t1.tv_usec - t0.tv_usec)/1000, 
                       (usage2.ru_utime.tv_sec - usage1.ru_utime.tv_sec)*1000 + (usage2.ru_utime.tv_usec - usage1.ru_utime.tv_usec)/1000,
                       (usage2.ru_stime.tv_sec - usage1.ru_stime.tv_sec)*1000 + (usage2.ru_stime.tv_usec - usage1.ru_stime.tv_usec)/1000,
                       usage2.ru_majflt-usage1.ru_majflt);
 
   StartupTimeline_Record(LINKER_INITIALIZED, &t0);
   StartupTimeline_Record(LIBRARIES_LOADED, &t1);
-  return SUCCESS;
 }
 
-static int loadSQLiteLibs(const char *apkName)
+static void loadSQLiteLibs(const char *apkName)
 {
   chdir(getenv("GRE_HOME"));
 
 #ifdef MOZ_OLD_LINKER
-  if (!simple_linker_initialized) {
-    simple_linker_init();
-    simple_linker_initialized = true;
-  }
+  simple_linker_init();
+
+  struct stat status;
+  if (!stat(apkName, &status))
+    apk_mtime = status.st_mtime;
 #endif
 
   RefPtr<Zip> zip = new Zip(apkName);
-  if (!lib_mapping) {
-    lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping));
-  }
+  lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping));
 
 #ifdef MOZ_CRASHREPORTER
   file_ids = (char *)extractBuf("lib.id", zip);
 #endif
 
 #ifndef MOZ_OLD_LINKER
   char *file = new char[strlen(apkName) + sizeof("!/libmozsqlite3.so")];
   sprintf(file, "%s!/libmozsqlite3.so", apkName);
@@ -690,156 +770,54 @@ static int loadSQLiteLibs(const char *ap
 #undef MOZLOAD
 #endif
 
 #ifdef MOZ_CRASHREPORTER
   free(file_ids);
   file_ids = NULL;
 #endif
 
-  if (!sqlite_handle) {
+  if (!sqlite_handle)
     __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libmozsqlite3!");
-    return FAILURE;
-  }
 
   setup_sqlite_functions(sqlite_handle);
-  return SUCCESS;
-}
-
-static mozglueresult
-loadNSSLibs(const char *apkName)
-{
-  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "loadNSSLibs");
-  chdir(getenv("GRE_HOME"));
-
-#ifdef MOZ_OLD_LINKER
-  if (!simple_linker_initialized) {
-    simple_linker_init();
-    simple_linker_initialized = true;
-  }
-#endif
-
-  Zip *zip = new Zip(apkName);
-  if (!lib_mapping) {
-    lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping));
-  }
-
-#ifdef MOZ_CRASHREPORTER
-  file_ids = (char *)extractBuf("lib.id", zip);
-#endif
-
-#ifndef MOZ_OLD_LINKER
-  char *file = new char[strlen(apkName) + sizeof("!/libnss3.so")];
-  sprintf(file, "%s!/libnss3.so", apkName);
-  nss_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
-  delete [] file;
-
-  file = new char[strlen(apkName) + sizeof("!/libnspr4.so")];
-  sprintf(file, "%s!/libnspr4.so", apkName);
-  nspr_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
-  delete [] file;
-
-  file = new char[strlen(apkName) + sizeof("!/libplc4.so")];
-  sprintf(file, "%s!/libplc4.so", apkName);
-  plc_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
-  delete [] file;
-#else
-#define MOZLOAD(name) mozload("lib" name ".so", zip)
-  nspr_handle = MOZLOAD("nspr4");
-  plc_handle = MOZLOAD("plc4");
-  MOZLOAD("plds4");
-  MOZLOAD("nssutil3");
-  nss_handle = MOZLOAD("nss3");
-  MOZLOAD("ssl3");
-  MOZLOAD("smime3");
-  MOZLOAD("nssckbi");
-  MOZLOAD("freebl3");
-  MOZLOAD("softokn3");
-#undef MOZLOAD
-#endif
-
-  delete zip;
-
-#ifdef MOZ_CRASHREPORTER
-  free(file_ids);
-  file_ids = NULL;
-#endif
-
-  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "loadNSSLibs 2");
-  if (!nss_handle) {
-    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libnss3!");
-    return FAILURE;
-  }
-
-  if (!nspr_handle) {
-    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libnspr4!");
-    return FAILURE;
-  }
-
-  if (!plc_handle) {
-    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libplc4!");
-    return FAILURE;
-  }
-
-  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "loadNSSLibs 3");
-  return setup_nss_functions(nss_handle, nspr_handle, plc_handle);
 }
 
 extern "C" NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_loadGeckoLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName)
 {
   const char* str;
   // XXX: java doesn't give us true UTF8, we should figure out something
   // better to do here
   str = jenv->GetStringUTFChars(jApkName, NULL);
   if (str == NULL)
     return;
 
-  int res = loadGeckoLibs(str);
-  if (res != SUCCESS) {
-    JNI_Throw(jenv, "java/lang/Exception", "Error loading gecko libraries");
-  }
+  loadGeckoLibs(str);
   jenv->ReleaseStringUTFChars(jApkName, str);
 }
 
 extern "C" NS_EXPORT void JNICALL
-Java_org_mozilla_gecko_GeckoAppShell_loadSQLiteLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName) {
-  putenv("MOZ_LINKER_EXTRACT=1");
+Java_org_mozilla_gecko_GeckoAppShell_loadSQLiteLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName, jboolean jShouldExtract) {
+  if (jShouldExtract) {
+#ifdef MOZ_OLD_LINKER
+    extractLibs = 1;
+#else
+    putenv("MOZ_LINKER_EXTRACT=1");
+#endif
+  }
+
   const char* str;
   // XXX: java doesn't give us true UTF8, we should figure out something
   // better to do here
   str = jenv->GetStringUTFChars(jApkName, NULL);
   if (str == NULL)
     return;
 
-  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Load sqlite start\n");
-  mozglueresult rv = loadSQLiteLibs(str);
-  if (rv != SUCCESS) {
-      JNI_Throw(jenv, "java/lang/Exception", "Error loading sqlite libraries");
-  }
-  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Load sqlite done\n");
-  jenv->ReleaseStringUTFChars(jApkName, str);
-}
-
-extern "C" NS_EXPORT void JNICALL
-Java_org_mozilla_gecko_GeckoAppShell_loadNSSLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName) {
-  putenv("MOZ_LINKER_EXTRACT=1");
-  const char* str;
-  // XXX: java doesn't give us true UTF8, we should figure out something
-  // better to do here
-  str = jenv->GetStringUTFChars(jApkName, NULL);
-  if (str == NULL)
-    return;
-
-  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Load nss start\n");
-  mozglueresult rv = loadNSSLibs(str);
-  if (rv != SUCCESS) {
-    JNI_Throw(jenv, "java/lang/Exception", "Error loading nss libraries");
-  }
-  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Load nss done\n");
+  loadSQLiteLibs(str);
   jenv->ReleaseStringUTFChars(jApkName, str);
 }
 
 typedef void (*GeckoStart_t)(void *, const nsXREAppData *);
 
 extern "C" NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_nativeRun(JNIEnv *jenv, jclass jc, jstring jargs)
 {
@@ -853,49 +831,47 @@ Java_org_mozilla_gecko_GeckoAppShell_nat
   char *args = (char *) malloc(len + 1);
   jenv->GetStringUTFRegion(jargs, 0, len, args);
   args[len] = '\0';
   GeckoStart(args, &sAppData);
   free(args);
 }
 
 typedef int GeckoProcessType;
+typedef int nsresult;
 
-extern "C" NS_EXPORT mozglueresult
+extern "C" NS_EXPORT int
 ChildProcessInit(int argc, char* argv[])
 {
   int i;
   for (i = 0; i < (argc - 1); i++) {
     if (strcmp(argv[i], "-greomni"))
       continue;
 
     i = i + 1;
     break;
   }
 
 #ifdef MOZ_OLD_LINKER
   fillLibCache(argv[argc - 1]);
 #endif
-  if (loadNSSLibs(argv[i]) != SUCCESS) {
-    return FAILURE;
-  }
-  if (loadSQLiteLibs(argv[i]) != SUCCESS) {
-    return FAILURE;
-  }
-  if (loadGeckoLibs(argv[i]) != SUCCESS) {
-    return FAILURE;
-  }
+  loadSQLiteLibs(argv[i]);
+  loadGeckoLibs(argv[i]);
 
   // don't pass the last arg - it's only recognized by the lib cache
   argc--;
 
   typedef GeckoProcessType (*XRE_StringToChildProcessType_t)(char*);
-  typedef mozglueresult (*XRE_InitChildProcess_t)(int, char**, GeckoProcessType);
+  typedef nsresult (*XRE_InitChildProcess_t)(int, char**, GeckoProcessType);
   XRE_StringToChildProcessType_t fXRE_StringToChildProcessType =
     (XRE_StringToChildProcessType_t)__wrap_dlsym(xul_handle, "XRE_StringToChildProcessType");
   XRE_InitChildProcess_t fXRE_InitChildProcess =
     (XRE_InitChildProcess_t)__wrap_dlsym(xul_handle, "XRE_InitChildProcess");
 
   GeckoProcessType proctype = fXRE_StringToChildProcessType(argv[--argc]);
 
-  return fXRE_InitChildProcess(argc, argv, proctype);
+  nsresult rv = fXRE_InitChildProcess(argc, argv, proctype);
+  if (rv != 0)
+    return 1;
+
+  return 0;
 }
 
--- a/mozglue/android/APKOpen.h
+++ b/mozglue/android/APKOpen.h
@@ -32,42 +32,35 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef APKOpen_h
 #define APKOpen_h
 
-#include <jni.h>
-
 #ifndef NS_EXPORT
 #define NS_EXPORT __attribute__ ((visibility("default")))
 #endif
 
 struct mapping_info {
   char * name;
   char * file_id;
   uintptr_t base;
   size_t len;
   size_t offset;
 };
 
 const struct mapping_info * getLibraryMapping();
 
-static const int SUCCESS = 0;
-static const int FAILURE = 1;
-void JNI_Throw(JNIEnv* jenv, const char* classname, const char* msg);
-
 #define MAX_LIB_CACHE_ENTRIES 32
 #define MAX_LIB_CACHE_NAME_LEN 32
 
 struct lib_cache_info {
   char name[MAX_LIB_CACHE_NAME_LEN];
   int fd;
   uint32_t lib_size;
   void* buffer;
 };
 
 NS_EXPORT const struct lib_cache_info * getLibraryCache();
 
-
 #endif /* APKOpen_h */
--- a/mozglue/android/Makefile.in
+++ b/mozglue/android/Makefile.in
@@ -50,47 +50,24 @@ STL_FLAGS=
 DEFINES += \
   -DANDROID_PACKAGE_NAME='"$(ANDROID_PACKAGE_NAME)"' \
   $(NULL)
 
 CPPSRCS = \
   nsGeckoUtils.cpp \
   APKOpen.cpp \
   SQLiteBridge.cpp \
-	NSSBridge.cpp \
   $(NULL)
 
 LOCAL_INCLUDES += -I$(DEPTH)/build
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
 
 LOCAL_INCLUDES += -I$(srcdir)/../linker
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/components/startup
 LOCAL_INCLUDES += -I$(topsrcdir)/db/sqlite3/src
-LOCAL_INCLUDES += -I$(topsrcdir)/base/src
-LOCAL_INCLUDES += -I$(topsrcdir)/nsprpub/lib/ds
-LOCAL_INCLUDES += -I$(topsrcdir)/nsprpub/lib/libc/include
-LOCAL_INCLUDES += -I$(topsrcdir)/nsprpub/pr/include
-LOCAL_INCLUDES += -I$(topsrcdir)/ipc/chromium/src/base/third_party/nspr
-LOCAL_INCLUDES += -I$(topsrcdir)/ipc/chromium/src
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/nss
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/util
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/softoken
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/pk11wrap
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/cmd/ecperf
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/pkcs7
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/certdb
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/cryptohi
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/dev
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/base
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/pki
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/smime
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/freebl/
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/lib/ssl
-LOCAL_INCLUDES += -I$(topsrcdir)/security/nss/cmd/lib/
-
 ifdef MOZ_OLD_LINKER
 DEFINES += -DMOZ_OLD_LINKER
 LOCAL_INCLUDES += -I$(topsrcdir)/other-licenses/android
 ifeq ($(CPU_ARCH),arm)
 DEFINES += -DANDROID_ARM_LINKER
 endif
 endif
 
deleted file mode 100644
--- a/mozglue/android/NSSBridge.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/* 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/. */
-
-#include <stdlib.h>
-#include "dlfcn.h"
-#include "NSSBridge.h"
-#include "APKOpen.h"
-#ifdef ANDROID
-#include <jni.h>
-#include <android/log.h>
-#endif
-
-#ifndef MOZ_OLD_LINKER
-#include "ElfLoader.h"
-#endif
-
-#define DEBUG 1
-
-#ifdef DEBUG
-#define LOG(x...) __android_log_print(ANDROID_LOG_INFO, "GeckoJNI", x)
-#else
-#define LOG(x...) printf(x);
-#endif
-
-static bool initialized = false;
-
-#define NSS_WRAPPER_INT(name) name ## _t f_ ## name;
-NSS_WRAPPER_INT(NSS_Initialize)
-NSS_WRAPPER_INT(NSS_Shutdown)
-NSS_WRAPPER_INT(SECITEM_ZfreeItem)
-NSS_WRAPPER_INT(PK11SDR_Encrypt)
-NSS_WRAPPER_INT(PK11SDR_Decrypt)
-NSS_WRAPPER_INT(PK11_GetInternalKeySlot)
-NSS_WRAPPER_INT(PK11_NeedUserInit)
-NSS_WRAPPER_INT(PK11_InitPin)
-NSS_WRAPPER_INT(PR_ErrorToString)
-NSS_WRAPPER_INT(PR_GetError)
-NSS_WRAPPER_INT(PR_Free)
-NSS_WRAPPER_INT(PL_Base64Encode)
-NSS_WRAPPER_INT(PL_Base64Decode)
-NSS_WRAPPER_INT(PL_strfree)
-
-int
-setup_nss_functions(void *nss_handle,
-                        void *nspr_handle,
-                        void *plc_handle)
-{
-  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "setup nss 1");
-  if (nss_handle == NULL || nspr_handle == NULL || plc_handle == NULL) {
-    LOG("missing handle\n");
-    return FAILURE;
-  }
-#define GETFUNC(name) f_ ## name = (name ## _t) __wrap_dlsym(nss_handle, #name); \
-                      if (!f_ ##name) return FAILURE;
-  GETFUNC(NSS_Initialize);
-  GETFUNC(NSS_Shutdown);
-  GETFUNC(PK11SDR_Encrypt);
-  GETFUNC(PK11SDR_Decrypt);
-  GETFUNC(PK11_GetInternalKeySlot);
-  GETFUNC(PK11_NeedUserInit);
-  GETFUNC(PK11_InitPin);
-  GETFUNC(SECITEM_ZfreeItem);
-#undef GETFUNC
-#define NSPRFUNC(name) f_ ## name = (name ## _t) __wrap_dlsym(nspr_handle, #name); \
-                       if (!f_ ##name) return FAILURE;
-  NSPRFUNC(PR_ErrorToString);
-  NSPRFUNC(PR_GetError);
-  NSPRFUNC(PR_Free);
-#undef NSPRFUNC
-#define PLCFUNC(name) f_ ## name = (name ## _t) __wrap_dlsym(plc_handle, #name); \
-                      if (!f_ ##name) return FAILURE;
-  PLCFUNC(PL_Base64Encode);
-  PLCFUNC(PL_Base64Decode);
-  PLCFUNC(PL_strfree);
-#undef PLCFUNC
-
-  return SUCCESS;
-}
-
-/* Throws the current NSS error. */
-static void
-throwError(JNIEnv* jenv, const char * funcString) {
-    char *msg;
-
-    PRErrorCode perr = f_PR_GetError();
-    char * errString = f_PR_ErrorToString(perr, 0);
-    asprintf(&msg, "%s returned error %d: %s\n", funcString, perr, errString);
-    LOG("Throwing error: %s\n", msg);
-
-    JNI_Throw(jenv, "java/lang/Exception", msg);
-    free(msg);
-    LOG("Error thrown\n");
-}
-
-extern "C" NS_EXPORT jstring JNICALL
-Java_org_mozilla_gecko_NSSBridge_nativeEncrypt(JNIEnv* jenv, jclass,
-                                               jstring jPath,
-                                               jstring jValue)
-{
-    jstring ret = jenv->NewStringUTF("");
-
-    const char* path;
-    path = jenv->GetStringUTFChars(jPath, NULL);
-
-    const char* value;
-    value = jenv->GetStringUTFChars(jValue, NULL);
-
-    char* result;
-    SECStatus rv = doCrypto(jenv, path, value, &result, true);
-    if (rv == SECSuccess) {
-      ret = jenv->NewStringUTF(result);
-      free(result);
-    }
-
-    jenv->ReleaseStringUTFChars(jValue, value);
-    jenv->ReleaseStringUTFChars(jPath, path);
-
-    return ret;
-}
-
-extern "C" NS_EXPORT jstring JNICALL
-Java_org_mozilla_gecko_NSSBridge_nativeDecrypt(JNIEnv* jenv, jclass,
-                                               jstring jPath,
-                                               jstring jValue)
-{
-    jstring ret = jenv->NewStringUTF("");
-
-    const char* path;
-    path = jenv->GetStringUTFChars(jPath, NULL);
-
-    const char* value;
-    value = jenv->GetStringUTFChars(jValue, NULL);
-
-    char* result;
-    SECStatus rv = doCrypto(jenv, path, value, &result, false);
-    if (rv == SECSuccess) {
-      ret = jenv->NewStringUTF(result);
-      free(result);
-    }
-
-    jenv->ReleaseStringUTFChars(jValue, value);
-    jenv->ReleaseStringUTFChars(jPath, path);
-
-    return ret;
-}
-
-
-/* Encrypts or decrypts a string. result should be freed with free() when done */
-SECStatus
-doCrypto(JNIEnv* jenv, const char *path, const char *value, char** result, bool encrypt)
-{
-    SECStatus rv;
-    PK11SlotInfo *slot;
-    if (!initialized) {
-      LOG("initialize crypto %s\n", path);
-      rv = f_NSS_Initialize(path, "", "", "secmod.db", NSS_INIT_NOROOTINIT);
-      if (rv != SECSuccess) {
-          throwError(jenv, "NSS_Initialize");
-          return rv;
-      }
-      initialized = true;
-    }
-
-    slot = f_PK11_GetInternalKeySlot();
-    if (!slot) {
-      throwError(jenv, "PK11_GetInternalKeySlot");
-      return SECFailure;
-    }
-
-    if (f_PK11_NeedUserInit(slot)) {
-      LOG("Initializing key3.db with default blank password.");
-      rv = f_PK11_InitPin(slot, NULL, NULL);
-      if (rv != SECSuccess) {
-        throwError(jenv, "PK11_InitPin");
-        return rv;
-      }
-    }
-
-    SECItem request;
-    SECItem reply;
-
-    reply.data = 0;
-    reply.len = 0;
-
-    if (encrypt) {
-      LOG("encrypting %s\n", value);
-      request.data = (unsigned char*)value;
-      request.len = strlen(value);
-
-      SECItem keyid;
-      keyid.data = 0;
-      keyid.len = 0;
-      rv = f_PK11SDR_Encrypt(&keyid, &request, &reply, NULL);
-
-      if (rv != SECSuccess) {
-        throwError(jenv, "PK11SDR_Encrypt");
-        goto done;
-      }
-
-      rv = encode(reply.data, reply.len, result);
-      if (rv != SECSuccess) {
-          throwError(jenv, "encode");
-          goto done;
-      }
-      LOG("encrypted %s\n", *result);
-    } else {
-      LOG("decoding %s\n", value);
-      rv = decode(value, &request.data, (PRInt32*)&request.len);
-      if (rv != SECSuccess) {
-          throwError(jenv, "decode");
-          return rv;
-      }
-
-      rv = f_PK11SDR_Decrypt(&request, &reply, NULL);
-      if (rv != SECSuccess) {
-        throwError(jenv, "PK11SDR_Decrypt");
-        goto done;
-      }
-
-      *result = (char *)malloc(reply.len);
-      (*result)[reply.len] = '\0';
-      strncpy(*result, (char *)reply.data, reply.len);
-      //asprintf(result, "%s", (char *)reply.data);
-
-      LOG("decoded %i letters %s\n", reply.len, *result);
-      free(request.data);
-    }
-
-done:
-    f_SECITEM_ZfreeItem(&reply, false);
-    return rv;
-}
-
-/*
- * Base64 encodes the data passed in. The caller must deallocate _retval using free();
- */
-SECStatus
-encode(const unsigned char *data, PRInt32 dataLen, char **_retval)
-{
-  SECStatus rv = SECSuccess;
-  char *encoded = f_PL_Base64Encode((const char *)data, dataLen, NULL);
-  if (!encoded)
-    rv = SECFailure;
-  if (!*encoded)
-    rv = SECFailure;
-
-  if (rv == SECSuccess) {
-    *_retval = (char *)malloc(strlen(encoded));
-    strcpy(*_retval, encoded);
-  }
-
-  if (encoded) {
-    f_PR_Free(encoded);
-  }
-
-  return rv;
-}
-
-/*
- * Base64 decodes the data passed in. The caller must deallocate result using free();
- */
-SECStatus
-decode(const char *data, unsigned char **result, PRInt32 *length)
-{
-  SECStatus rv = SECSuccess;
-  PRUint32 len = strlen(data);
-  int adjust = 0;
-
-  /* Compute length adjustment */
-  if (len > 0 && data[len-1] == '=') {
-    adjust++;
-    if (data[len-2] == '=') adjust++;
-  }
-
-  char *decoded;
-  decoded = f_PL_Base64Decode(data, len, NULL);
-  if (!decoded) {
-    return SECFailure;
-  }
-
-  LOG("xxx Decoded: %s\n", decoded);
-
-  if (!*decoded) {
-    return SECFailure;
-  }
-
-  *length = (len*3)/4 - adjust;
-  *result = (unsigned char*)malloc((size_t)len);
-
-  if (!*result) {
-    rv = SECFailure;
-  } else {
-    memcpy((char*)*result, decoded, len);
-  }
-  f_PR_Free(decoded);
-  return rv;
-}
-
-
deleted file mode 100644
--- a/mozglue/android/NSSBridge.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef NSSBridge_h
-#define NSSBridge_h
-
-#include "nss.h"
-#include "seccomon.h"
-#include "secmodt.h"
-#include "secutil.h"
-#include "pk11func.h"
-#include <jni.h>
-
-int setup_nss_functions(void *nss_handle, void *nssutil_handle, void *plc_handle);
-
-#define NSS_WRAPPER(name, return_type, args...) \
-typedef return_type (*name ## _t)(args);  \
-extern name ## _t f_ ## name;
-
-NSS_WRAPPER(NSS_Initialize, SECStatus, const char*, const char*, const char*, const char*, PRUint32)
-NSS_WRAPPER(NSS_Shutdown, void, void)
-NSS_WRAPPER(PK11SDR_Encrypt, SECStatus, SECItem *, SECItem *, SECItem *, void *)
-NSS_WRAPPER(PK11SDR_Decrypt, SECStatus, SECItem *, SECItem *, void *)
-NSS_WRAPPER(SECITEM_ZfreeItem, void, SECItem*, PRBool)
-NSS_WRAPPER(PR_ErrorToString, char *, PRErrorCode, PRLanguageCode)
-NSS_WRAPPER(PR_GetError, PRErrorCode, void)
-NSS_WRAPPER(PR_Free, PRErrorCode, char *)
-NSS_WRAPPER(PL_Base64Encode, char*, const char*, PRUint32, char*)
-NSS_WRAPPER(PL_Base64Decode, char*, const char*, PRUint32, char*)
-NSS_WRAPPER(PL_strfree, void, char*)
-NSS_WRAPPER(PK11_GetInternalKeySlot, PK11SlotInfo *, void)
-NSS_WRAPPER(PK11_NeedUserInit, PRBool, PK11SlotInfo *)
-NSS_WRAPPER(PK11_InitPin, SECStatus, PK11SlotInfo*, const char*, const char*)
-
-bool setPassword(PK11SlotInfo *slot);
-SECStatus doCrypto(JNIEnv* jenv, const char *path, const char *value, char** result, bool doEncrypt);
-SECStatus encode(const unsigned char *data, PRInt32 dataLen, char **_retval);
-SECStatus decode(const char *data, unsigned char **result, PRInt32 * _retval);
-#endif /* NSS_h */
--- a/mozglue/android/SQLiteBridge.cpp
+++ b/mozglue/android/SQLiteBridge.cpp
@@ -97,16 +97,31 @@ static jclass stringClass;
 static jclass objectClass;
 static jclass byteBufferClass;
 static jclass cursorClass;
 static jmethodID jByteBufferAllocateDirect;
 static jmethodID jCursorConstructor;
 static jmethodID jCursorAddRow;
 
 static void
+JNI_Throw(JNIEnv* jenv, const char* name, const char* msg)
+{
+    jclass cls = jenv->FindClass(name);
+    if (cls == NULL) {
+        LOG("Couldn't find exception class (or exception pending)\n");
+        return;
+    }
+    int rc = jenv->ThrowNew(cls, msg);
+    if (rc < 0) {
+        LOG("Error throwing exception\n");
+    }
+    jenv->DeleteLocalRef(cls);
+}
+
+static void
 JNI_Setup(JNIEnv* jenv)
 {
     if (initialized) return;
 
     jclass lObjectClass       = jenv->FindClass("java/lang/Object");
     jclass lStringClass       = jenv->FindClass("java/lang/String");
     jclass lByteBufferClass   = jenv->FindClass("java/nio/ByteBuffer");
     jclass lCursorClass       = jenv->FindClass("org/mozilla/gecko/sqlite/MatrixBlobCursor");
--- a/other-licenses/android/dlfcn.c
+++ b/other-licenses/android/dlfcn.c
@@ -38,26 +38,30 @@ static const char *dl_errors[] = {
     [DL_ERR_SYMBOL_NOT_FOUND] = "Symbol not found",
     [DL_ERR_SYMBOL_NOT_GLOBAL] = "Symbol is not global",
 };
 
 #define likely(expr)   __builtin_expect (expr, 1)
 #define unlikely(expr) __builtin_expect (expr, 0)
 
 static pthread_mutex_t dl_lock = PTHREAD_MUTEX_INITIALIZER;
+extern int extractLibs;
 
 static void set_dlerror(int err)
 {
     format_buffer(dl_err_buf, sizeof(dl_err_buf), "%s: %s", dl_errors[err],
              linker_get_error());
     dl_err_str = (const char *)&dl_err_buf[0];
 }
 
 void *__wrap_dlopen(const char *filename, int flag)
 {
+    if (extractLibs)
+        return dlopen(filename, flag);
+
     soinfo *ret;
 
     pthread_mutex_lock(&dl_lock);
     ret = find_library(filename);
     if (unlikely(ret == NULL)) {
         set_dlerror(DL_ERR_CANNOT_LOAD_LIBRARY);
     } else {
         ret->refcount++;
@@ -79,23 +83,29 @@ void *moz_mapped_dlopen(const char *file
         ret->refcount++;
     }
     pthread_mutex_unlock(&dl_lock);
     return ret;
 }
 
 const char *__wrap_dlerror(void)
 {
+    if (extractLibs)
+        return dlerror();
+
     const char *tmp = dl_err_str;
     dl_err_str = NULL;
     return (const char *)tmp;
 }
 
 void *__wrap_dlsym(void *handle, const char *symbol)
 {
+    if (extractLibs)
+        return dlsym(handle, symbol);
+
     soinfo *found;
     Elf32_Sym *sym;
     unsigned bind;
 
     pthread_mutex_lock(&dl_lock);
 
     if(unlikely(handle == 0)) { 
         set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE);
@@ -168,16 +178,19 @@ int __wrap_dladdr(void *addr, Dl_info *i
 
     pthread_mutex_unlock(&dl_lock);
 
     return ret;
 }
 
 int __wrap_dlclose(void *handle)
 {
+    if (extractLibs)
+        return dlclose(handle);
+
     pthread_mutex_lock(&dl_lock);
     (void)unload_library((soinfo*)handle);
     pthread_mutex_unlock(&dl_lock);
     return 0;
 }
 
 #if defined(ANDROID_ARM_LINKER)
 //                     0000000 00011111 111112 22222222 2333333 333344444444445555555