Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23b4faf6 authored by Xavier Ducrohet's avatar Xavier Ducrohet
Browse files

Use reflection to figure out a readable string from install error code.

Instead of a switch that needs to be maintained, the code now
look for public static final int fields in PackageManager
whose names start with INSTALL_FAILED or INSTALL_PARSE_FAILED.

If their int value match the error code, the name of the field
is used as a human readable error string.

Change-Id: If58ddc4d9ccc40a9a8aaec9de4cc7e4931db0292
parent a0cad2f5
Loading
Loading
Loading
Loading
+74 −127
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -498,92 +500,37 @@ public final class Pm {
        }
    }

    /**
     * Converts a failure code into a string by using reflection to find a matching constant
     * in PackageManager.
     */
    private String installFailureToString(int result) {
        String s;
        switch (result) {
        case PackageManager.INSTALL_FAILED_ALREADY_EXISTS:
            s = "INSTALL_FAILED_ALREADY_EXISTS";
            break;
        case PackageManager.INSTALL_FAILED_INVALID_APK:
            s = "INSTALL_FAILED_INVALID_APK";
            break;
        case PackageManager.INSTALL_FAILED_INVALID_URI:
            s = "INSTALL_FAILED_INVALID_URI";
            break;
        case PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE:
            s = "INSTALL_FAILED_INSUFFICIENT_STORAGE";
            break;
        case PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE:
            s = "INSTALL_FAILED_DUPLICATE_PACKAGE";
            break;
        case PackageManager.INSTALL_FAILED_NO_SHARED_USER:
            s = "INSTALL_FAILED_NO_SHARED_USER";
            break;
        case PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE:
            s = "INSTALL_FAILED_UPDATE_INCOMPATIBLE";
            break;
        case PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE:
            s = "INSTALL_FAILED_SHARED_USER_INCOMPATIBLE";
            break;
        case PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY:
            s = "INSTALL_FAILED_MISSING_SHARED_LIBRARY";
            break;
        case PackageManager.INSTALL_FAILED_DEXOPT:
            s = "INSTALL_FAILED_DEXOPT";
            break;
        case PackageManager.INSTALL_FAILED_OLDER_SDK:
            s = "INSTALL_FAILED_OLDER_SDK";
            break;
        case PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER:
            s = "INSTALL_FAILED_CONFLICTING_PROVIDER";
            break;
        case PackageManager.INSTALL_FAILED_NEWER_SDK:
            s = "INSTALL_FAILED_NEWER_SDK";
            break;
        case PackageManager.INSTALL_FAILED_TEST_ONLY:
            s = "INSTALL_FAILED_TEST_ONLY";
            break;
        case PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE:
            s = "INSTALL_FAILED_CPU_ABI_INCOMPATIBLE";
            break;
        case PackageManager.INSTALL_FAILED_MISSING_FEATURE:
            s = "INSTALL_FAILED_MISSING_FEATURE";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_NOT_APK:
            s = "INSTALL_PARSE_FAILED_NOT_APK";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST:
            s = "INSTALL_PARSE_FAILED_BAD_MANIFEST";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION:
            s = "INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES:
            s = "INSTALL_PARSE_FAILED_NO_CERTIFICATES";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES:
            s = "INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING:
            s = "INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME:
            s = "INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID:
            s = "INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED:
            s = "INSTALL_PARSE_FAILED_MANIFEST_MALFORMED";
            break;
        case PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY:
            s = "INSTALL_PARSE_FAILED_MANIFEST_EMPTY";
            break;
        default:
            s = Integer.toString(result);
        break;
        Field[] fields = PackageManager.class.getFields();
        for (Field f: fields) {
            if (f.getType() == int.class) {
                int modifiers = f.getModifiers();
                // only look at public final static fields.
                if (((modifiers & Modifier.FINAL) != 0) &&
                        ((modifiers & Modifier.PUBLIC) != 0) &&
                        ((modifiers & Modifier.STATIC) != 0)) {
                    String fieldName = f.getName();
                    if (fieldName.startsWith("INSTALL_FAILED_") ||
                            fieldName.startsWith("INSTALL_PARSE_FAILED_")) {
                        // get the int value and compare it to result.
                        try {
                            if (result == f.getInt(null)) {
                                return fieldName;
                            }
                        } catch (IllegalAccessException e) {
                            // this shouldn't happen since we only look for public static fields.
                        }
                    }
        return s;
                }
            }
        }

        // couldn't find a matching constant? return the value
        return Integer.toString(result);
    }

    private void runInstall() {