1 /*
2  * Copyright (C) 2014 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 
17 package com.android.tradefed.util;
18 
19 import com.android.tradefed.device.DeviceNotAvailableException;
20 import com.android.tradefed.device.ITestDevice;
21 
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
24 
25 /**
26  * Utility class for abi.
27  */
28 public class AbiFormatter {
29 
30     private static final String PRODUCT_CPU_ABILIST_KEY = "ro.product.cpu.abilist";
31     private static final String PRODUCT_CPU_ABI_KEY = "ro.product.cpu.abi";
32     public static final String FORCE_ABI_STRING = "force-abi";
33     public static final String FORCE_ABI_DESCRIPTION = "The abi to use, can be either 32 or 64.";
34 
35     /**
36      * Special marker to be used as a placeholder in strings, that can be then
37      * replaced with the help of {@link #formatCmdForAbi}.
38      */
39     static final String ABI_REGEX = "\\|#ABI(\\d*)#\\|";
40 
41     /**
42      * Helper method that formats a given string to include abi specific
43      * values to it by replacing a given marker.
44      *
45      * @param str {@link String} to format which includes special markers |
46      *            {@value #ABI_REGEX} to be replaced
47      * @param abi {@link String} of the abi we desire to run on.
48      * @return formatted string.
49      */
formatCmdForAbi(String str, String abi)50     public static String formatCmdForAbi(String str, String abi) {
51         // If the abi is not set or null, do nothing. This is to maintain backward compatibility.
52         if (str == null) {
53             return null;
54         }
55         if (abi == null) {
56             return str.replaceAll(ABI_REGEX, "");
57         }
58         StringBuffer sb = new StringBuffer();
59         Matcher m = Pattern.compile(ABI_REGEX).matcher(str);
60         while (m.find()) {
61             if (m.group(1).equals(abi)) {
62                 m.appendReplacement(sb, "");
63             } else {
64                 m.appendReplacement(sb, abi);
65             }
66         }
67         m.appendTail(sb);
68         return sb.toString();
69     }
70 
71     /**
72      * Helper method to get the default abi name for the given bitness
73      *
74      * @param device
75      * @param bitness
76      * @return the default abi name for the given abi. Returns null if something went wrong.
77      * @throws DeviceNotAvailableException
78      */
getDefaultAbi(ITestDevice device, String bitness)79     public static String getDefaultAbi(ITestDevice device, String bitness)
80             throws DeviceNotAvailableException {
81         String []abis = getSupportedAbis(device, bitness);
82         if (abis != null && abis.length > 0 && abis[0] != null && abis[0].length() > 0) {
83             return abis[0];
84         }
85         return null;
86     }
87 
88     /**
89      * Helper method to get the list of supported abis for the given bitness
90      *
91      * @param device
92      * @param bitness 32 or 64 or empty string
93      * @return the supported abi list of that bitness
94      * @throws DeviceNotAvailableException
95      */
getSupportedAbis(ITestDevice device, String bitness)96     public static String[] getSupportedAbis(ITestDevice device, String bitness)
97             throws DeviceNotAvailableException {
98         String abiList = device.getProperty(PRODUCT_CPU_ABILIST_KEY + bitness);
99         if (abiList != null && !abiList.isEmpty()) {
100             String []abis = abiList.split(",");
101             if (abis.length > 0) {
102                 return abis;
103             }
104         }
105         // fallback plan for before lmp, the bitness is ignored
106         String legacyProperty = device.getProperty(PRODUCT_CPU_ABI_KEY);
107         if (legacyProperty != null) {
108             return new String[] {legacyProperty};
109         }
110         return new String[] {};
111     }
112 }
113