diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/FmIconFetcher.java b/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/FmIconFetcher.java index d342641328b..a65c888f791 100644 --- a/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/FmIconFetcher.java +++ b/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/FmIconFetcher.java @@ -102,6 +102,14 @@ public ImageLoader.ImageFetcherResult fetchImage(@NonNull String tag) { false, true, defaultImage); } } + } else if (FmIcons.isArchive(drawableRes)) { + if (ContentType.JAVA_ARCHIVE.getMimeType().equals(mimeType)) { + Bitmap bitmap = FmIcons.generateJ2meIcon(mFmItem.path); + if (bitmap != null) { + return new ImageLoader.ImageFetcherResult(tag, getThumbnail(bitmap, size, true), + false, true, defaultImage); + } + } } else if (FmIcons.isAudio(drawableRes)) { try { Bitmap bitmap = ThumbnailUtilsCompat.createAudioThumbnail(ContextUtils.getContext(), FmProvider.getContentUri(mFmItem.path), size, null); diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/FmIcons.java b/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/FmIcons.java index 8866711bd03..568105212a1 100644 --- a/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/FmIcons.java +++ b/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/FmIcons.java @@ -275,6 +275,10 @@ public static boolean isApk(@DrawableRes int drawable) { return drawable == DRAWABLE_APK; } + public static boolean isArchive(@DrawableRes int drawable) { + return drawable == DRAWABLE_ARCHIVE; + } + public static boolean isImage(@DrawableRes int drawable) { return drawable == DRAWABLE_IMAGE; } @@ -368,6 +372,21 @@ public static Bitmap generateEpubCover(@NonNull Path path) { } } + @Nullable + public static Bitmap generateJ2meIcon(@NonNull Path path) { + Pair file = getUsableFile(path); + if (file == null) { + return null; + } + try { + return J2meIconExtractor.generateFromFile(file.first); + } finally { + if (file.second) { + file.first.delete(); + } + } + } + @Nullable public static Bitmap getOpenDocumentThumbnail(@NonNull Path path) { Pair file = getUsableFile(path); diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/J2meIconExtractor.java b/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/J2meIconExtractor.java new file mode 100644 index 00000000000..6dc81e28dc9 --- /dev/null +++ b/app/src/main/java/io/github/muntashirakon/AppManager/fm/icons/J2meIconExtractor.java @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package io.github.muntashirakon.AppManager.fm.icons; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +class J2meIconExtractor { + @Nullable + public static Bitmap generateFromFile(@NonNull File file) { + try(ZipFile zipFile = new ZipFile(file)) { + String iconFile = getIconLocation(zipFile, zipFile.getEntry("META-INF/MANIFEST.MF")); + if (iconFile == null) { + // Not a J2ME JAR + return null; + } + ZipEntry iconEntry = zipFile.getEntry(iconFile); + if (iconEntry != null) { + return BitmapFactory.decodeStream(zipFile.getInputStream(iconEntry)); + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + @Nullable + private static String getIconLocation(@NonNull ZipFile zipFile, @Nullable ZipEntry zipEntry) { + if (zipEntry == null) { + return null; + } + try { + Manifest manifest = new Manifest(zipFile.getInputStream(zipEntry)); + Attributes attributes = manifest.getMainAttributes(); + // The logic is derived from J2ME Loader (ru.woesss.j2me.jar.Descriptor#getIcon()) + String icon = attributes.getValue("MIDlet-Icon"); + if (icon == null || icon.trim().isEmpty()) { + String midlet = "MIDlet-" + 1; + icon = attributes.getValue(midlet); + if (icon == null) { + return null; + } + int start = icon.indexOf(','); + if (start != -1) { + int end = icon.indexOf(',', ++start); + if (end != -1) + icon = icon.substring(start, end); + } + } + icon = icon.trim(); + if (icon.isEmpty()) { + return null; + } + while (icon.charAt(0) == '/') { + icon = icon.substring(1); + } + return icon; + } catch (IOException ignore) { + } + return null; + } +}