blob: b69497b3f87199c9d2ce577de603ffed3ed200ad [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tradefed.util;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Utility class for handling device ABIs
*/
public class AbiUtils {
// List of supported abi
public static final String ABI_ARM_V7A = "armeabi-v7a";
public static final String ABI_ARM_64_V8A = "arm64-v8a";
public static final String ABI_X86 = "x86";
public static final String ABI_X86_64 = "x86_64";
public static final String ABI_MIPS = "mips";
public static final String ABI_MIPS64 = "mips64";
// List of supported architectures
public static final String BASE_ARCH_ARM = "arm";
public static final String ARCH_ARM64 = BASE_ARCH_ARM + "64";
public static final String BASE_ARCH_X86 = "x86";
public static final String ARCH_X86_64 = BASE_ARCH_X86 + "_64";
public static final String BASE_ARCH_MIPS = "mips";
public static final String ARCH_MIPS64 = BASE_ARCH_MIPS + "64";
/**
* The set of 32Bit ABIs.
*/
private static final Set<String> ABIS_32BIT = new HashSet<String>();
/**
* The set of 64Bit ABIs.
*/
private static final Set<String> ABIS_64BIT = new HashSet<String>();
/**
* The set of ARM ABIs.
*/
protected static final Set<String> ARM_ABIS = new HashSet<String>();
/**
* The set of Intel ABIs.
*/
private static final Set<String> INTEL_ABIS = new HashSet<String>();
/**
* The set of Mips ABIs.
*/
private static final Set<String> MIPS_ABIS = new HashSet<String>();
/** The set of ABI names which Compatibility supports. */
protected static final Set<String> ABIS_SUPPORTED_BY_COMPATIBILITY = new LinkedHashSet<>();
/** The set of Architecture supported. */
private static final Set<String> ARCH_SUPPORTED = new LinkedHashSet<>();
/** The map of architecture to ABI. */
private static final Map<String, Set<String>> ARCH_TO_ABIS =
new LinkedHashMap<String, Set<String>>();
private static final Map<String, String> ABI_TO_ARCH = new LinkedHashMap<String, String>();
private static final Map<String, String> ABI_TO_BASE_ARCH = new LinkedHashMap<String, String>();
static {
ABIS_32BIT.add(ABI_ARM_V7A);
ABIS_32BIT.add(ABI_X86);
ABIS_32BIT.add(ABI_MIPS);
ABIS_64BIT.add(ABI_ARM_64_V8A);
ABIS_64BIT.add(ABI_X86_64);
ABIS_64BIT.add(ABI_MIPS64);
ARM_ABIS.add(ABI_ARM_V7A);
ARM_ABIS.add(ABI_ARM_64_V8A);
INTEL_ABIS.add(ABI_X86);
INTEL_ABIS.add(ABI_X86_64);
MIPS_ABIS.add(ABI_MIPS);
MIPS_ABIS.add(ABI_MIPS64);
ARCH_TO_ABIS.put(BASE_ARCH_ARM, ARM_ABIS);
ARCH_TO_ABIS.put(ARCH_ARM64, ARM_ABIS);
ARCH_TO_ABIS.put(BASE_ARCH_X86, INTEL_ABIS);
ARCH_TO_ABIS.put(ARCH_X86_64, INTEL_ABIS);
ARCH_TO_ABIS.put(BASE_ARCH_MIPS, MIPS_ABIS);
ARCH_TO_ABIS.put(ARCH_MIPS64, MIPS_ABIS);
ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(ARM_ABIS);
ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(INTEL_ABIS);
ABIS_SUPPORTED_BY_COMPATIBILITY.addAll(MIPS_ABIS);
ABI_TO_ARCH.put(ABI_ARM_V7A, BASE_ARCH_ARM);
ABI_TO_ARCH.put(ABI_ARM_64_V8A, ARCH_ARM64);
ABI_TO_ARCH.put(ABI_X86, BASE_ARCH_X86);
ABI_TO_ARCH.put(ABI_X86_64, ARCH_X86_64);
ABI_TO_ARCH.put(ABI_MIPS, BASE_ARCH_MIPS);
ABI_TO_ARCH.put(ABI_MIPS64, ARCH_MIPS64);
ABI_TO_BASE_ARCH.put(ABI_ARM_V7A, BASE_ARCH_ARM);
ABI_TO_BASE_ARCH.put(ABI_ARM_64_V8A, BASE_ARCH_ARM);
ABI_TO_BASE_ARCH.put(ABI_X86, BASE_ARCH_X86);
ABI_TO_BASE_ARCH.put(ABI_X86_64, BASE_ARCH_X86);
ABI_TO_BASE_ARCH.put(ABI_MIPS, BASE_ARCH_MIPS);
ABI_TO_BASE_ARCH.put(ABI_MIPS64, BASE_ARCH_MIPS);
ARCH_SUPPORTED.add(BASE_ARCH_ARM);
ARCH_SUPPORTED.add(ARCH_ARM64);
ARCH_SUPPORTED.add(BASE_ARCH_X86);
ARCH_SUPPORTED.add(ARCH_X86_64);
ARCH_SUPPORTED.add(BASE_ARCH_MIPS);
ARCH_SUPPORTED.add(ARCH_MIPS64);
}
/**
* Private constructor to avoid instantiation.
*/
private AbiUtils() {}
/**
* Returns the set of ABIs associated with the given architecture.
* @param arch The architecture to look up.
* @return a new Set containing the ABIs.
*/
public static Set<String> getAbisForArch(String arch) {
if (arch == null || arch.isEmpty() || !ARCH_TO_ABIS.containsKey(arch)) {
return getAbisSupportedByCompatibility();
}
return new LinkedHashSet<String>(ARCH_TO_ABIS.get(arch));
}
/**
* Returns the architecture matching the abi.
*/
public static String getArchForAbi(String abi) {
if (abi == null || abi.isEmpty()) {
throw new IllegalArgumentException("Abi cannot be null or empty");
}
return ABI_TO_ARCH.get(abi);
}
/** Returns the base architecture matching the abi. */
public static String getBaseArchForAbi(String abi) {
if (abi == null || abi.isEmpty()) {
throw new IllegalArgumentException("Abi cannot be null or empty");
}
return ABI_TO_BASE_ARCH.get(abi);
}
/**
* Returns the set of ABIs supported by Compatibility.
*
* @return a new Set containing the supported ABIs.
*/
public static Set<String> getAbisSupportedByCompatibility() {
return new LinkedHashSet<String>(ABIS_SUPPORTED_BY_COMPATIBILITY);
}
/** Returns the set of supported architecture representations. */
public static Set<String> getArchSupported() {
return new LinkedHashSet<String>(ARCH_SUPPORTED);
}
/**
* @param abi The ABI name to test.
* @return true if the given ABI is supported by Compatibility.
*/
public static boolean isAbiSupportedByCompatibility(String abi) {
return ABIS_SUPPORTED_BY_COMPATIBILITY.contains(abi);
}
/**
* Creates a flag for the given ABI.
* @param abi the ABI to create the flag for.
* @return a string which can be add to a command sent to ADB.
*/
public static String createAbiFlag(String abi) {
if (abi == null || abi.isEmpty() || !isAbiSupportedByCompatibility(abi)) {
return "";
}
return String.format("--abi %s ", abi);
}
/**
* Creates a unique id from the given ABI and name.
* @param abi The ABI to use.
* @param name The name to use.
* @return a string which uniquely identifies a run.
*/
public static String createId(String abi, String name) {
return String.format("%s %s", abi, name);
}
/**
* Parses a unique id into the ABI and name.
* @param id The id to parse.
* @return a string array containing the ABI and name.
*/
public static String[] parseId(String id) {
if (id == null || !id.contains(" ")) {
return new String[] {"", ""};
}
return id.split(" ");
}
/**
* @return the test name portion of the test id.
* e.g. armeabi-v7a android.mytest = android.mytest
*/
public static String parseTestName(String id) {
return parseId(id)[1];
}
/**
* @return the abi portion of the test id.
* e.g. armeabi-v7a android.mytest = armeabi-v7a
*/
public static String parseAbi(String id) {
return parseId(id)[0];
}
/**
* @param abi The name of the ABI.
* @return The bitness of the ABI with the given name
*/
public static String getBitness(String abi) {
return ABIS_32BIT.contains(abi) ? "32" : "64";
}
/**
* @param unsupportedAbiDescription A comma separated string containing abis.
* @return A List of Strings containing valid ABIs.
*/
public static Set<String> parseAbiList(String unsupportedAbiDescription) {
Set<String> abiSet = new HashSet<>();
String[] descSegments = unsupportedAbiDescription.split(":");
if (descSegments.length == 2) {
for (String abi : descSegments[1].split(",")) {
String trimmedAbi = abi.trim();
if (isAbiSupportedByCompatibility(trimmedAbi)) {
abiSet.add(trimmedAbi);
}
}
}
return abiSet;
}
/**
* @param abiListProp A comma separated list containing abis coming from the device property.
* @return A List of Strings containing valid ABIs.
*/
public static Set<String> parseAbiListFromProperty(String abiListProp) {
Set<String> abiSet = new HashSet<>();
String[] abiList = abiListProp.split(",");
for (String abi : abiList) {
String trimmedAbi = abi.trim();
if (isAbiSupportedByCompatibility(trimmedAbi)) {
abiSet.add(trimmedAbi);
}
}
return abiSet;
}
/** Returns the Set of abis supported by the host machine. */
public static Set<String> getHostAbi() {
CommandResult commandResult = RunUtil.getDefault().runTimedCmd(5000L, "uname", "-m");
String mainAbi = commandResult.getStdout().trim();
return getAbisForArch(mainAbi);
}
}