package com.qm4rs.fridabox; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; public final class ApkInspector { private ApkInspector() { } public static Result inspect(File apk) throws IOException { return inspect(Collections.singletonList(apk)); } public static Result inspect(File... apks) throws IOException { return inspect(Arrays.asList(apks)); } public static Result inspect(Iterable apks) throws IOException { Set abis = new LinkedHashSet<>(); boolean hasNativeLibraries = false; boolean inspectedAny = false; for (File apk : apks) { inspectedAny = true; try (ZipFile archive = new ZipFile(apk)) { if (archive.getEntry("AndroidManifest.xml") == null) { throw new IOException("The selected file has no AndroidManifest.xml"); } for (ZipEntry entry : Collections.list(archive.entries())) { String name = entry.getName(); if (!entry.isDirectory() && name.startsWith("lib/") && name.endsWith(".so")) { String[] parts = name.split("/", 3); if (parts.length == 3) { hasNativeLibraries = true; abis.add(parts[1]); } } } } } if (!inspectedAny) throw new IOException("No APK files were provided"); boolean supported = !hasNativeLibraries || !Collections.disjoint(abis, SUPPORTED_ABIS); return new Result(hasNativeLibraries, supported, abis); } public static final class Result { public final boolean hasNativeLibraries; public final boolean supported; public final Set abis; Result(boolean hasNativeLibraries, boolean supported, Set abis) { this.hasNativeLibraries = hasNativeLibraries; this.supported = supported; this.abis = Collections.unmodifiableSet(new LinkedHashSet<>(abis)); } public String description() { if (!hasNativeLibraries) return "Pure Java/Kotlin (accepted)"; return supported ? "Supported ABI: " + abis : "Rejected; unsupported ABI: " + abis; } } private static final Set SUPPORTED_ABIS = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList( "armeabi-v7a", "arm64-v8a", "x86", "x86_64" ))); }