mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
fix: implement usage of variant-specific applicationId in actions (fixes #1387)
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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" }
|
||||
|
||||
+6
-9
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -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,
|
||||
|
||||
+1
-36
@@ -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)) {
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
|
||||
-3
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
+2
-2
@@ -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()
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user