package tv.cjump.jni; import android.os.Build; import android.os.Environment; import android.text.TextUtils; import android.util.Log; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.lang.reflect.Field; public class DeviceUtils { public static final String ABI_X86 = "x86"; public static final String ABI_MIPS = "mips"; public static enum ARCH { Unknown, ARM, X86, MIPS, ARM64, } private static ARCH sArch = ARCH.Unknown; // see include/​uapi/​linux/​elf-em.h private static final int EM_ARM = 40; private static final int EM_386 = 3; private static final int EM_MIPS = 8; private static final int EM_AARCH64 = 183; // /system/lib/libc.so // XXX: need a runtime check public static synchronized ARCH getMyCpuArch() { byte[] data = new byte[20]; File libc = new File(Environment.getRootDirectory(), "lib/libc.so"); if (libc.canRead()) { RandomAccessFile fp = null; try { fp = new RandomAccessFile(libc, "r"); fp.readFully(data); int machine = (data[19] << 8) | data[18]; switch (machine) { case EM_ARM: sArch = ARCH.ARM; break; case EM_386: sArch = ARCH.X86; break; case EM_MIPS: sArch = ARCH.MIPS; break; case EM_AARCH64: sArch = ARCH.ARM64; break; default: Log.e("NativeBitmapFactory", "libc.so is unknown arch: " + Integer.toHexString(machine)); break; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fp != null) { try { fp.close(); } catch (IOException e) { e.printStackTrace(); } } } } return sArch; } public static String get_CPU_ABI() { return Build.CPU_ABI; } public static String get_CPU_ABI2() { try { Field field = Build.class.getDeclaredField("CPU_ABI2"); if (field == null) return null; Object fieldValue = field.get(null); if (!(fieldValue instanceof String)) { return null; } return (String) fieldValue; } catch (Exception e) { } return null; } public static boolean supportABI(String requestAbi) { String abi = get_CPU_ABI(); if (!TextUtils.isEmpty(abi) && abi.equalsIgnoreCase(requestAbi)) return true; String abi2 = get_CPU_ABI2(); return !TextUtils.isEmpty(abi2) && abi.equalsIgnoreCase(requestAbi); } public static boolean supportX86() { return supportABI(ABI_X86); } public static boolean supportMips() { return supportABI(ABI_MIPS); } public static boolean isARMSimulatedByX86() { ARCH arch = getMyCpuArch(); return !supportX86() && ARCH.X86.equals(arch); } public static boolean isMiBox2Device() { String manufacturer = Build.MANUFACTURER; String productName = Build.PRODUCT; return manufacturer.equalsIgnoreCase("Xiaomi") && productName.equalsIgnoreCase("dredd"); } public static boolean isMagicBoxDevice() { String manufacturer = Build.MANUFACTURER; String productName = Build.PRODUCT; return manufacturer.equalsIgnoreCase("MagicBox") && productName.equalsIgnoreCase("MagicBox"); } public static boolean isProblemBoxDevice() { return isMiBox2Device() || isMagicBoxDevice(); } public static boolean isRealARMArch() { ARCH arch = getMyCpuArch(); return (supportABI("armeabi-v7a") || supportABI("armeabi")) && ARCH.ARM.equals(arch); } public static boolean isRealX86Arch() { ARCH arch = getMyCpuArch(); return supportABI(ABI_X86) || ARCH.X86.equals(arch); } }