1 /*
2  * Copyright (C) 2017 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.compatibility.common.util;
17 import com.android.tradefed.device.CollectingOutputReceiver;
18 
19 import com.android.tradefed.device.DeviceNotAvailableException;
20 import com.android.tradefed.device.ITestDevice;
21 import java.util.regex.Pattern;
22 
23 /**
24  * Host-side utility class for reading properties and gathering information for testing
25  * Android device compatibility.
26  */
27 public class CpuFeatures {
28 
29     private static final String UNAME_OPTION_MACHINE_TYPE = "-m";
30     private static final String UNAME_OPTION_KERNEL_RELEASE = "-r";
31 
uname(ITestDevice device, String option)32     private static String uname(ITestDevice device, String option) throws DeviceNotAvailableException {
33         CollectingOutputReceiver Out = new CollectingOutputReceiver();
34         device.executeShellCommand("uname " + option, Out);
35         return Out.getOutput().trim();
36     }
37 
38     /**
39      * Return true if architecture is arm64.
40      */
isArm64(ITestDevice device)41     public static boolean isArm64(ITestDevice device) throws DeviceNotAvailableException {
42 
43         return uname(device, UNAME_OPTION_MACHINE_TYPE).contains("aarch64");
44     }
45 
46     /**
47      * Return true if architecture is arm32.
48      */
isArm32(ITestDevice device)49     public static boolean isArm32(ITestDevice device) throws DeviceNotAvailableException {
50 
51         return uname(device, UNAME_OPTION_MACHINE_TYPE).contains("armv7");
52     }
53 
54     /**
55      * Return true if architecture is x86.
56      */
isX86(ITestDevice device)57     public static boolean isX86(ITestDevice device) throws DeviceNotAvailableException {
58         // Possible names: i386, i486, i686, x86_64.
59         return uname(device, UNAME_OPTION_MACHINE_TYPE).contains("86");
60     }
61 
62     /* Return true if architecture is x86_64. */
isX86_64(ITestDevice device)63     public static boolean isX86_64(ITestDevice device) throws DeviceNotAvailableException {
64 
65         return uname(device, UNAME_OPTION_MACHINE_TYPE).contains("x86_64");
66     }
67 
68     /* Return true if architecture is 32-bit x86. */
isX86_32(ITestDevice device)69     public static boolean isX86_32(ITestDevice device) throws DeviceNotAvailableException {
70 
71         return isX86(device) && !isX86_64(device);
72     }
73 
74     /* Return true if ABI is native. */
isNativeAbi(ITestDevice device, String abi)75     public static boolean isNativeAbi(ITestDevice device, String abi)
76             throws DeviceNotAvailableException {
77       if (isArm32(device) && abi.equals("armeabi-v7a")) {
78           return true;
79       }
80       // Both armeabi-v7a and arm64-v8a are native.
81       if (isArm64(device) && abi.contains("arm")) {
82           return true;
83       }
84       if (isX86_32(device) && abi.equals("x86")) {
85           return true;
86       }
87       // Both x86 and x86_64 are native.
88       if (isX86_64(device) && abi.contains("x86")) {
89           return true;
90       }
91       return false;
92     }
93 
94     /**
95      * Return true kernel if version is less than input values.
96      */
kernelVersionLessThan(ITestDevice device, int major, int minor)97     public static boolean kernelVersionLessThan(ITestDevice device, int major, int minor)
98             throws DeviceNotAvailableException {
99 
100         String[] kernelVersion = uname(device, UNAME_OPTION_KERNEL_RELEASE).split(Pattern.quote("."));
101         int deviceMajor = Integer.parseInt(kernelVersion[0]);
102         int deviceMinor = Integer.parseInt(kernelVersion[1]);
103 
104         return (major > deviceMajor) || ((major == deviceMajor) && (minor > deviceMinor));
105     }
106 }
107