fix: implement usage of variant-specific applicationId in actions (fixes #1387)

This commit is contained in:
Akash Yadav
2024-01-22 19:43:04 +05:30
parent adee0d678b
commit 94449ada46
15 changed files with 40 additions and 74 deletions
@@ -27,6 +27,7 @@ import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.openApplicationModuleChooser
import com.itsaky.androidide.builder.model.UNKNOWN_PACKAGE
import com.itsaky.androidide.projects.IProjectManager
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.utils.IntentUtils
import com.itsaky.androidide.utils.flashError
@@ -38,7 +39,6 @@ import com.itsaky.androidide.utils.flashError
class LaunchAppAction(context: Context, override val order: Int) : EditorActivityAction() {
override val id: String = "ide.editor.launchInstalledApp"
override var requiresUIThread: Boolean = true
init {
@@ -46,6 +46,10 @@ class LaunchAppAction(context: Context, override val order: Int) : EditorActivit
icon = ContextCompat.getDrawable(context, R.drawable.ic_open_external)
}
companion object {
private val log = ILogger.newInstance("LaunchAppAction")
}
override fun prepare(data: ActionData) {
super.prepare(data)
data.getActivity() ?: run {
@@ -61,14 +65,26 @@ class LaunchAppAction(context: Context, override val order: Int) : EditorActivit
override suspend fun execAction(data: ActionData) {
openApplicationModuleChooser(data) { app ->
val packageName = app.packageName
if (packageName == UNKNOWN_PACKAGE) {
val variant = app.getSelectedVariant()
log.debug("Selected variant: ${variant?.name}")
if (variant == null) {
flashError(R.string.err_selected_variant_not_found)
return@openApplicationModuleChooser
}
val applicationId = variant.mainArtifact.applicationId
if (applicationId == null) {
log.error("Unable to launch application. variant.mainArtifact.applicationId is null")
flashError(R.string.err_cannot_determine_package)
return@openApplicationModuleChooser
}
log.info("Launching application: $applicationId")
val activity = data.requireActivity()
IntentUtils.launchApp(activity, packageName, logError = false)
IntentUtils.launchApp(activity, applicationId, logError = false)
}
}
-1
View File
@@ -28,7 +28,6 @@ plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.maven.publish) apply false
alias(libs.plugins.gradle.publish) apply false
}
View File
-1
View File
@@ -148,6 +148,5 @@ maven-publish = { module = "com.vanniktech:gradle-maven-publish-plugin", version
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
maven-publish = { id = "com.vanniktech.maven.publish.base", version.ref = "maven-publish-plugin" }
gradle-publish = { id = "com.gradle.plugin-publish", version = "1.2.1" }
@@ -66,7 +66,6 @@ import java.util.concurrent.CompletableFuture
* @param buildDir The build directory of the project.
* @param buildScript The Gradle buildscript file of the project.
* @param tasks The tasks of the project.
* @param packageName The package name of this module extracted from `AndroidManifest.xml`.
* @param resourcePrefix The resource prefix.
* @param namespace The namespace of this project. As defined in the buildscript.
* @param androidTestNamespace The androidTestNamespace of this project. As defined in the
@@ -95,7 +94,6 @@ open class AndroidModule( // Class must be open because BaseXMLTest mocks this..
buildDir: File,
buildScript: File,
tasks: List<GradleTask>,
open val packageName: String, // Property must be open because BaseXMLTest mocks this...
val resourcePrefix: String?,
val namespace: String?,
val androidTestNamespace: String?,
@@ -306,24 +304,23 @@ open class AndroidModule( // Class must be open because BaseXMLTest mocks this..
/** Get the resource table for this module i.e. without resource tables for dependent modules. */
fun getResourceTable(): ResourceTable? {
if (this.packageName == UNKNOWN_PACKAGE) {
return null
}
val namespace = this.namespace ?: return null
val resDirs = mainSourceSet?.sourceProvider?.resDirectories ?: return null
return ResourceTableRegistry.getInstance().forPackage(this.packageName, *resDirs.toTypedArray())
return ResourceTableRegistry.getInstance().forPackage(namespace, *resDirs.toTypedArray())
}
/** Updates the resource table for this module. */
fun updateResourceTable() {
if (this.packageName == UNKNOWN_PACKAGE) {
if (this.namespace == null) {
return
}
CompletableFuture.runAsync {
val tableRegistry = ResourceTableRegistry.getInstance()
val resDirs = mainSourceSet?.sourceProvider?.resDirectories ?: return@runAsync
tableRegistry.removeTable(this.packageName)
tableRegistry.forPackage(this.packageName, *resDirs.toTypedArray())
tableRegistry.removeTable(this.namespace)
tableRegistry.forPackage(this.namespace, *resDirs.toTypedArray())
}
}
@@ -99,7 +99,6 @@ class ProjectTransformer {
buildDir = metadata.buildDir,
buildScript = metadata.buildScript,
tasks = project.getTasks().get(),
packageName = metadata.packageName,
resourcePrefix = metadata.resourcePrefix,
namespace = metadata.namespace,
androidTestNamespace = metadata.androidTestNamespace,
@@ -66,16 +66,6 @@ internal class AndroidProjectImpl(
private val serialVersionUID = 1L
private var shouldLookupPackage = true
var packageName: String = UNKNOWN_PACKAGE
get() {
if (field == UNKNOWN_PACKAGE && shouldLookupPackage) {
findPackageName()
}
return field
}
override fun getConfiguredVariant(): CompletableFuture<String> {
return CompletableFuture.completedFuture(this.configuredVariant)
}
@@ -190,7 +180,7 @@ internal class AndroidProjectImpl(
val viewBindingOptions = androidProject.viewBindingOptions?.let(
AndroidModulePropertyCopier::copy) ?: DefaultViewBindingOptions()
return@supplyAsync AndroidProjectMetadata(gradleMetadata, packageName,
return@supplyAsync AndroidProjectMetadata(gradleMetadata,
basicAndroidProject.projectType, copy(androidProject.flags),
copy(androidProject.javaCompileOptions), viewBindingOptions, androidProject.resourcePrefix,
androidProject.namespace, androidProject.androidTestNamespace,
@@ -198,31 +188,6 @@ internal class AndroidProjectImpl(
}
}
private fun findPackageName() {
val namespace = androidProject.namespace
if (namespace.isNotBlank()) {
this.packageName = namespace
this.shouldLookupPackage = false
return
}
val mainSourceSet = basicAndroidProject.mainSourceSet
if (mainSourceSet == null) {
shouldLookupPackage = false
return
}
val manifestFile = mainSourceSet.sourceProvider.manifestFile
if (manifestFile == DefaultSourceProvider.NoFile) {
shouldLookupPackage = false
return
}
this.packageName = extractPackageName(manifestFile) ?: UNKNOWN_PACKAGE
this.shouldLookupPackage = false
}
private fun AndroidArtifact.computeApplicationId(variantName: String): String? {
val minAgpForAppId = AndroidPluginVersion(7, 4, 0)
return if (minAgpForAppId <= AndroidPluginVersion.parse(versions.agp)) {
@@ -73,7 +73,7 @@ internal fun performBasicProjectAssertions(project: IProject, server: IToolingAp
assertThat(metadata.javaCompileOptions.isCoreLibraryDesugaringEnabled).isFalse()
assertThat(metadata.androidType)
.isEqualTo(com.android.builder.model.v2.ide.ProjectType.APPLICATION)
assertThat(metadata.packageName).isEqualTo("com.itsaky.test.app")
assertThat(metadata.namespace).isEqualTo("com.itsaky.test.app")
assertThat(metadata.viewBindingOptions).isNotNull()
assertThat(metadata.viewBindingOptions.isEnabled).isTrue()
@@ -36,7 +36,6 @@ class AndroidProjectMetadata(
description: String?,
buildScript: File,
type: ProjectType,
val packageName: String,
val androidType: AndroidProjectType,
val flags: DefaultAndroidGradlePluginProjectFlags,
val javaCompileOptions: DefaultJavaCompileOptions,
@@ -51,7 +50,6 @@ class AndroidProjectMetadata(
constructor(
base: ProjectMetadata,
packageName: String,
androidType: AndroidProjectType,
flags: DefaultAndroidGradlePluginProjectFlags,
javaCompileOptiosn: DefaultJavaCompileOptions,
@@ -70,7 +68,6 @@ class AndroidProjectMetadata(
base.description,
base.buildScript,
base.type,
packageName,
androidType,
flags,
javaCompileOptiosn,
-1
View File
@@ -15,7 +15,6 @@
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
id("com.android.library")
kotlin("android")
@@ -20,7 +20,6 @@ package com.itsaky.androidide.testing.android
import android.content.Context
import androidx.annotation.StringRes
import androidx.test.core.app.ApplicationProvider
import com.itsaky.androidide.app.BaseApplication
/**
* Get the application context.
@@ -28,11 +27,6 @@ import com.itsaky.androidide.app.BaseApplication
fun <AppContext : Context> getApplicationContext(): AppContext =
ApplicationProvider.getApplicationContext()
/**
* Get the [BaseApplication] instance.
*/
fun getBaseApplication() = getApplicationContext<BaseApplication>()
/**
* Get the value of the string resource.
*/
@@ -19,6 +19,7 @@ package com.itsaky.androidide.testing.android
import android.app.Activity
import android.app.UiAutomation
import android.content.Context
import android.content.Intent
import androidx.test.core.app.ApplicationProvider
import androidx.test.platform.app.InstrumentationRegistry
@@ -29,7 +30,6 @@ import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiDeviceAccessor
import androidx.test.uiautomator.Until
import com.google.common.truth.Truth.assertThat
import com.itsaky.androidide.app.BaseApplication
import com.itsaky.androidide.buildinfo.BuildInfo
import com.itsaky.androidide.utils.uncheckedCast
@@ -60,7 +60,7 @@ fun launchAndroidIDE(
}
// Launch the app
val context = ApplicationProvider.getApplicationContext<BaseApplication>()
val context = ApplicationProvider.getApplicationContext<Context>()
val intent = context.packageManager.getLaunchIntentForPackage(BuildInfo.PACKAGE_NAME)
assertThat(intent).isNotNull()
+2 -2
View File
@@ -15,10 +15,10 @@
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
@Suppress("JavaPluginLanguageLevel")
plugins {
//noinspection JavaPluginLanguageLevel
id("java-library")
alias(libs.plugins.kotlin.jvm)
id("org.jetbrains.kotlin.jvm")
}
dependencies {
+7 -6
View File
@@ -26,13 +26,14 @@ android {
dependencies {
api(libs.androidx.core.ktx)
api(libs.common.kotlin)
api(projects.lsp.api)
api(projects.actions)
api(projects.eventbusAndroid)
api(libs.common.editor)
api(libs.common.kotlin)
api(projects.actions)
api(projects.common)
api(projects.eventbusAndroid)
api(projects.lsp.api)
api(projects.testing.common)
api(projects.testing.tooling)
api(projects.testing.unit)
@@ -101,7 +101,7 @@ fun processXmlFile(file: File, expectedType: AaptResourceType): Pair<XmlProcesso
?: throw InflateException("Cannot find module for given file. Is the project initialized?")
val resFile =
ResourceFile(
ResourceName(module.packageName, pathData.type!!, pathData.name),
ResourceName(module.namespace, pathData.type!!, pathData.name),
pathData.config,
pathData.source,
ProtoXml