Merge "Fix secondary ABI instrumetion" into nyc-dev
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 061d924..e54edf2 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4957,6 +4957,31 @@
         }
     }
 
+    /**
+     * Returns the correct library directory for the current ABI.
+     * <p>
+     * If we're dealing with a multi-arch application that has both 32 and 64 bit shared
+     * libraries, we might need to choose the secondary depending on what the current
+     * runtime's instruction set is.
+     */
+    private String getInstrumentationLibrary(ApplicationInfo appInfo, InstrumentationInfo insInfo) {
+        if (appInfo.primaryCpuAbi != null && appInfo.secondaryCpuAbi != null) {
+            // Get the instruction set supported by the secondary ABI. In the presence
+            // of a native bridge this might be different than the one secondary ABI used.
+            String secondaryIsa =
+                    VMRuntime.getInstructionSet(appInfo.secondaryCpuAbi);
+            final String secondaryDexCodeIsa =
+                    SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
+            secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
+
+            final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
+            if (runtimeIsa.equals(secondaryIsa)) {
+                return insInfo.secondaryNativeLibraryDir;
+            }
+        }
+        return insInfo.nativeLibraryDir;
+    }
+
     private void handleBindApplication(AppBindData data) {
         // Register the UI Thread as a sensitive thread to the runtime.
         VMRuntime.registerSensitiveThread();
@@ -5130,7 +5155,7 @@
             mInstrumentationPackageName = ii.packageName;
             mInstrumentationAppDir = ii.sourceDir;
             mInstrumentationSplitAppDirs = ii.splitSourceDirs;
-            mInstrumentationLibDir = ii.nativeLibraryDir;
+            mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
             mInstrumentedAppDir = data.info.getAppDir();
             mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
             mInstrumentedLibDir = data.info.getLibDir();
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
index cbeed35..9d88cdd 100644
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -66,13 +66,12 @@
     /** {@hide} */
     public String credentialProtectedDataDir;
 
-    /**
-     * Full path to the directory where the native JNI libraries are stored.
-     * 
-     * {@hide}
-     */
+    /** {@hide} Full path to the directory containing primary ABI native libraries. */
     public String nativeLibraryDir;
 
+    /** {@hide} Full path to the directory containing secondary ABI native libraries. */
+    public String secondaryNativeLibraryDir;
+
     /**
      * Specifies whether or not this instrumentation will handle profiling.
      */
@@ -95,6 +94,7 @@
         deviceProtectedDataDir = orig.deviceProtectedDataDir;
         credentialProtectedDataDir = orig.credentialProtectedDataDir;
         nativeLibraryDir = orig.nativeLibraryDir;
+        secondaryNativeLibraryDir = orig.secondaryNativeLibraryDir;
         handleProfiling = orig.handleProfiling;
         functionalTest = orig.functionalTest;
     }
@@ -120,6 +120,7 @@
         dest.writeString(deviceProtectedDataDir);
         dest.writeString(credentialProtectedDataDir);
         dest.writeString(nativeLibraryDir);
+        dest.writeString(secondaryNativeLibraryDir);
         dest.writeInt((handleProfiling == false) ? 0 : 1);
         dest.writeInt((functionalTest == false) ? 0 : 1);
     }
@@ -145,6 +146,7 @@
         deviceProtectedDataDir = source.readString();
         credentialProtectedDataDir = source.readString();
         nativeLibraryDir = source.readString();
+        secondaryNativeLibraryDir = source.readString();
         handleProfiling = source.readInt() != 0;
         functionalTest = source.readInt() != 0;
     }
@@ -160,5 +162,6 @@
         ai.deviceProtectedDataDir = deviceProtectedDataDir;
         ai.credentialProtectedDataDir = credentialProtectedDataDir;
         ai.nativeLibraryDir = nativeLibraryDir;
+        ai.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
     }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 034b057..da8799d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8727,9 +8727,8 @@
                 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
                 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
 
-                // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
-                // need other information about the application, like the ABI and what not ?
                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
+                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
                 mInstrumentation.put(a.getComponentName(), a);
                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
                     if (r == null) {