Return pkgName for extension install

This commit is contained in:
Syer10
2026-07-12 22:54:36 -04:00
parent a66649715e
commit 4fdef7d17d
3 changed files with 26 additions and 36 deletions

View File

@@ -179,10 +179,10 @@ class ExtensionMutation {
val (clientMutationId, extensionFile) = input val (clientMutationId, extensionFile) = input
return future { return future {
Extension.installExternalExtension(extensionFile.content(), extensionFile.filename()) val pkgName = Extension.installExternalExtension(extensionFile.content(), extensionFile.filename())
val dbExtension = val dbExtension =
transaction { ExtensionTable.selectAll().where { ExtensionTable.apkName eq extensionFile.filename() }.first() } transaction { ExtensionTable.selectAll().where { ExtensionTable.pkgName eq pkgName }.first() }
InstallExternalExtensionPayload( InstallExternalExtensionPayload(
clientMutationId, clientMutationId,

View File

@@ -63,8 +63,6 @@ object ExtensionController {
ctx.future { ctx.future {
future { future {
Extension.installExtension(pkgName) Extension.installExtension(pkgName)
}.thenApply {
ctx.status(it)
} }
} }
}, },
@@ -99,8 +97,6 @@ object ExtensionController {
uploadedFile.content(), uploadedFile.content(),
uploadedFile.filename(), uploadedFile.filename(),
) )
}.thenApply {
ctx.status(it)
} }
} }
}, },
@@ -126,8 +122,6 @@ object ExtensionController {
ctx.future { ctx.future {
future { future {
Extension.updateExtension(pkgName) Extension.updateExtension(pkgName)
}.thenApply {
ctx.status(it)
} }
} }
}, },

View File

@@ -80,7 +80,7 @@ object Extension {
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
private val applicationDirs: ApplicationDirs by injectLazy() private val applicationDirs: ApplicationDirs by injectLazy()
suspend fun installExtension(pkgName: String): Int { suspend fun installExtension(pkgName: String): String {
logger.debug { "Installing $pkgName" } logger.debug { "Installing $pkgName" }
val extension = val extension =
transaction { transaction {
@@ -119,7 +119,7 @@ object Extension {
suspend fun installExternalExtension( suspend fun installExternalExtension(
inputStream: InputStream, inputStream: InputStream,
extensionName: String, extensionName: String,
): Int { ): String {
val copyToExtensionsRoot = { val copyToExtensionsRoot = {
val rootPath = Path(applicationDirs.extensionsRoot) val rootPath = Path(applicationDirs.extensionsRoot)
val downloadedFile = rootPath.resolve(extensionName).normalize() val downloadedFile = rootPath.resolve(extensionName).normalize()
@@ -147,21 +147,22 @@ object Extension {
suspend fun installAPK( suspend fun installAPK(
forceReinstall: Boolean = false, forceReinstall: Boolean = false,
fetcher: suspend () -> String, fetcher: suspend () -> String,
): Int { ): String {
val apkFile = Path(fetcher()) val apkFile = Path(fetcher())
val packageInfo = getPackageInfo(apkFile)
val pkgName = packageInfo.packageName
// check if we don't have the extension already installed // check if we don't have the extension already installed
// if it's installed and we want to update, it first has to be uninstalled // if it's installed and we want to update, it first has to be uninstalled
val isInstalled = val isInstalled =
transaction { transaction {
ExtensionTable.selectAll().where { ExtensionTable.apkName eq apkFile.name }.firstOrNull() ExtensionTable.select(ExtensionTable.isInstalled).where { ExtensionTable.pkgName eq pkgName }.firstOrNull()
}?.get(ExtensionTable.isInstalled) ?: false }?.get(ExtensionTable.isInstalled) ?: false
val dirPathWithoutType = "${applicationDirs.extensionsRoot}/${apkFile.nameWithoutExtension}" val dirPathWithoutType = "${applicationDirs.extensionsRoot}/${apkFile.nameWithoutExtension}"
val jarFile = Path("$dirPathWithoutType.jar") val jarFile = Path("$dirPathWithoutType.jar")
val packageInfo = getPackageInfo(apkFile)
val pkgName = packageInfo.packageName
if (isInstalled && forceReinstall) { if (isInstalled && forceReinstall) {
uninstallExtension(pkgName) uninstallExtension(pkgName)
} }
@@ -210,7 +211,7 @@ object Extension {
val className = val className =
if (sourceClass.startsWith(".")) { if (sourceClass.startsWith(".")) {
packageInfo.packageName + sourceClass pkgName + sourceClass
} else { } else {
sourceClass sourceClass
} }
@@ -219,7 +220,7 @@ object Extension {
dex2jar(apkFile, jarFile) dex2jar(apkFile, jarFile)
extractAssetsFromApk(apkFile, jarFile) extractAssetsFromApk(apkFile, jarFile)
extractAndCacheApkIcon(apkFile, packageInfo.packageName) extractAndCacheApkIcon(apkFile, pkgName)
// clean up // clean up
apkFile.deleteIfExists() apkFile.deleteIfExists()
@@ -243,13 +244,11 @@ object Extension {
extensionName, extensionName,
extensionLibVersion, extensionLibVersion,
apkFile.name, apkFile.name,
packageInfo.packageName, pkgName,
packageInfo.versionName, packageInfo.versionName,
packageInfo.versionCode, packageInfo.versionCode,
contentWarning contentWarning
) )
return 201 // we installed successfully
} catch (e: Throwable) { } catch (e: Throwable) {
// free up the file descriptor if exists // free up the file descriptor if exists
PackageTools.jarLoaderMap.remove(jarFile.absolutePathString())?.close() PackageTools.jarLoaderMap.remove(jarFile.absolutePathString())?.close()
@@ -261,35 +260,35 @@ object Extension {
} }
throw e throw e
} }
} else {
return 302 // extension was already installed
} }
return pkgName
} }
suspend fun installJAR( suspend fun installJAR(
forceReinstall: Boolean = false, forceReinstall: Boolean = false,
fetcher: suspend () -> String, fetcher: suspend () -> String,
): Int { ): String {
val jarFile = Path(fetcher()) val jarFile = Path(fetcher())
// check if we don't have the extension already installed
// if it's installed and we want to update, it first has to be uninstalled
val isInstalled =
transaction {
ExtensionTable.selectAll().where { ExtensionTable.apkName eq (jarFile.nameWithoutExtension + ".apk") }.firstOrNull()
}?.get(ExtensionTable.isInstalled) ?: false
val jarZip = ZipFile.builder() val jarZip = ZipFile.builder()
.setPath(jarFile) .setPath(jarFile)
.get() .get()
return jarZip.use { jarZip -> return jarZip.use { jarZip ->
val manifest = jarZip.getInputStream(jarZip.getEntry("AndroidManifest.xml")) val manifest = jarZip.getInputStream(jarZip.getEntry("AndroidManifest.xml"))
.use { .use {
AndroidManifestParser.parse(it) AndroidManifestParser.parse(it)
} }
val pkgName = manifest.packageName val pkgName = manifest.packageName
// check if we don't have the extension already installed
// if it's installed and we want to update, it first has to be uninstalled
val isInstalled =
transaction {
ExtensionTable.select(ExtensionTable.isInstalled).where { ExtensionTable.pkgName eq pkgName }.firstOrNull()
}?.get(ExtensionTable.isInstalled) ?: false
if (isInstalled && forceReinstall) { if (isInstalled && forceReinstall) {
uninstallExtension(pkgName) uninstallExtension(pkgName)
} }
@@ -362,13 +361,11 @@ object Extension {
extensionName, extensionName,
extensionLibVersion, extensionLibVersion,
jarFile.name.removeSuffix(".jar") + ".apk", jarFile.name.removeSuffix(".jar") + ".apk",
manifest.packageName, pkgName,
manifest.versionName, manifest.versionName,
manifest.versionCode!!, manifest.versionCode!!,
contentWarning contentWarning
) )
return@use 201 // we installed successfully
} catch (e: Throwable) { } catch (e: Throwable) {
// free up the file descriptor if exists // free up the file descriptor if exists
PackageTools.jarLoaderMap.remove(jarFile.absolutePathString())?.close() PackageTools.jarLoaderMap.remove(jarFile.absolutePathString())?.close()
@@ -379,9 +376,8 @@ object Extension {
} catch (_: Exception) {} } catch (_: Exception) {}
throw e throw e
} }
} else {
return@use 302 // extension was already installed
} }
return@use pkgName
} }
} }
@@ -613,7 +609,7 @@ object Extension {
} }
} }
suspend fun updateExtension(pkgName: String): Int { suspend fun updateExtension(pkgName: String): String {
val targetExtension = ExtensionsList.updateMap.remove(pkgName)!! val targetExtension = ExtensionsList.updateMap.remove(pkgName)!!
uninstallExtension(pkgName) uninstallExtension(pkgName)
transaction { transaction {