diff --git a/subprojects/xml-dom/src/main/java/org/eclipse/lemminx/dom/builder/alias.kt b/subprojects/xml-dom/src/main/java/org/eclipse/lemminx/dom/builder/alias.kt
new file mode 100644
index 000000000..6a0e9a4cb
--- /dev/null
+++ b/subprojects/xml-dom/src/main/java/org/eclipse/lemminx/dom/builder/alias.kt
@@ -0,0 +1,21 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AndroidIDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AndroidIDE. If not, see .
+ */
+
+package org.eclipse.lemminx.dom.builder
+
+typealias XmlConfigurator = XmlBuilder.() -> Unit
+typealias IndentedXmlConfigurator = IndentedXmlBuilder.() -> Unit
\ No newline at end of file
diff --git a/templates-api/src/main/assets/templates/base/module/android/res/xml/backup_rules.xml b/templates-api/src/main/assets/templates/base/module/android/res/xml/backup_rules.xml
new file mode 100644
index 000000000..9b42d90d9
--- /dev/null
+++ b/templates-api/src/main/assets/templates/base/module/android/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/templates-api/src/main/assets/templates/base/module/android/res/xml/data_extraction_rules.xml b/templates-api/src/main/assets/templates/base/module/android/res/xml/data_extraction_rules.xml
new file mode 100644
index 000000000..c6c3bb05a
--- /dev/null
+++ b/templates-api/src/main/assets/templates/base/module/android/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates-api/src/main/java/com/itsaky/androidide/templates/base/modules/android/manifest.kt b/templates-api/src/main/java/com/itsaky/androidide/templates/base/modules/android/manifest.kt
index 38827fff8..44c654577 100644
--- a/templates-api/src/main/java/com/itsaky/androidide/templates/base/modules/android/manifest.kt
+++ b/templates-api/src/main/java/com/itsaky/androidide/templates/base/modules/android/manifest.kt
@@ -17,12 +17,23 @@
package com.itsaky.androidide.templates.base.modules.android
+import org.eclipse.lemminx.dom.builder.IndentedXmlConfigurator
+
/**
* Model for activities declared in [AndroidManifestBuilder].
*
+ * @param name The name of the activity (for `android:name` attribute).
+ * @param isExported Sets the `android:exported` attribute.
+ * @param isLauncher Adds the `intent-filter` for setting this activity as the launcher activity.
+ * @param configureAttrs Function for configuring additional attributes for this activity.
+ * @param configureInside Function for configuring additional elements inside this activity tag.
* @author Akash Yadav
*/
-data class ManifestActivity(val name: String, val isExported: Boolean, val isLauncher: Boolean = false)
+data class ManifestActivity(val name: String, val isExported: Boolean,
+ val isLauncher: Boolean = false,
+ val configureAttrs: IndentedXmlConfigurator? = null,
+ val configureInside: IndentedXmlConfigurator? = null
+)
/**
* Model for icon values in [AndroidManifestBuilder].
diff --git a/templates-api/src/main/java/com/itsaky/androidide/templates/base/util/AndroidManifestBuilder.kt b/templates-api/src/main/java/com/itsaky/androidide/templates/base/util/AndroidManifestBuilder.kt
index 49799884b..ea1211898 100644
--- a/templates-api/src/main/java/com/itsaky/androidide/templates/base/util/AndroidManifestBuilder.kt
+++ b/templates-api/src/main/java/com/itsaky/androidide/templates/base/util/AndroidManifestBuilder.kt
@@ -30,8 +30,13 @@ import com.android.SdkConstants.XMLNS
import com.itsaky.androidide.templates.RecipeExecutor
import com.itsaky.androidide.templates.base.modules.android.ManifestActivity
import com.itsaky.androidide.templates.base.modules.android.ManifestIcon
+import com.itsaky.androidide.templates.base.util.AndroidManifestBuilder.ConfigurationType.APPLICATION_ATTR
+import com.itsaky.androidide.templates.base.util.AndroidManifestBuilder.ConfigurationType.APPLICATION_CONTENT
+import com.itsaky.androidide.templates.base.util.AndroidManifestBuilder.ConfigurationType.MANIFEST_ATTR
+import com.itsaky.androidide.templates.base.util.AndroidManifestBuilder.ConfigurationType.MANIFEST_CONTENT
import com.itsaky.androidide.xml.permissions.Permission
import org.eclipse.lemminx.dom.builder.IndentedXmlBuilder
+import org.eclipse.lemminx.dom.builder.IndentedXmlConfigurator
import java.io.File
/**
@@ -41,6 +46,31 @@ import java.io.File
*/
class AndroidManifestBuilder {
+ enum class ConfigurationType {
+
+ /**
+ * For configuring attributes for the `` tag.
+ */
+ MANIFEST_ATTR,
+
+ /**
+ * For configuring elements inside the `` tag.
+ */
+ MANIFEST_CONTENT,
+
+ /**
+ * For configuring attributes for the `` tag.
+ */
+ APPLICATION_ATTR,
+
+ /**
+ * For configuring elements inside the `` tag.
+ */
+ APPLICATION_CONTENT
+ }
+
+ private val configurators =
+ hashMapOf>()
private val permissions = hashSetOf()
private val activities = hashSetOf()
@@ -94,6 +124,11 @@ class AndroidManifestBuilder {
activities.add(activity)
}
+ fun configure(type: ConfigurationType, configurator: IndentedXmlConfigurator
+ ) {
+ configurators.computeIfAbsent(type) { hashSetOf() }.add(configurator)
+ }
+
/**
* Generates the manifest and saves the content to the given file.
*/
@@ -110,9 +145,13 @@ class AndroidManifestBuilder {
private fun IndentedXmlBuilder.buildManifest() {
createElement(TAG_MANIFEST) {
attr(name = ANDROID_NS_NAME, value = ANDROID_URI, ns = XMLNS)
+ configurators[MANIFEST_ATTR]?.forEach { configurator -> configurator() }
closeStartElement()
permissions()
+
+ configurators[MANIFEST_CONTENT]?.forEach { configurator -> configurator() }
+
application()
}
}
@@ -141,9 +180,12 @@ class AndroidManifestBuilder {
androidAttr("label", "@string/${appLabelRes}")
androidAttr("supportsRtl", rtl.toString())
androidAttr("theme", "@style/${themeRes}")
+ configurators[APPLICATION_ATTR]?.forEach { configurator -> configurator() }
closeStartElement()
activities()
+
+ configurators[APPLICATION_CONTENT]?.forEach { configurator -> configurator() }
}
}
@@ -159,10 +201,14 @@ class AndroidManifestBuilder {
androidAttr("exported", "true")
}
+ activity.configureAttrs?.invoke(this@activities)
closeStartElement()
+
if (activity.isLauncher) {
intentFilter()
}
+
+ activity.configureInside?.invoke(this@activities)
}
}
}