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