Fix multiArch installs where only some archs are available.

In this case, NO_MATCHING_ABIS shouldn't result in a failure
when we're trying to match against one of SUPPORTED_32_BIT_ABIS
or SUPPORTED_64_BIT_ABIS.

There shouldn't be a general requirement that packages must
contain both 32 and 64 bit libs because it might legitimately
exclude one or the other for reasons such as compatibility
etc.

bug: 16299358

Change-Id: I5f66b0a54b63b93b36371b584e9cf6bed07c507a
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index cfba19c..2215182 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5428,11 +5428,8 @@
                         }
                     }
 
-                    if (abi32 < 0 && abi32 != PackageManager.NO_NATIVE_LIBRARIES) {
-                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                                "Error unpackaging 32 bit native libs for multiarch app, errorCode="
-                                + abi32);
-                    }
+                    maybeThrowExceptionForMultiArchCopy(
+                            "Error unpackaging 32 bit native libs for multiarch app.", abi32);
 
                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
                         if (isAsec) {
@@ -5443,11 +5440,8 @@
                         }
                     }
 
-                    if (abi64 < 0 && abi64 != PackageManager.NO_NATIVE_LIBRARIES) {
-                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                                "Error unpackaging 64 bit native libs for multiarch app, errorCode="
-                                + abi32);
-                    }
+                    maybeThrowExceptionForMultiArchCopy(
+                            "Error unpackaging 64 bit native libs for multiarch app.", abi64);
 
                     if (abi64 >= 0) {
                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
@@ -6240,9 +6234,6 @@
             if (info.primaryCpuAbi != null) {
                 info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
                         VMRuntime.getInstructionSet(info.primaryCpuAbi)).getAbsolutePath();
-            } else {
-                Slog.w(TAG, "Package " + info.packageName
-                        + " missing ABI; unable to derive nativeLibraryDir");
             }
         } else {
             info.nativeLibraryDir = info.nativeLibraryRootDir;
@@ -9264,29 +9255,13 @@
                     if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
                         copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot,
                                 Build.SUPPORTED_32_BIT_ABIS, true /* use isa specific subdirs */);
-                        if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
-                            Slog.w(TAG, "Failure copying 32 bit native libraries [errorCode=" + copyRet + "]");
-                            return copyRet;
-                        }
-                    }
-
-                    if (DEBUG_ABI_SELECTION && copyRet >= 0) {
-                        Log.d(TAG, "Installed 32 bit libraries under: " + codeFile + " abi=" +
-                                Build.SUPPORTED_32_BIT_ABIS[copyRet]);
+                        maybeThrowExceptionForMultiArchCopy("Failure copying 32 bit native libraries", copyRet);
                     }
 
                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
                         copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot,
                                 Build.SUPPORTED_64_BIT_ABIS, true /* use isa specific subdirs */);
-                        if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
-                            Slog.w(TAG, "Failure copying 64 bit native libraries [errorCode=" + copyRet + "]");
-                            return copyRet;
-                        }
-                    }
-
-                    if (DEBUG_ABI_SELECTION && copyRet >= 0) {
-                        Log.d(TAG, "Installed 64 bit libraries under: " + codeFile + " abi=" +
-                                Build.SUPPORTED_64_BIT_ABIS[copyRet]);
+                        maybeThrowExceptionForMultiArchCopy("Failure copying 64 bit native libraries", copyRet);
                     }
                 } else {
                     String[] abiList = (abiOverride != null) ?
@@ -9303,14 +9278,13 @@
                         Slog.w(TAG, "Failure copying native libraries [errorCode=" + copyRet + "]");
                         return copyRet;
                     }
-
-                    if (DEBUG_ABI_SELECTION && copyRet >= 0) {
-                        Log.d(TAG, "Installed libraries under: " + codeFile + " abi=" + abiList[copyRet]);
-                    }
                 }
             } catch (IOException e) {
                 Slog.e(TAG, "Copying native libraries failed", e);
                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+            } catch (PackageManagerException pme) {
+                Slog.e(TAG, "Copying native libraries failed", pme);
+                ret = pme.error;
             } finally {
                 IoUtils.closeQuietly(handle);
             }
@@ -9459,6 +9433,16 @@
         return !asecPath.startsWith(mAsecInternalPath);
     }
 
+    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
+            PackageManagerException {
+        if (copyRet < 0) {
+            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
+                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
+                throw new PackageManagerException(copyRet, message);
+            }
+        }
+    }
+
     /**
      * Extract the MountService "container ID" from the full code path of an
      * .apk.