AMInstaller: Support installing shared libraries as well

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2024-02-07 21:12:48 +01:00
parent 59b38f9ac4
commit cb584db2e4
3 changed files with 50 additions and 39 deletions

View File

@@ -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<File>()
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<File>) {
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<String>): 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<File>, 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
}
}

View File

@@ -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

View File

@@ -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")