Bug 990130 - Fall back to full path of library on failure. r=mfinkle
authorRichard Newman <rnewman@mozilla.com>
Wed, 16 Apr 2014 10:57:59 -0700
changeset 197409 be14df51e362a840d94fc7826edcfc4639dc300d
parent 197408 5cf9041418fa3033411ef2d3fcc84efe030c1c32
child 197410 59f4f732f6d7969faff8894cbb97949f38d76aab
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs990130
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 990130 - Fall back to full path of library on failure. r=mfinkle
mobile/android/base/background/nativecode/NativeCrypto.java
mobile/android/base/db/PasswordsProvider.java
mobile/android/base/mozglue/GeckoLoader.java.in
--- a/mobile/android/base/background/nativecode/NativeCrypto.java
+++ b/mobile/android/base/background/nativecode/NativeCrypto.java
@@ -1,22 +1,40 @@
 /* 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.background.nativecode;
 
+import java.security.GeneralSecurityException;
+
+import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.mozglue.RobocopTarget;
 
-import java.security.GeneralSecurityException;
+import android.util.Log;
 
 @RobocopTarget
 public class NativeCrypto {
   static {
-    System.loadLibrary("mozglue");
+    try {
+      System.loadLibrary("mozglue");
+    } catch (UnsatisfiedLinkError e) {
+      Log.wtf("NativeCrypto", "Couldn't load mozglue. Trying /data/app-lib path.");
+      try {
+        System.load("/data/app-lib/" + AppConstants.ANDROID_PACKAGE_NAME + "/libmozglue.so");
+      } catch (Throwable ee) {
+          try {
+            Log.wtf("NativeCrypto", "Couldn't load mozglue: " + ee + ". Trying /data/data path.");
+            System.load("/data/data/" + AppConstants.ANDROID_PACKAGE_NAME + "/lib/libmozglue.so");
+          } catch (UnsatisfiedLinkError eee) {
+              Log.wtf("NativeCrypto", "Failed every attempt to load mozglue. Giving up.");
+              throw new RuntimeException("Unable to load mozglue", eee);
+          }
+      }
+    }
   }
 
   /**
    * Wrapper to perform PBKDF2-HMAC-SHA-256 in native code.
    */
   public native static byte[] pbkdf2SHA256(byte[] password, byte[] salt, int c, int dkLen)
       throws GeneralSecurityException;
 
--- a/mobile/android/base/db/PasswordsProvider.java
+++ b/mobile/android/base/db/PasswordsProvider.java
@@ -1,27 +1,27 @@
 /* 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.db;
 
-import java.lang.IllegalArgumentException;
 import java.util.HashMap;
+
 import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.NSSBridge;
-import org.mozilla.gecko.db.DBUtils;
+import org.mozilla.gecko.db.BrowserContract.DeletedPasswords;
 import org.mozilla.gecko.db.BrowserContract.Passwords;
-import org.mozilla.gecko.db.BrowserContract.DeletedPasswords;
-import org.mozilla.gecko.db.BrowserContract;
+import org.mozilla.gecko.mozglue.GeckoLoader;
 import org.mozilla.gecko.sqlite.MatrixBlobCursor;
 import org.mozilla.gecko.sqlite.SQLiteBridge;
 import org.mozilla.gecko.sync.Utils;
+
 import android.content.ContentValues;
 import android.content.Intent;
 import android.content.UriMatcher;
 import android.database.Cursor;
 import android.net.Uri;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -71,17 +71,20 @@ public class PasswordsProvider extends S
         PASSWORDS_PROJECTION_MAP.put(Passwords.TIMES_USED, Passwords.TIMES_USED);
 
         URI_MATCHER.addURI(BrowserContract.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");
+
+        // We don't use .loadMozGlue because we're in a different process,
+        // and we just want to reuse code rather than use the loader lock etc.
+        GeckoLoader.doLoadLibrary("mozglue");
     }
 
     public PasswordsProvider() {
         super(LOG_TAG);
     }
 
     @Override
     protected String getDBName(){
--- a/mobile/android/base/mozglue/GeckoLoader.java.in
+++ b/mobile/android/base/mozglue/GeckoLoader.java.in
@@ -1,8 +1,9 @@
+#filter substitution
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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.mozglue;
 
 import android.content.Context;
@@ -15,16 +16,19 @@ import java.io.File;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.text.NumberFormat;
 import java.util.Locale;
 
 public final class GeckoLoader {
     private static final String LOGTAG = "GeckoLoader";
 
+    // This matches AppConstants, but we're built earlier.
+    private static final String ANDROID_PACKAGE_NAME = "@ANDROID_PACKAGE_NAME@";
+
     private static volatile Intent sIntent;
     private static File sCacheFile;
     private static File sGREDir;
 
     private static final Object sLibLoadingLock = new Object();
     // Must hold sLibLoadingLock while accessing the following boolean variables.
     private static boolean sSQLiteLibsLoaded;
     private static boolean sNSSLibsLoaded;
@@ -254,25 +258,44 @@ public final class GeckoLoader {
             sNSSLibsLoaded = true;
         }
 
         loadMozGlue();
         loadLibsSetup(context);
         loadNSSLibsNative(apkName, false);
     }
 
+    public static void doLoadLibrary(final String lib) {
+        try {
+            System.loadLibrary(lib);
+        } catch (UnsatisfiedLinkError e) {
+            Log.wtf(LOGTAG, "Couldn't load " + lib + ". Trying /data/app-lib path.");
+            try {
+                System.load("/data/app-lib/" + ANDROID_PACKAGE_NAME + "/lib" + lib + ".so");
+            } catch (Throwable ee) {
+                try {
+                    Log.wtf(LOGTAG, "Couldn't load " + lib + ": " + ee + ". Trying /data/data path.");
+                    System.load("/data/data/" + ANDROID_PACKAGE_NAME + "/lib/lib" + lib + ".so");
+                } catch (Throwable eee) {
+                    Log.wtf(LOGTAG, "Failed every attempt to load " + lib + ". Giving up.");
+                    throw new RuntimeException("Unable to load " + lib, eee);
+                }
+            }
+        }
+    }
+
     public static void loadMozGlue() {
         synchronized (sLibLoadingLock) {
             if (sMozGlueLoaded) {
                 return;
             }
             sMozGlueLoaded = true;
         }
 
-        System.loadLibrary("mozglue");
+        doLoadLibrary("mozglue");
     }
 
     public static void loadGeckoLibs(Context context, String apkName) {
         loadLibsSetup(context);
         loadGeckoLibsNative(apkName);
     }
 
     private static void setupLocaleEnvironment() {