17487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov/* 27487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * Copyright (C) 2015 The Android Open Source Project 37487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * 47487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * Licensed under the Apache License, Version 2.0 (the "License"); 57487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * you may not use this file except in compliance with the License. 67487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * You may obtain a copy of the License at 77487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * 87487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * http://www.apache.org/licenses/LICENSE-2.0 97487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * 107487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * Unless required by applicable law or agreed to in writing, software 117487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * distributed under the License is distributed on an "AS IS" BASIS, 127487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * See the License for the specific language governing permissions and 147487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * limitations under the License 157487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov */ 167487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 177487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovpackage com.android.server.pm; 187487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 197487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovimport android.content.pm.ApplicationInfo; 207487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovimport android.os.Build; 217487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovimport android.os.SystemProperties; 227487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovimport android.text.TextUtils; 237487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovimport android.util.ArraySet; 247487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 257487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovimport java.util.ArrayList; 267487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovimport java.util.List; 277487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 287487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovimport dalvik.system.VMRuntime; 297487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 307487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov/** 317487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * Provides various methods for obtaining and converting of instruction sets. 327487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * 337487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * @hide 347487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov */ 357487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolovpublic class InstructionSets { 367487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov private static final String PREFERRED_INSTRUCTION_SET = 377487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);; 387487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov public static String[] getAppDexInstructionSets(ApplicationInfo info) { 397487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov if (info.primaryCpuAbi != null) { 407487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov if (info.secondaryCpuAbi != null) { 417487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return new String[] { 427487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov VMRuntime.getInstructionSet(info.primaryCpuAbi), 437487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov VMRuntime.getInstructionSet(info.secondaryCpuAbi) }; 447487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } else { 457487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return new String[] { 467487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov VMRuntime.getInstructionSet(info.primaryCpuAbi) }; 477487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 487487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 497487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 507487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return new String[] { getPreferredInstructionSet() }; 517487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 527487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 537487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov public static String[] getAppDexInstructionSets(PackageSetting ps) { 547487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov if (ps.primaryCpuAbiString != null) { 557487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov if (ps.secondaryCpuAbiString != null) { 567487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return new String[] { 577487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov VMRuntime.getInstructionSet(ps.primaryCpuAbiString), 587487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) }; 597487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } else { 607487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return new String[] { 617487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov VMRuntime.getInstructionSet(ps.primaryCpuAbiString) }; 627487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 637487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 647487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 657487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return new String[] { getPreferredInstructionSet() }; 667487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 677487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 687487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov public static String getPreferredInstructionSet() { 697487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return PREFERRED_INSTRUCTION_SET; 707487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 717487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 727487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov /** 737487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * Returns the instruction set that should be used to compile dex code. In the presence of 747487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * a native bridge this might be different than the one shared libraries use. 757487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov */ 767487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov public static String getDexCodeInstructionSet(String sharedLibraryIsa) { 77b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov // TODO b/19550105 Build mapping once instead of querying each time 787487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa); 797487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return TextUtils.isEmpty(dexCodeIsa) ? sharedLibraryIsa : dexCodeIsa; 807487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 817487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 827487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov public static String[] getDexCodeInstructionSets(String[] instructionSets) { 837487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length); 847487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov for (String instructionSet : instructionSets) { 857487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet)); 867487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 877487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]); 887487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 897487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 907487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov /** 917487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov * Returns deduplicated list of supported instructions for dex code. 927487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov */ 937487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov public static String[] getAllDexCodeInstructionSets() { 947487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length]; 957487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov for (int i = 0; i < supportedInstructionSets.length; i++) { 967487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov String abi = Build.SUPPORTED_ABIS[i]; 977487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi); 987487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 997487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return getDexCodeInstructionSets(supportedInstructionSets); 1007487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 1017487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 1027487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov public static List<String> getAllInstructionSets() { 1037487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov final String[] allAbis = Build.SUPPORTED_ABIS; 1047487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov final List<String> allInstructionSets = new ArrayList<String>(allAbis.length); 1057487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 1067487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov for (String abi : allAbis) { 1077487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov final String instructionSet = VMRuntime.getInstructionSet(abi); 1087487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov if (!allInstructionSets.contains(instructionSet)) { 1097487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov allInstructionSets.add(instructionSet); 1107487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 1117487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 1127487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov 1137487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov return allInstructionSets; 1147487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov } 115b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov 116b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov public static String getPrimaryInstructionSet(ApplicationInfo info) { 117b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov if (info.primaryCpuAbi == null) { 118b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov return getPreferredInstructionSet(); 119b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov } 120b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov 121b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov return VMRuntime.getInstructionSet(info.primaryCpuAbi); 122b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov } 123b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov 1247487657ee9f3f91a1fb4e52ce2a03b56496ac1f4Fyodor Kupolov} 125