Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.nekohasekai.sagernet.ui

import io.nekohasekai.sagernet.R
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import org.xmlpull.v1.XmlPullParser

@RunWith(RobolectricTestRunner::class)
@Config(sdk = [35], application = android.app.Application::class)
class ShortcutTargetPackageTest {

@Test
fun shortcutIntents_targetCurrentApplicationVariant() {
val application = RuntimeEnvironment.getApplication()
val resources = application.resources
val shortcutIds = mutableListOf<String>()
var intentCount = 0
val parser = resources.getXml(R.xml.shortcuts)

try {
while (parser.eventType != XmlPullParser.END_DOCUMENT) {
if (parser.eventType == XmlPullParser.START_TAG) {
when (parser.name) {
"shortcut" -> {
val shortcutId =
parser.getAttributeValue(ANDROID_NAMESPACE, "shortcutId").orEmpty()
shortcutIds += shortcutId
}

"intent" -> {
intentCount++
assertEquals(
application.packageName,
parser.getAttributeValue(ANDROID_NAMESPACE, "targetPackage"),
)
assertEquals(
0,
parser.getAttributeResourceValue(
ANDROID_NAMESPACE,
"targetPackage",
0,
),
)
assertTrue(
parser.getAttributeValue(ANDROID_NAMESPACE, "targetClass")
.orEmpty()
.isNotBlank(),
)
}
}
}
parser.next()
}
} finally {
parser.close()
}

assertEquals(4, intentCount)
assertEquals(4, shortcutIds.size)
assertEquals(setOf("toggle", "enable", "disable", "scan"), shortcutIds.toSet())
}

private companion object {
const val ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android"
}
}
43 changes: 43 additions & 0 deletions buildSrc/src/main/kotlin/Helpers.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import org.gradle.api.DefaultTask
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.getByName
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.withType
Expand Down Expand Up @@ -228,6 +235,20 @@ fun Project.setupApp() {
// The preview flavor uses PRE_VERSION_NAME to match the previous behaviour.
val previewVersionName = requireMetadata().getProperty("PRE_VERSION_NAME")
androidComponents.onVariants { variant ->
val shortcutResourcesTask = tasks.register<GenerateShortcutResourcesTask>(
"generate${variant.name.replaceFirstChar { it.uppercase() }}ShortcutResources",
) {
val effectivePackageName = if (variant.buildType == "debug") "$pkgName.debug" else pkgName
targetPackage.set(effectivePackageName)
outputDirectory.set(
layout.buildDirectory.dir("generated/shortcutResources/${variant.name}"),
)
}
variant.sources.res?.addGeneratedSourceDirectory(
shortcutResourcesTask,
GenerateShortcutResourcesTask::outputDirectory,
)

val isPreview = variant.flavorName == "preview" ||
variant.productFlavors.any { (_, flavor) -> flavor == "preview" }
val version = if (isPreview) previewVersionName else verName
Expand All @@ -243,3 +264,25 @@ fun Project.setupApp() {
.toListenTo(SingleArtifact.APK)
}
}

@CacheableTask
abstract class GenerateShortcutResourcesTask : DefaultTask() {
@get:Input
abstract val targetPackage: Property<String>

@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty

@TaskAction
fun generate() {
val xmlDirectory = outputDirectory.dir("xml").get().asFile.apply { mkdirs() }
xmlDirectory.resolve("shortcuts.xml").writeText(renderShortcuts(targetPackage.get()))
}

private fun renderShortcuts(packageName: String): String {
val template = checkNotNull(javaClass.getResourceAsStream("/shortcuts-template.xml")) {
"shortcuts-template.xml resource not found"
}.bufferedReader().use { it.readText() }
return template.replace("{{TARGET_PACKAGE}}", packageName)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<intent
android:action="android.intent.action.MAIN"
android:targetClass="io.nekohasekai.sagernet.QuickToggleShortcut"
android:targetPackage="com.nb4a" />
android:targetPackage="{{TARGET_PACKAGE}}" />
</shortcut>
<shortcut
android:icon="@drawable/ic_qu_shadowsocks_launcher"
Expand All @@ -18,7 +18,7 @@
<intent
android:action="android.intent.action.MAIN"
android:targetClass="io.nekohasekai.sagernet.ui.QuickEnableShortcut"
android:targetPackage="com.nb4a" />
android:targetPackage="{{TARGET_PACKAGE}}" />
</shortcut>
<shortcut
android:icon="@drawable/ic_qu_shadowsocks_launcher"
Expand All @@ -28,7 +28,7 @@
<intent
android:action="android.intent.action.MAIN"
android:targetClass="io.nekohasekai.sagernet.ui.QuickDisableShortcut"
android:targetPackage="com.nb4a" />
android:targetPackage="{{TARGET_PACKAGE}}" />
</shortcut>
<shortcut
android:icon="@drawable/ic_qu_camera_launcher"
Expand All @@ -38,6 +38,6 @@
<intent
android:action="android.intent.action.MAIN"
android:targetClass="io.nekohasekai.sagernet.ui.ScannerActivity"
android:targetPackage="com.nb4a" />
android:targetPackage="{{TARGET_PACKAGE}}" />
</shortcut>
</shortcuts>
Loading