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
47 changes: 28 additions & 19 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,50 @@ allprojects {
lockAllConfigurations()
}
}

val projectDependencyEdges = allprojects.flatMap { project ->
project.configurations.flatMap { configuration ->
configuration.dependencies.withType<ProjectDependency>().map { dependency ->
Triple(project.path, configuration.name, dependency.path)
}
}
}

tasks.register("verifyArchitecture") {
doLast {
rootProject.allprojects.forEach { project ->
project.configurations.forEach { configuration ->
configuration.dependencies.withType<ProjectDependency>().forEach { dependency ->
val target = dependency.path
when {
project.path.startsWith(":core") && (target.startsWith(":feature") || target.startsWith(":apps")) -> error("Forbidden dependency: ${project.path} -> $target")
project.path.startsWith(":processing") && (target.startsWith(":feature") || target.startsWith(":apps")) -> error("Forbidden dependency: ${project.path} -> $target")
project.path.startsWith(":feature") && target.startsWith(":feature") && target != project.path -> error("Feature-to-feature dependency: ${project.path} -> $target")
}
}
projectDependencyEdges.forEach { (projectPath, _, target) ->
when {
projectPath.startsWith(":core") && (target.startsWith(":feature") || target.startsWith(":apps")) -> error("Forbidden dependency: $projectPath -> $target")
projectPath.startsWith(":processing") && (target.startsWith(":feature") || target.startsWith(":apps")) -> error("Forbidden dependency: $projectPath -> $target")
projectPath.startsWith(":feature") && target.startsWith(":feature") && target != projectPath -> error("Feature-to-feature dependency: $projectPath -> $target")
}
}
}
}

val manifestFiles = fileTree(rootDir) { include("**/src/main/AndroidManifest.xml") }.files.toList()
val manifestContents = manifestFiles.associateWith { it.readText() }
val gradlePolicyFiles = fileTree(rootDir) {
include("**/*.gradle.kts")
include("**/*.toml")
exclude("build.gradle.kts")
}.files.toList()
val gradlePolicyContents = gradlePolicyFiles.associateWith { it.readText() }

tasks.register("verifyAndroidPrivacy") {
doLast {
fileTree(rootDir) { include("**/src/main/AndroidManifest.xml") }.forEach { manifest ->
val text = manifest.readText()
manifestContents.forEach { (manifest, text) ->
check(!text.contains("android.permission.INTERNET")) { "INTERNET permission found in $manifest" }
check(!text.contains("MANAGE_EXTERNAL_STORAGE")) { "Broad storage permission found in $manifest" }
check(!text.contains("READ_EXTERNAL_STORAGE")) { "Legacy storage permission found in $manifest" }
check(!text.contains("WRITE_EXTERNAL_STORAGE")) { "Legacy storage permission found in $manifest" }
}
val appManifest = file("apps/documents/src/main/AndroidManifest.xml").readText()
val appManifest = manifestContents.getValue(file("apps/documents/src/main/AndroidManifest.xml"))
check(appManifest.contains("android:allowBackup=\"false\"")) { "Document backup must be disabled" }
check(appManifest.contains("androidx.core.content.FileProvider")) { "Secure FileProvider is required" }
check(appManifest.contains("android:exported=\"false\"")) { "FileProvider must not be exported" }
fileTree(rootDir) {
include("**/*.gradle.kts")
include("**/*.toml")
exclude("build.gradle.kts")
}.forEach { file ->
check(!file.readText().contains("jitpack.io")) { "JitPack found in $file" }
gradlePolicyContents.forEach { (file, text) ->
check(!text.contains("jitpack.io")) { "JitPack found in $file" }
}
}
}
Expand Down
1 change: 0 additions & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
org.gradle.caching=true
org.gradle.configuration-cache=true
android.useAndroidX=true
android.nonTransitiveRClass=true
kotlin.code.style=official
8 changes: 8 additions & 0 deletions android/gradle/verification-metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,9 @@
</artifact>
</component>
<component group="com.android.tools.build" name="aapt2" version="8.13.2-14304508">
<artifact name="aapt2-8.13.2-14304508-linux.jar">
<sha256 value="839609d6d776d6dd60a02aa577d97193ce3e650cf1deaabf062321e23bbd6bf6" origin="Verified from Google Maven"/>
</artifact>
<artifact name="aapt2-8.13.2-14304508-windows.jar">
<sha256 value="5dc730c3dc454b76d779a46036c06fd9c874039a31e22214434ecdbe64c3300a" origin="Generated by Gradle"/>
</artifact>
Expand Down Expand Up @@ -3294,6 +3297,11 @@
<sha256 value="4e5d1900e6379ef3f5970d04a8f30529adc82f859e8cc107c21ce8149ef666c4" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-bom" version="1.8.0">
<artifact name="kotlinx-coroutines-bom-1.8.0.pom">
<sha256 value="1239e9dbe1397cd5971342956b2511bc3ace7b641842e4372a088dcfa8b9ad55" origin="Verified from Maven Central"/>
</artifact>
</component>
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-bom" version="1.8.1">
<artifact name="kotlinx-coroutines-bom-1.8.1.pom">
<sha256 value="563e4aa29fa8fe09a6e1746d0a5b51308f7c7dedc468dc5a0ca810a485877030" origin="Generated by Gradle"/>
Expand Down
Loading