diff --git a/app/src/main/java/com/aurora/store/data/installer/AMInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/AMInstaller.kt index bdb37bc98..4457595f3 100644 --- a/app/src/main/java/com/aurora/store/data/installer/AMInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/AMInstaller.kt @@ -2,14 +2,16 @@ package com.aurora.store.data.installer import android.content.Context import android.content.Intent -import androidx.core.content.FileProvider import com.aurora.store.data.room.download.Download import com.aurora.store.util.Log -import java.io.* +import com.aurora.store.util.PackageUtil.isSharedLibraryInstalled +import com.aurora.store.util.PathUtil +import java.io.File import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream class AMInstaller(context: Context) : InstallerBase(context) { + companion object { const val AM_PACKAGE_NAME = "io.github.muntashirakon.AppManager" const val AM_DEBUG_PACKAGE_NAME = "io.github.muntashirakon.AppManager.debug" @@ -20,50 +22,46 @@ class AMInstaller(context: Context) : InstallerBase(context) { Log.i("${download.packageName} already queued") } else { Log.i("Received AM install request for ${download.packageName}") - val fileList = - getFiles(download.packageName, download.versionCode).map { it.absolutePath } - when { - fileList.size == 1 -> { - xInstall(File(fileList.first())) - } - fileList.size > 1 -> { - val apks = zipFile(fileList) - xInstall(apks) - } - else -> { - throw Exception("Invalid data, expecting non empty fileList") + val fileList = mutableListOf() + + download.sharedLibs.forEach { + // Shared library packages cannot be updated + if (!isSharedLibraryInstalled(context, it.packageName, it.versionCode)) { + fileList.addAll( + getFiles( + download.packageName, + download.versionCode, + it.packageName + ) + ) } } + + val zipFile = PathUtil.getZipFile(context, download.packageName, download.versionCode) + fileList.add(zip(getFiles(download.packageName, download.versionCode), zipFile)) + + install(fileList) } } - private fun xInstall(file: File) { - val intent = Intent(Intent.ACTION_VIEW) - intent.setDataAndType( - FileProvider.getUriForFile( - context, - context.applicationContext.packageName + ".fileProvider", - file - ), "application/octet-stream" - ); - intent.flags = - Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION + private fun install(files: List) { + val intent = Intent(Intent.ACTION_SEND_MULTIPLE).apply { + type = "application/x-apks" + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION + putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(files.map { getUri(it) })) + } context.startActivity(intent) } - @Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") - private fun zipFile(files: List): File { - val outPath = File(files.first()).parentFile.absolutePath + "/bundle.apks" - val out = ZipOutputStream(BufferedOutputStream(FileOutputStream(outPath))) - for (file in files) { - val fi = FileInputStream(file) - val origin = BufferedInputStream(fi) - val entry = ZipEntry(file.substring(file.lastIndexOf("/"))) - out.putNextEntry(entry) - origin.copyTo(out, 1024) - origin.close() + fun zip(files: List, zipFile: File): File { + ZipOutputStream(zipFile.outputStream()).use { zipOutput -> + files.forEach { file -> + file.inputStream().use { input -> + zipOutput.putNextEntry(ZipEntry(file.name)) + input.copyTo(zipOutput) + } + } } - out.close() - return File(outPath) + return zipFile } } diff --git a/app/src/main/java/com/aurora/store/data/installer/InstallerBase.kt b/app/src/main/java/com/aurora/store/data/installer/InstallerBase.kt index fe505cd96..60d5dcc51 100644 --- a/app/src/main/java/com/aurora/store/data/installer/InstallerBase.kt +++ b/app/src/main/java/com/aurora/store/data/installer/InstallerBase.kt @@ -25,7 +25,6 @@ import androidx.core.content.FileProvider import com.aurora.store.AuroraApplication import com.aurora.store.BuildConfig import com.aurora.store.data.event.InstallerEvent -import com.aurora.store.data.room.download.Download import com.aurora.store.util.Log import com.aurora.store.util.PathUtil import org.greenrobot.eventbus.EventBus diff --git a/app/src/main/java/com/aurora/store/util/PathUtil.kt b/app/src/main/java/com/aurora/store/util/PathUtil.kt index 8502c7196..de7f8dc55 100644 --- a/app/src/main/java/com/aurora/store/util/PathUtil.kt +++ b/app/src/main/java/com/aurora/store/util/PathUtil.kt @@ -90,6 +90,20 @@ object PathUtil { ) + "/${file.name}" } + fun getZipFile( + context: Context, + packageName: String, + versionCode: Int + ): File { + return File( + getAppDownloadDir( + context, + packageName, + versionCode, + ), "${packageName}_${versionCode}.apks" + ) + } + fun getExternalPath(context: Context): String { val defaultDir = File("${Environment.getExternalStorageDirectory().absolutePath}/Aurora/Store")