Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.tradefed.util;
     17 
     18 import java.util.HashMap;
     19 import java.util.HashSet;
     20 import java.util.Map;
     21 import java.util.Set;
     22 
     23 /**
     24  * Utility class for handling device ABIs
     25  */
     26 public class AbiUtils {
     27 
     28     // List of supported abi
     29     public static final String ABI_ARM_V7A = "armeabi-v7a";
     30     public static final String ABI_ARM_64_V8A = "arm64-v8a";
     31     public static final String ABI_X86 = "x86";
     32     public static final String ABI_X86_64 = "x86_64";
     33     public static final String ABI_MIPS = "mips";
     34     public static final String ABI_MIPS64 = "mips64";
     35 
     36     // List of supported architectures
     37     public static final String BASE_ARCH_ARM = "arm";
     38     public static final String ARCH_ARM64 = BASE_ARCH_ARM + "64";
     39     public static final String BASE_ARCH_X86 = "x86";
     40     public static final String ARCH_X86_64 = BASE_ARCH_X86 + "_64";
     41     public static final String BASE_ARCH_MIPS = "mips";
     42     public static final String ARCH_MIPS64 = BASE_ARCH_MIPS + "64";
     43 
     44     /**
     45      * The set of 32Bit ABIs.
     46      */
     47     private static final Set<String> ABIS_32BIT = new HashSet<String>();
     48 
     49     /**
     50      * The set of 64Bit ABIs.
     51      */
     52     private static final Set<String> ABIS_64BIT = new HashSet<String>();
     53 
     54     /**
     55      * The set of ARM ABIs.
     56      */
     57     protected static final Set<String> ARM_ABIS = new HashSet<String>();
     58 
     59     /**
     60      * The set of Intel ABIs.
     61      */
     62     private static final Set<String> INTEL_ABIS = new HashSet<String>();
     63 
     64     /**
     65      * The set of Mips ABIs.
     66      */
     67     private static final Set<String> MIPS_ABIS = new HashSet<String>();
     68 
     69     /**
     70      * The set of ABI names which Compatibility supports.
     71      */
     72     protected static final Set<String> ABIS_SUPPORTED_BY_COMPATIBILITY = new HashSet<String>();
     73 
     74     /**
     75      * The map of architecture to ABI.
     76      */
     77     private static final Map<String, Set<String>> ARCH_TO_ABIS = new HashMap<String, Set<String>>();
     78 
     79     private static final Map<String, String> ABI_TO_ARCH = new HashMap<String, String>();
     80 
     81     private static final Map<String, String> ABI_TO_BASE_ARCH = new HashMap<String, String>();
     82 
     83     static {
     84         ABIS_32BIT.add(ABI_ARM_V7A);
     85         ABIS_32BIT.add(ABI_X86);
     86         ABIS_32BIT.add(ABI_MIPS);
     87 
     88         ABIS_64BIT.add(ABI_ARM_64_V8A);
     89         ABIS_64BIT.add(ABI_X86_64);
     90         ABIS_64BIT.add(ABI_MIPS64);
     91 
     92         ARM_ABIS.add(ABI_ARM_V7A);
     93         ARM_ABIS.add(ABI_ARM_64_V8A);
     94 
     95         INTEL_ABIS.add(ABI_X86);
     96         INTEL_ABIS.add(ABI_X86_64);
     97 
     98         MIPS_ABIS.add(ABI_MIPS);
     99         MIPS_ABIS.add(ABI_MIPS64);
    100 
    101         ARCH_TO_ABIS.put(BASE_ARCH_ARM, ARM_ABIS);
    102         ARCH_TO_ABIS.put(ARCH_ARM64, ARM_ABIS);
    103         ARCH_TO_ABIS.put(BASE_ARCH_X86, INTEL_ABIS);
    104         ARCH_TO_ABIS.put(ARCH_X86_64, INTEL_ABIS);
    105         ARCH_TO_ABIS.put(BASE_ARCH_MIPS, MIPS_ABIS);
    106         ARCH_TO_ABIS.put(ARCH_MIPS64, MIPS_ABIS);
    107 
    108         ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(ARM_ABIS);
    109         ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(INTEL_ABIS);
    110         ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(MIPS_ABIS);
    111 
    112         ABI_TO_ARCH.put(ABI_ARM_V7A, BASE_ARCH_ARM);
    113         ABI_TO_ARCH.put(ABI_ARM_64_V8A, ARCH_ARM64);
    114         ABI_TO_ARCH.put(ABI_X86, BASE_ARCH_X86);
    115         ABI_TO_ARCH.put(ABI_X86_64, ARCH_X86_64);
    116         ABI_TO_ARCH.put(ABI_MIPS, BASE_ARCH_MIPS);
    117         ABI_TO_ARCH.put(ABI_MIPS64, ARCH_MIPS64);
    118 
    119         ABI_TO_BASE_ARCH.put(ABI_ARM_V7A, BASE_ARCH_ARM);
    120         ABI_TO_BASE_ARCH.put(ABI_ARM_64_V8A, BASE_ARCH_ARM);
    121         ABI_TO_BASE_ARCH.put(ABI_X86, BASE_ARCH_X86);
    122         ABI_TO_BASE_ARCH.put(ABI_X86_64, BASE_ARCH_X86);
    123         ABI_TO_BASE_ARCH.put(ABI_MIPS, BASE_ARCH_MIPS);
    124         ABI_TO_BASE_ARCH.put(ABI_MIPS64, BASE_ARCH_MIPS);
    125     }
    126 
    127     /**
    128      * Private constructor to avoid instantiation.
    129      */
    130     private AbiUtils() {}
    131 
    132     /**
    133      * Returns the set of ABIs associated with the given architecture.
    134      * @param arch The architecture to look up.
    135      * @return a new Set containing the ABIs.
    136      */
    137     public static Set<String> getAbisForArch(String arch) {
    138         if (arch == null || arch.isEmpty() || !ARCH_TO_ABIS.containsKey(arch)) {
    139             return getAbisSupportedByCompatibility();
    140         }
    141         return new HashSet<String>(ARCH_TO_ABIS.get(arch));
    142     }
    143 
    144     /**
    145      * Returns the architecture matching the abi.
    146      */
    147     public static String getArchForAbi(String abi) {
    148         if (abi == null || abi.isEmpty()) {
    149             throw new IllegalArgumentException("Abi cannot be null or empty");
    150         }
    151         return ABI_TO_ARCH.get(abi);
    152     }
    153 
    154     /** Returns the base architecture matching the abi. */
    155     public static String getBaseArchForAbi(String abi) {
    156         if (abi == null || abi.isEmpty()) {
    157             throw new IllegalArgumentException("Abi cannot be null or empty");
    158         }
    159         return ABI_TO_BASE_ARCH.get(abi);
    160     }
    161 
    162     /**
    163      * Returns the set of ABIs supported by Compatibility.
    164      *
    165      * @return a new Set containing the supported ABIs.
    166      */
    167     public static Set<String> getAbisSupportedByCompatibility() {
    168         return new HashSet<String>(ABIS_SUPPORTED_BY_COMPATIBILITY);
    169     }
    170 
    171     /**
    172      * @param abi The ABI name to test.
    173      * @return true if the given ABI is supported by Compatibility.
    174      */
    175     public static boolean isAbiSupportedByCompatibility(String abi) {
    176         return ABIS_SUPPORTED_BY_COMPATIBILITY.contains(abi);
    177     }
    178 
    179     /**
    180      * Creates a flag for the given ABI.
    181      * @param abi the ABI to create the flag for.
    182      * @return a string which can be add to a command sent to ADB.
    183      */
    184     public static String createAbiFlag(String abi) {
    185         if (abi == null || abi.isEmpty() || !isAbiSupportedByCompatibility(abi)) {
    186             return "";
    187         }
    188         return String.format("--abi %s ", abi);
    189     }
    190 
    191     /**
    192      * Creates a unique id from the given ABI and name.
    193      * @param abi The ABI to use.
    194      * @param name The name to use.
    195      * @return a string which uniquely identifies a run.
    196      */
    197     public static String createId(String abi, String name) {
    198         return String.format("%s %s", abi, name);
    199     }
    200 
    201     /**
    202      * Parses a unique id into the ABI and name.
    203      * @param id The id to parse.
    204      * @return a string array containing the ABI and name.
    205      */
    206     public static String[] parseId(String id) {
    207         if (id == null || !id.contains(" ")) {
    208             return new String[] {"", ""};
    209         }
    210         return id.split(" ");
    211     }
    212 
    213     /**
    214      * @return the test name portion of the test id.
    215      *         e.g. armeabi-v7a android.mytest = android.mytest
    216      */
    217     public static String parseTestName(String id) {
    218         return parseId(id)[1];
    219     }
    220 
    221     /**
    222      * @return the abi portion of the test id.
    223      *         e.g. armeabi-v7a android.mytest = armeabi-v7a
    224      */
    225     public static String parseAbi(String id) {
    226         return parseId(id)[0];
    227     }
    228 
    229     /**
    230      * @param abi The name of the ABI.
    231      * @return The bitness of the ABI with the given name
    232      */
    233     public static String getBitness(String abi) {
    234         return ABIS_32BIT.contains(abi) ? "32" : "64";
    235     }
    236 
    237     /**
    238      * @param unsupportedAbiDescription A comma separated string containing abis.
    239      * @return A List of Strings containing valid ABIs.
    240      */
    241     public static Set<String> parseAbiList(String unsupportedAbiDescription) {
    242         Set<String> abiSet = new HashSet<>();
    243         String[] descSegments = unsupportedAbiDescription.split(":");
    244         if (descSegments.length == 2) {
    245             for (String abi : descSegments[1].split(",")) {
    246                 String trimmedAbi = abi.trim();
    247                 if (isAbiSupportedByCompatibility(trimmedAbi)) {
    248                     abiSet.add(trimmedAbi);
    249                 }
    250             }
    251         }
    252         return abiSet;
    253     }
    254 
    255     /**
    256      * @param abiListProp A comma separated list containing abis coming from the device property.
    257      * @return A List of Strings containing valid ABIs.
    258      */
    259     public static Set<String> parseAbiListFromProperty(String abiListProp) {
    260         Set<String> abiSet = new HashSet<>();
    261         String[] abiList = abiListProp.split(",");
    262         for (String abi : abiList) {
    263             String trimmedAbi = abi.trim();
    264             if (isAbiSupportedByCompatibility(trimmedAbi)) {
    265                 abiSet.add(trimmedAbi);
    266             }
    267         }
    268         return abiSet;
    269     }
    270 }
    271