From 61a51f5ebc48fb43222ed348ea10122f4c17d6ca Mon Sep 17 00:00:00 2001 From: Muntashir Al-Islam Date: Thu, 7 Sep 2023 17:16:19 +0600 Subject: [PATCH] [Installer] Fix installing some signed APK files Some signed APKs could not be installed due size mismatch. Signed-off-by: Muntashir Al-Islam --- .../muntashirakon/AppManager/apk/ApkFile.java | 23 +++++++++++++++---- .../apk/installer/PackageInstallerCompat.java | 3 ++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/apk/ApkFile.java b/app/src/main/java/io/github/muntashirakon/AppManager/apk/ApkFile.java index 482385cdec7..d5c8aa9df0c 100644 --- a/app/src/main/java/io/github/muntashirakon/AppManager/apk/ApkFile.java +++ b/app/src/main/java/io/github/muntashirakon/AppManager/apk/ApkFile.java @@ -67,6 +67,7 @@ import io.github.muntashirakon.AppManager.settings.Prefs; import io.github.muntashirakon.AppManager.utils.ArrayUtils; import io.github.muntashirakon.AppManager.utils.ContextUtils; +import io.github.muntashirakon.AppManager.utils.DigestUtils; import io.github.muntashirakon.AppManager.utils.FileUtils; import io.github.muntashirakon.AppManager.utils.LangUtils; import io.github.muntashirakon.io.IoUtils; @@ -707,6 +708,18 @@ public long getFileSize() { else throw new RuntimeException("Neither zipEntry nor source is defined."); } + /** + * Get size of the entry or {@code -1} if unavailable + */ + @WorkerThread + public long getFileSize(boolean signed) { + try { + return (signed ? getSignedFile() : getRealCachedFile()).length(); + } catch (IOException e) { + return -1; + } + } + @WorkerThread public File getFile(boolean signed) throws IOException { return signed ? getSignedFile() : getRealCachedFile(); @@ -734,12 +747,14 @@ private File getSignedFile() throws IOException { mIdsigFile = mFileCache.createCachedFile("idsig"); signer.setIdsigFile(mIdsigFile); } - if (signer.sign(realFile, mSignedFile, -1, zipAlign)) { - if (Signer.verify(sigSchemes, mSignedFile, mIdsigFile)) { - return mSignedFile; - } + if (signer.sign(realFile, mSignedFile, -1, zipAlign) + && Signer.verify(sigSchemes, mSignedFile, mIdsigFile)) { + DigestUtils.getHexDigest(DigestUtils.SHA_256, mSignedFile); + return mSignedFile; } throw new IOException("Failed to sign " + realFile); + } catch (IOException e) { + throw e; } catch (Exception e) { throw new IOException(e); } diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/apk/installer/PackageInstallerCompat.java b/app/src/main/java/io/github/muntashirakon/AppManager/apk/installer/PackageInstallerCompat.java index 248dabe41d2..b86183965db 100644 --- a/app/src/main/java/io/github/muntashirakon/AppManager/apk/installer/PackageInstallerCompat.java +++ b/app/src/main/java/io/github/muntashirakon/AppManager/apk/installer/PackageInstallerCompat.java @@ -592,8 +592,9 @@ public boolean install(@NonNull ApkFile apkFile, @NonNull List selectedS Log.d(TAG, "Install: selected entries: %s", selectedSplitIds); // Write apk files for (ApkFile.Entry entry : selectedEntries) { + long entrySize = entry.getFileSize(options.isSignApkFiles()); try (InputStream apkInputStream = entry.getInputStream(options.isSignApkFiles()); - OutputStream apkOutputStream = mSession.openWrite(entry.getFileName(), 0, entry.getFileSize())) { + OutputStream apkOutputStream = mSession.openWrite(entry.getFileName(), 0, entrySize)) { IoUtils.copy(apkInputStream, apkOutputStream, totalSize, progressHandler); mSession.fsync(apkOutputStream); Log.d(TAG, "Install: copied entry %s", entry.name);