1 /*
2  * Copyright (C) 2015 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.server.pm;
18 
19 import android.os.Build;
20 import android.os.SystemProperties;
21 import android.text.TextUtils;
22 import android.util.ArraySet;
23 
24 import dalvik.system.VMRuntime;
25 
26 import java.util.ArrayList;
27 import java.util.List;
28 
29 /**
30  * Provides various methods for obtaining and converting of instruction sets.
31  *
32  * @hide
33  */
34 public class InstructionSets {
35     private static final String PREFERRED_INSTRUCTION_SET =
36             VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
37 
getAppDexInstructionSets(String primaryCpuAbi, String secondaryCpuAbi)38     public static String[] getAppDexInstructionSets(String primaryCpuAbi, String secondaryCpuAbi) {
39         if (primaryCpuAbi != null) {
40             if (secondaryCpuAbi != null) {
41                 return new String[] {
42                         VMRuntime.getInstructionSet(primaryCpuAbi),
43                         VMRuntime.getInstructionSet(secondaryCpuAbi) };
44             } else {
45                 return new String[] {
46                         VMRuntime.getInstructionSet(primaryCpuAbi) };
47             }
48         }
49 
50         return new String[] { getPreferredInstructionSet() };
51     }
52 
getPreferredInstructionSet()53     public static String getPreferredInstructionSet() {
54         return PREFERRED_INSTRUCTION_SET;
55     }
56 
57     /**
58      * Returns the instruction set that should be used to compile dex code. In the presence of
59      * a native bridge this might be different than the one shared libraries use.
60      */
getDexCodeInstructionSet(String sharedLibraryIsa)61     public static String getDexCodeInstructionSet(String sharedLibraryIsa) {
62         // TODO b/19550105 Build mapping once instead of querying each time
63         String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
64         return TextUtils.isEmpty(dexCodeIsa) ? sharedLibraryIsa : dexCodeIsa;
65     }
66 
getDexCodeInstructionSets(String[] instructionSets)67     public static String[] getDexCodeInstructionSets(String[] instructionSets) {
68         ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length);
69         for (String instructionSet : instructionSets) {
70             dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
71         }
72         return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
73     }
74 
75     /**
76      * Returns deduplicated list of supported instructions for dex code.
77      */
getAllDexCodeInstructionSets()78     public static String[] getAllDexCodeInstructionSets() {
79         String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
80         for (int i = 0; i < supportedInstructionSets.length; i++) {
81             String abi = Build.SUPPORTED_ABIS[i];
82             supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
83         }
84         return getDexCodeInstructionSets(supportedInstructionSets);
85     }
86 
getAllInstructionSets()87     public static List<String> getAllInstructionSets() {
88         final String[] allAbis = Build.SUPPORTED_ABIS;
89         final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
90 
91         for (String abi : allAbis) {
92             final String instructionSet = VMRuntime.getInstructionSet(abi);
93             if (!allInstructionSets.contains(instructionSet)) {
94                 allInstructionSets.add(instructionSet);
95             }
96         }
97 
98         return allInstructionSets;
99     }
100 
101     /**
102      * Calculates the primary instruction set based on the computed Abis of a given package.
103      */
getPrimaryInstructionSet(PackageAbiHelper.Abis abis)104     public static String getPrimaryInstructionSet(PackageAbiHelper.Abis abis) {
105         if (abis.primary == null) {
106             return getPreferredInstructionSet();
107         }
108 
109         return VMRuntime.getInstructionSet(abis.primary);
110     }
111 }
112