@dailephd/my-dev-kit-lab 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +46 -270
  2. package/dist/scripts/security/validate.js +177 -70
  3. package/dist/src/audits/codeRot/detectors/architectureDriftDetector.js +5 -2
  4. package/dist/src/audits/codeRot/detectors/securityValidationAssumptionRotDetector.js +5 -2
  5. package/dist/src/mobile/android/audit/androidFinding.js +68 -0
  6. package/dist/src/mobile/android/audit/checkResultBuilder.js +97 -0
  7. package/dist/src/mobile/android/audit/deepLinkAudit.js +183 -0
  8. package/dist/src/mobile/android/audit/exportedComponentAudit.js +183 -0
  9. package/dist/src/mobile/android/audit/intentFilterAudit.js +128 -0
  10. package/dist/src/mobile/android/audit/permissionAudit.js +142 -0
  11. package/dist/src/mobile/android/detect/androidTargetDetection.js +18 -0
  12. package/dist/src/mobile/android/detect/buildFileEvidence.js +36 -0
  13. package/dist/src/mobile/android/detect/classify.js +150 -0
  14. package/dist/src/mobile/android/detect/detectAndroidProject.js +252 -0
  15. package/dist/src/mobile/android/detect/settingsModules.js +60 -0
  16. package/dist/src/mobile/android/detect/sourceEvidence.js +92 -0
  17. package/dist/src/mobile/android/detect/traversal.js +79 -0
  18. package/dist/src/mobile/android/detect/versionCatalogEvidence.js +37 -0
  19. package/dist/src/mobile/android/detection.js +28 -0
  20. package/dist/src/mobile/android/gradle/gradleMetadataCheckResult.js +120 -0
  21. package/dist/src/mobile/android/gradle/moduleMetadataExtractor.js +137 -0
  22. package/dist/src/mobile/android/gradle/pluginVersionExtractor.js +40 -0
  23. package/dist/src/mobile/android/gradle/readAndroidGradleMetadata.js +210 -0
  24. package/dist/src/mobile/android/gradle/releaseMetadataSummary.js +64 -0
  25. package/dist/src/mobile/android/gradle/settingsMetadata.js +20 -0
  26. package/dist/src/mobile/android/gradle/types.js +1 -0
  27. package/dist/src/mobile/android/gradle/validate/executor.js +9 -0
  28. package/dist/src/mobile/android/gradle/validate/operationCheckResult.js +99 -0
  29. package/dist/src/mobile/android/gradle/validate/operations.js +68 -0
  30. package/dist/src/mobile/android/gradle/validate/planner.js +49 -0
  31. package/dist/src/mobile/android/gradle/validate/runOptionalGradleValidation.js +113 -0
  32. package/dist/src/mobile/android/gradle/validate/targetMutation.js +45 -0
  33. package/dist/src/mobile/android/gradle/validate/taskListParser.js +24 -0
  34. package/dist/src/mobile/android/gradle/versionCatalogMetadata.js +94 -0
  35. package/dist/src/mobile/android/gradle/wrapperMetadata.js +32 -0
  36. package/dist/src/mobile/android/manifest/parseAndroidManifest.js +341 -0
  37. package/dist/src/mobile/android/manifest/types.js +29 -0
  38. package/dist/src/mobile/android/manifest/xml/parseXml.js +313 -0
  39. package/dist/src/mobile/android/profile.js +29 -0
  40. package/dist/src/mobile/android/report/model.js +104 -0
  41. package/dist/src/mobile/android/report/renderAndroidReport.js +223 -0
  42. package/dist/src/mobile/android/report/writeAndroidReportFiles.js +23 -0
  43. package/dist/src/mobile/android/targetMetadata.js +27 -0
  44. package/dist/src/mobile/android/validate/androidVerdict.js +248 -0
  45. package/dist/src/mobile/android/validate/detectionAndImmutabilityCheckResults.js +177 -0
  46. package/dist/src/mobile/android/validate/playReadinessChecklist.js +145 -0
  47. package/dist/src/mobile/android/validate/validateAndroidTarget.js +172 -0
  48. package/dist/src/mobile/android/validation/checkResult.js +51 -0
  49. package/dist/src/mobile/android/validation/result.js +25 -0
  50. package/dist/src/mobile/index.js +42 -0
  51. package/dist/src/mobile/types.js +27 -0
  52. package/dist/src/securityValidation/attackScenarios/attackProfile.js +2 -0
  53. package/dist/src/securityValidation/attackScenarios/profiles/androidProfile.js +20 -0
  54. package/dist/src/securityValidation/validate/cliOptions.js +46 -2
  55. package/package.json +2 -1
  56. package/tests/fixtures/android/compose-app/app/build.gradle.kts +21 -0
  57. package/tests/fixtures/android/compose-app/app/src/main/AndroidManifest.xml +22 -0
  58. package/tests/fixtures/android/compose-app/app/src/main/java/com/example/composeapp/MainActivity.kt +11 -0
  59. package/tests/fixtures/android/compose-app/build.gradle.kts +4 -0
  60. package/tests/fixtures/android/compose-app/gradle/wrapper/gradle-wrapper.properties +4 -0
  61. package/tests/fixtures/android/compose-app/settings.gradle.kts +2 -0
  62. package/tests/fixtures/android/gradle-metadata-fixtures/catalog-only-plugin/build.gradle.kts +3 -0
  63. package/tests/fixtures/android/gradle-metadata-fixtures/catalog-only-plugin/gradle/libs.versions.toml +5 -0
  64. package/tests/fixtures/android/gradle-metadata-fixtures/comment-safety.gradle.kts +21 -0
  65. package/tests/fixtures/android/gradle-metadata-fixtures/dynamic-values.gradle.kts +17 -0
  66. package/tests/fixtures/android/gradle-metadata-fixtures/groovy-literal.gradle +23 -0
  67. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-malformed.properties +4 -0
  68. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-missing-url.properties +3 -0
  69. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-with-checksum.properties +5 -0
  70. package/tests/fixtures/android/java-app/app/build.gradle +16 -0
  71. package/tests/fixtures/android/java-app/app/src/main/AndroidManifest.xml +19 -0
  72. package/tests/fixtures/android/java-app/app/src/main/java/com/example/javaapp/MainActivity.java +4 -0
  73. package/tests/fixtures/android/java-app/build.gradle +3 -0
  74. package/tests/fixtures/android/java-app/gradle/wrapper/gradle-wrapper.properties +4 -0
  75. package/tests/fixtures/android/java-app/settings.gradle +2 -0
  76. package/tests/fixtures/android/library/build.gradle.kts +3 -0
  77. package/tests/fixtures/android/library/gradle/wrapper/gradle-wrapper.properties +4 -0
  78. package/tests/fixtures/android/library/mylibrary/build.gradle.kts +13 -0
  79. package/tests/fixtures/android/library/mylibrary/src/main/AndroidManifest.xml +2 -0
  80. package/tests/fixtures/android/library/settings.gradle.kts +2 -0
  81. package/tests/fixtures/android/manifest-audit-fixtures/incomplete-intent-filter.xml +14 -0
  82. package/tests/fixtures/android/manifest-audit-fixtures/malformed-exported.xml +10 -0
  83. package/tests/fixtures/android/manifest-audit-fixtures/malformed.xml +5 -0
  84. package/tests/fixtures/android/manifest-audit-fixtures/missing-application.xml +7 -0
  85. package/tests/fixtures/android/manifest-audit-fixtures/missing-component-name.xml +11 -0
  86. package/tests/fixtures/android/manifest-audit-fixtures/permission-coverage.xml +29 -0
  87. package/tests/fixtures/android/manifest-audit-fixtures/risky-components.xml +62 -0
  88. package/tests/fixtures/android/manifest-audit-fixtures/risky-deep-links.xml +45 -0
  89. package/tests/fixtures/android/manifest-audit-fixtures/unresolved-placeholder.xml +14 -0
  90. package/tests/fixtures/android/manifest-audit-fixtures/unusual-namespace-prefix.xml +11 -0
  91. package/tests/fixtures/android/multi-module/app/build.gradle.kts +22 -0
  92. package/tests/fixtures/android/multi-module/app/src/androidTest/java/com/example/multimodule/app/ExampleInstrumentedTest.kt +3 -0
  93. package/tests/fixtures/android/multi-module/app/src/main/AndroidManifest.xml +11 -0
  94. package/tests/fixtures/android/multi-module/app/src/test/java/com/example/multimodule/app/ExampleUnitTest.kt +3 -0
  95. package/tests/fixtures/android/multi-module/build.gradle.kts +5 -0
  96. package/tests/fixtures/android/multi-module/core/build.gradle.kts +14 -0
  97. package/tests/fixtures/android/multi-module/core/src/main/AndroidManifest.xml +2 -0
  98. package/tests/fixtures/android/multi-module/feature-login/build.gradle.kts +18 -0
  99. package/tests/fixtures/android/multi-module/feature-login/src/main/AndroidManifest.xml +2 -0
  100. package/tests/fixtures/android/multi-module/gradle/libs.versions.toml +8 -0
  101. package/tests/fixtures/android/multi-module/gradle/wrapper/gradle-wrapper.properties +4 -0
  102. package/tests/fixtures/android/multi-module/settings.gradle.kts +4 -0
  103. package/tests/fixtures/android/non-android-gradle/build.gradle.kts +3 -0
  104. package/tests/fixtures/android/non-android-gradle/core/build.gradle.kts +3 -0
  105. package/tests/fixtures/android/non-android-gradle/core/src/main/java/com/example/core/Core.java +4 -0
  106. package/tests/fixtures/android/non-android-gradle/gradle/wrapper/gradle-wrapper.properties +4 -0
  107. package/tests/fixtures/android/non-android-gradle/settings.gradle.kts +2 -0
  108. package/tests/fixtures/android/partial/app/build.gradle.kts +7 -0
  109. package/tests/fixtures/android/partial/settings.gradle.kts +2 -0
  110. package/tests/fixtures/android/xml-view-app/app/build.gradle.kts +17 -0
  111. package/tests/fixtures/android/xml-view-app/app/src/main/AndroidManifest.xml +31 -0
  112. package/tests/fixtures/android/xml-view-app/app/src/main/kotlin/com/example/xmlviewapp/MainActivity.kt +7 -0
  113. package/tests/fixtures/android/xml-view-app/app/src/main/res/layout/activity_main.xml +4 -0
  114. package/tests/fixtures/android/xml-view-app/build.gradle.kts +4 -0
  115. package/tests/fixtures/android/xml-view-app/gradle/wrapper/gradle-wrapper.properties +4 -0
  116. package/tests/fixtures/android/xml-view-app/settings.gradle.kts +2 -0
@@ -0,0 +1,20 @@
1
+ // ---------------------------------------------------------------------------
2
+ // v0.4.0 Batch 5 — registry placeholder for the "android" profile.
3
+ //
4
+ // Unlike the other three profiles, "android" does NOT route through the
5
+ // classic check-group/attack-scenario pipeline that this definition
6
+ // describes (src/mobile/android/validate/validateAndroidTarget.ts is an
7
+ // entirely separate orchestrator — see agents.txt Batch 5 section 6.1). This
8
+ // entry exists only so SECURITY_PROFILE_IDS including "android" satisfies
9
+ // PROFILE_REGISTRY's Record<SecurityProfileId, AttackProfileDefinition> type;
10
+ // its check-id lists are deliberately empty so nothing here ever appears to
11
+ // select or gate a classic check group for the Android path.
12
+ // ---------------------------------------------------------------------------
13
+ export const ANDROID_PROFILE = {
14
+ id: "android",
15
+ label: "Android",
16
+ description: "Profile for an Android Gradle project, validated through a dedicated Android orchestrator (detection, manifest audits, Gradle metadata, optional Gradle operations) rather than the classic check-group/attack-scenario pipeline this definition otherwise describes.",
17
+ defaultCheckIds: [],
18
+ applicableCheckIds: [],
19
+ scenarioGroups: [],
20
+ };
@@ -35,7 +35,15 @@ export const PLANNED_SECURITY_CHECK_IDS = [
35
35
  "network",
36
36
  ];
37
37
  export const DEFAULT_SECURITY_CHECKS = IMPLEMENTED_SECURITY_CHECK_IDS;
38
- export const SECURITY_PROFILE_IDS = ["node-cli-package", "local-tool", "npm-package"];
38
+ // v0.4.0 Batch 5 — "android" added additively. Unlike the other three
39
+ // profiles (which select --checks defaults for the classic
40
+ // check-group/attack-scenario pipeline), "android" routes to an entirely
41
+ // separate orchestrator (src/mobile/android/validate/validateAndroidTarget.ts)
42
+ // because the Android check/finding/status vocabulary established in
43
+ // Batches 1-4 does not fit SecurityCheckId/SecurityCheckResult — seeagents.txt
44
+ // Batch 5 section 6.1-6.2. The CLI still exposes it through the same
45
+ // --profile flag on the same security:validate command (no second CLI).
46
+ export const SECURITY_PROFILE_IDS = ["node-cli-package", "local-tool", "npm-package", "android"];
39
47
  export const DEFAULT_SECURITY_PROFILE = "node-cli-package";
40
48
  export const SECURITY_OUTPUT_FORMATS = ["text", "json"];
41
49
  export const DEFAULT_SECURITY_OUTPUT_FORMATS = ["text", "json"];
@@ -52,14 +60,31 @@ const FLAGS_WITH_VALUE = {
52
60
  "--profile": "profile",
53
61
  "--format": "format",
54
62
  "--fail-on": "failOn",
63
+ "--android-gradle-operations": "androidGradleOperations",
55
64
  };
65
+ // v0.4.0 Batch 5 — the exact allowlisted optional Gradle operation ids
66
+ // (agents.txt Batch 5 section 7.3). Deliberately re-declared here rather than
67
+ // imported from src/mobile/android/gradle/validate/operations.ts: this keeps
68
+ // the foundational CLI-parsing module free of a new securityValidation ->
69
+ // mobile dependency direction for five short string literals. Both lists
70
+ // must stay in sync; a regression test in tests/security/ asserts they do.
71
+ export const ANDROID_GRADLE_OPERATION_IDS = ["wrapper-version", "tasks", "assemble-debug", "unit-test-debug", "lint-debug"];
56
72
  export function parseSecurityValidateArgs(argv) {
57
73
  const result = {};
58
74
  for (let i = 0; i < argv.length; i++) {
59
75
  const arg = argv[i];
60
76
  const key = FLAGS_WITH_VALUE[arg];
61
- if (!key)
77
+ if (!key) {
78
+ // Keep the conventional argument separator harmless while rejecting
79
+ // misspelled or unsupported top-level options before any validation
80
+ // configuration, target resolution, or report work begins.
81
+ if (arg === "--")
82
+ continue;
83
+ if (arg.startsWith("-")) {
84
+ throw new Error(`Unknown option: ${arg}.`);
85
+ }
62
86
  continue;
87
+ }
63
88
  if (i + 1 >= argv.length) {
64
89
  throw new Error(`Missing value for ${arg}. Expected a value after ${arg}.`);
65
90
  }
@@ -73,6 +98,7 @@ export function normalizeSecurityValidateConfig(raw, toolRoot) {
73
98
  const formats = parseFormatOption(raw.format);
74
99
  const failOn = parseFailOnOption(raw.failOn);
75
100
  const out = raw.out !== undefined ? resolveOutDir(raw.out) : path.join(toolRoot, "reports", "security");
101
+ const androidGradleOperationIds = parseAndroidGradleOperationsOption(raw.androidGradleOperations, profile.value);
76
102
  return {
77
103
  target: raw.target,
78
104
  out,
@@ -88,8 +114,26 @@ export function normalizeSecurityValidateConfig(raw, toolRoot) {
88
114
  formatsWereDefault: formats.wasDefault,
89
115
  failOnThreshold: failOn.value,
90
116
  failOnWasDefault: failOn.wasDefault,
117
+ androidGradleOperationIds,
91
118
  };
92
119
  }
120
+ // Parses --android-gradle-operations. Absent by default (empty array — zero
121
+ // Gradle execution). Rejects unknown operation ids and non-"android"-profile
122
+ // usage before any validation work begins (agents.txt Batch 5 section 7.3).
123
+ function parseAndroidGradleOperationsOption(raw, profile) {
124
+ if (raw === undefined)
125
+ return [];
126
+ if (profile !== "android") {
127
+ throw new Error(`--android-gradle-operations requires --profile android (got --profile ${profile}).`);
128
+ }
129
+ const parts = splitAndNormalizeList(raw, "--android-gradle-operations");
130
+ const invalid = parts.filter((p) => !ANDROID_GRADLE_OPERATION_IDS.includes(p));
131
+ if (invalid.length > 0) {
132
+ throw new Error(`Invalid --android-gradle-operations value(s): ${invalid.join(", ")}. Valid values are: ${ANDROID_GRADLE_OPERATION_IDS.join(", ")}.`);
133
+ }
134
+ const unique = new Set(parts);
135
+ return ANDROID_GRADLE_OPERATION_IDS.filter((id) => unique.has(id));
136
+ }
93
137
  // ---------------------------------------------------------------------------
94
138
  // v0.2.2 Batch 5 — profile-aware default checks
95
139
  // ---------------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dailephd/my-dev-kit-lab",
3
- "version": "0.3.4",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "Evidence, benchmark, and evaluation companion for my-dev-kit.",
6
6
  "bin": {
@@ -71,6 +71,7 @@
71
71
  "test:plots": "vitest run tests/plots tests/commands/generateExperimentPlotsCommand.spec.ts",
72
72
  "test:visualization-demos": "vitest run tests/visualizationDemos tests/commands/runVisualizationDemosCommand.spec.ts",
73
73
  "verify:benchmarks": "tsx scripts/verify-benchmarks.ts",
74
+ "docs:check": "node scripts/check-docs.mjs",
74
75
  "verify": "npm run build && npm run test && npm run test:benchmarks && npm run test:report && npm run test:screenshot && npm run test:evaluation && npm run test:agents && npm run test:experiments && npm run test:plots && npm run test:visualization-demos && npm run test:gallery && npm run test:demo && npm run test:integration && npm run test:e2e && npm run verify:benchmarks",
75
76
  "security:deps": "tsx scripts/security/runDependencyChecks.ts",
76
77
  "security:package": "tsx scripts/security/runPackageChecks.ts",
@@ -0,0 +1,21 @@
1
+ plugins {
2
+ id("com.android.application")
3
+ id("org.jetbrains.kotlin.android")
4
+ }
5
+
6
+ android {
7
+ namespace = "com.example.composeapp"
8
+ compileSdk = 34
9
+
10
+ defaultConfig {
11
+ applicationId = "com.example.composeapp"
12
+ minSdk = 24
13
+ targetSdk = 34
14
+ versionCode = 1
15
+ versionName = "1.0"
16
+ }
17
+
18
+ buildFeatures {
19
+ compose = true
20
+ }
21
+ }
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+
4
+ <uses-permission android:name="android.permission.INTERNET" />
5
+
6
+ <application
7
+ android:label="Compose App"
8
+ android:icon="@mipmap/ic_launcher"
9
+ android:allowBackup="true">
10
+
11
+ <activity
12
+ android:name=".MainActivity"
13
+ android:exported="true">
14
+ <intent-filter>
15
+ <action android:name="android.intent.action.MAIN" />
16
+ <category android:name="android.intent.category.LAUNCHER" />
17
+ </intent-filter>
18
+ </activity>
19
+
20
+ </application>
21
+
22
+ </manifest>
@@ -0,0 +1,11 @@
1
+ package com.example.composeapp
2
+
3
+ import androidx.compose.runtime.Composable
4
+ import androidx.compose.material3.Text
5
+
6
+ class MainActivity
7
+
8
+ @Composable
9
+ fun Greeting(name: String) {
10
+ Text(text = "Hello, $name!")
11
+ }
@@ -0,0 +1,4 @@
1
+ plugins {
2
+ id("com.android.application") version "8.2.0" apply false
3
+ id("org.jetbrains.kotlin.android") version "1.9.22" apply false
4
+ }
@@ -0,0 +1,4 @@
1
+ distributionBase=GRADLE_USER_HOME
2
+ distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
3
+ distributionPath=wrapper/dists
4
+ zipStorePath=wrapper/dists
@@ -0,0 +1,2 @@
1
+ rootProject.name = "compose-app"
2
+ include(":app")
@@ -0,0 +1,3 @@
1
+ plugins {
2
+ alias(libs.plugins.android.application) apply false
3
+ }
@@ -0,0 +1,5 @@
1
+ [versions]
2
+ agp = "8.2.2"
3
+
4
+ [plugins]
5
+ android-application = { id = "com.android.application", version.ref = "agp" }
@@ -0,0 +1,21 @@
1
+ plugins {
2
+ id("com.android.application")
3
+ }
4
+
5
+ // applicationId = "com.example.commented-out-should-not-be-used"
6
+ /*
7
+ namespace = "com.example.also-commented-out"
8
+ */
9
+
10
+ android {
11
+ namespace = "com.example.commentsafety"
12
+ // A string that merely mentions "applicationId" in prose should not match.
13
+ val note = "the applicationId field below is the real one"
14
+
15
+ defaultConfig {
16
+ applicationId = "com.example.commentsafety"
17
+ minSdk = 24
18
+ targetSdk = 34
19
+ compileSdk = 34
20
+ }
21
+ }
@@ -0,0 +1,17 @@
1
+ plugins {
2
+ id("com.android.application")
3
+ }
4
+
5
+ val gitVersionName = providers.exec { commandLine("git", "describe") }.standardOutput.asText.get()
6
+
7
+ android {
8
+ namespace = "com.example.dynamic"
9
+ compileSdk = libs.versions.compileSdk.get().toInt()
10
+
11
+ defaultConfig {
12
+ applicationId = appIdFromProperties()
13
+ versionName = gitVersionName
14
+ targetSdk = project.property("targetSdkFromProperties") as Int
15
+ minSdk = 24
16
+ }
17
+ }
@@ -0,0 +1,23 @@
1
+ apply plugin: 'com.android.application'
2
+
3
+ android {
4
+ namespace "com.example.groovyliteral"
5
+ compileSdkVersion 33
6
+
7
+ defaultConfig {
8
+ applicationId "com.example.groovyliteral"
9
+ minSdkVersion 21
10
+ targetSdkVersion 33
11
+ versionCode 2
12
+ versionName "2.0"
13
+ }
14
+
15
+ buildTypes {
16
+ debug {
17
+ }
18
+ release {
19
+ }
20
+ staging {
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,4 @@
1
+ distributionBase=GRADLE_USER_HOME
2
+ distributionUrl=https\://services.gradle.org/distributions/not-a-real-distribution.zip
3
+ distributionPath=wrapper/dists
4
+ zipStorePath=wrapper/dists
@@ -0,0 +1,3 @@
1
+ distributionBase=GRADLE_USER_HOME
2
+ distributionPath=wrapper/dists
3
+ zipStorePath=wrapper/dists
@@ -0,0 +1,5 @@
1
+ distributionBase=GRADLE_USER_HOME
2
+ distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
3
+ distributionSha256Sum=abcdef1234567890
4
+ distributionPath=wrapper/dists
5
+ zipStorePath=wrapper/dists
@@ -0,0 +1,16 @@
1
+ plugins {
2
+ id 'com.android.application'
3
+ }
4
+
5
+ android {
6
+ namespace 'com.example.javaapp'
7
+ compileSdk 34
8
+
9
+ defaultConfig {
10
+ applicationId 'com.example.javaapp'
11
+ minSdk 21
12
+ targetSdk 34
13
+ versionCode 1
14
+ versionName '1.0'
15
+ }
16
+ }
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+
4
+ <application
5
+ android:label="Java App"
6
+ android:icon="@mipmap/ic_launcher">
7
+
8
+ <activity
9
+ android:name=".MainActivity"
10
+ android:exported="true">
11
+ <intent-filter>
12
+ <action android:name="android.intent.action.MAIN" />
13
+ <category android:name="android.intent.category.LAUNCHER" />
14
+ </intent-filter>
15
+ </activity>
16
+
17
+ </application>
18
+
19
+ </manifest>
@@ -0,0 +1,4 @@
1
+ package com.example.javaapp;
2
+
3
+ public class MainActivity {
4
+ }
@@ -0,0 +1,3 @@
1
+ plugins {
2
+ id 'com.android.application' version '8.2.0' apply false
3
+ }
@@ -0,0 +1,4 @@
1
+ distributionBase=GRADLE_USER_HOME
2
+ distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
3
+ distributionPath=wrapper/dists
4
+ zipStorePath=wrapper/dists
@@ -0,0 +1,2 @@
1
+ rootProject.name = 'java-app'
2
+ include ':app'
@@ -0,0 +1,3 @@
1
+ plugins {
2
+ id("com.android.library") version "8.2.0" apply false
3
+ }
@@ -0,0 +1,4 @@
1
+ distributionBase=GRADLE_USER_HOME
2
+ distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
3
+ distributionPath=wrapper/dists
4
+ zipStorePath=wrapper/dists
@@ -0,0 +1,13 @@
1
+ plugins {
2
+ id("com.android.library")
3
+ }
4
+
5
+ android {
6
+ namespace = "com.example.mylibrary"
7
+ compileSdk = 34
8
+
9
+ defaultConfig {
10
+ minSdk = 21
11
+ targetSdk = 34
12
+ }
13
+ }
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" />
@@ -0,0 +1,2 @@
1
+ rootProject.name = "library"
2
+ include(":mylibrary")
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <application>
4
+ <activity android:name=".EmptyFilterActivity" android:exported="true">
5
+ <intent-filter>
6
+ </intent-filter>
7
+ </activity>
8
+ <activity android:name=".BrowsableOnlyActivity" android:exported="true">
9
+ <intent-filter>
10
+ <category android:name="android.intent.category.BROWSABLE" />
11
+ </intent-filter>
12
+ </activity>
13
+ </application>
14
+ </manifest>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <application>
4
+ <activity android:name=".WeirdActivity" android:exported="maybe">
5
+ <intent-filter>
6
+ <action android:name="android.intent.action.VIEW" />
7
+ </intent-filter>
8
+ </activity>
9
+ </application>
10
+ </manifest>
@@ -0,0 +1,5 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <application>
3
+ <activity android:name=".MainActivity">
4
+ </application>
5
+ </manifest>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.example.missingapp">
4
+
5
+ <uses-permission android:name="android.permission.INTERNET" />
6
+
7
+ </manifest>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <application>
4
+ <activity android:exported="true">
5
+ <intent-filter>
6
+ <action android:name="android.intent.action.MAIN" />
7
+ <category android:name="android.intent.category.LAUNCHER" />
8
+ </intent-filter>
9
+ </activity>
10
+ </application>
11
+ </manifest>
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.example.permissions">
4
+
5
+ <uses-permission android:name="android.permission.INTERNET" />
6
+ <uses-permission android:name="android.permission.CAMERA" />
7
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
8
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
9
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
10
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
11
+ <uses-permission android:name="android.permission.READ_CALENDAR" />
12
+ <uses-permission android:name="android.permission.SEND_SMS" />
13
+ <uses-permission android:name="android.permission.READ_CALL_LOG" />
14
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
15
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
16
+ <uses-permission android:name="com.example.permissions.CUSTOM_PERMISSION" />
17
+ <uses-permission android:name="android.permission.CAMERA" />
18
+ <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH_CONNECT" />
19
+
20
+ <application>
21
+ <activity android:name=".MainActivity" android:exported="true">
22
+ <intent-filter>
23
+ <action android:name="android.intent.action.MAIN" />
24
+ <category android:name="android.intent.category.LAUNCHER" />
25
+ </intent-filter>
26
+ </activity>
27
+ </application>
28
+
29
+ </manifest>
@@ -0,0 +1,62 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.example.risky">
4
+
5
+ <application>
6
+
7
+ <activity android:name=".MainActivity" android:exported="true">
8
+ <intent-filter>
9
+ <action android:name="android.intent.action.MAIN" />
10
+ <category android:name="android.intent.category.LAUNCHER" />
11
+ </intent-filter>
12
+ </activity>
13
+
14
+ <activity android:name=".UnprotectedExportedActivity" android:exported="true">
15
+ <intent-filter>
16
+ <action android:name="com.example.risky.CUSTOM_ACTION" />
17
+ <category android:name="android.intent.category.DEFAULT" />
18
+ </intent-filter>
19
+ </activity>
20
+
21
+ <activity android:name=".ProtectedExportedActivity"
22
+ android:exported="true"
23
+ android:permission="com.example.risky.permission.ADMIN" />
24
+
25
+ <activity android:name=".UnspecifiedExportedActivity">
26
+ <intent-filter>
27
+ <action android:name="com.example.risky.ANOTHER_ACTION" />
28
+ </intent-filter>
29
+ </activity>
30
+
31
+ <activity android:name=".NotExportedActivity" android:exported="false" />
32
+
33
+ <service android:name=".UnprotectedExportedService" android:exported="true">
34
+ <intent-filter>
35
+ <action android:name="com.example.risky.SERVICE_ACTION" />
36
+ </intent-filter>
37
+ </service>
38
+
39
+ <receiver android:name=".UnprotectedExportedReceiver" android:exported="true">
40
+ <intent-filter>
41
+ <action android:name="com.example.risky.RECEIVER_ACTION" />
42
+ </intent-filter>
43
+ </receiver>
44
+
45
+ <provider android:name=".UnprotectedExportedProvider"
46
+ android:authorities="com.example.risky.provider"
47
+ android:exported="true" />
48
+
49
+ <provider android:name=".PartiallyProtectedProvider"
50
+ android:authorities="com.example.risky.provider2"
51
+ android:exported="true"
52
+ android:readPermission="com.example.risky.permission.READ" />
53
+
54
+ <provider android:name=".FullyProtectedProvider"
55
+ android:authorities="com.example.risky.provider3"
56
+ android:exported="true"
57
+ android:readPermission="com.example.risky.permission.READ"
58
+ android:writePermission="com.example.risky.permission.WRITE" />
59
+
60
+ </application>
61
+
62
+ </manifest>
@@ -0,0 +1,45 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.example.deeplinks">
4
+
5
+ <application>
6
+
7
+ <activity android:name=".CustomSchemeNoHostActivity" android:exported="true">
8
+ <intent-filter>
9
+ <action android:name="android.intent.action.VIEW" />
10
+ <category android:name="android.intent.category.DEFAULT" />
11
+ <category android:name="android.intent.category.BROWSABLE" />
12
+ <data android:scheme="myapp" />
13
+ </intent-filter>
14
+ </activity>
15
+
16
+ <activity android:name=".HttpNoHostActivity" android:exported="true">
17
+ <intent-filter>
18
+ <action android:name="android.intent.action.VIEW" />
19
+ <category android:name="android.intent.category.DEFAULT" />
20
+ <category android:name="android.intent.category.BROWSABLE" />
21
+ <data android:scheme="https" />
22
+ </intent-filter>
23
+ </activity>
24
+
25
+ <activity android:name=".BroadPathPatternActivity" android:exported="true">
26
+ <intent-filter>
27
+ <action android:name="android.intent.action.VIEW" />
28
+ <category android:name="android.intent.category.DEFAULT" />
29
+ <category android:name="android.intent.category.BROWSABLE" />
30
+ <data android:scheme="https" android:host="example.com" android:pathPattern=".*" />
31
+ </intent-filter>
32
+ </activity>
33
+
34
+ <activity android:name=".BoundedSafeDeepLinkActivity" android:exported="true">
35
+ <intent-filter android:autoVerify="true">
36
+ <action android:name="android.intent.action.VIEW" />
37
+ <category android:name="android.intent.category.DEFAULT" />
38
+ <category android:name="android.intent.category.BROWSABLE" />
39
+ <data android:scheme="https" android:host="example.com" android:pathPrefix="/product" />
40
+ </intent-filter>
41
+ </activity>
42
+
43
+ </application>
44
+
45
+ </manifest>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="${applicationId}">
4
+ <application android:label="@string/app_name" android:icon="@mipmap/ic_launcher">
5
+ <activity android:name=".ShareActivity" android:exported="true">
6
+ <intent-filter android:autoVerify="true">
7
+ <action android:name="android.intent.action.VIEW" />
8
+ <category android:name="android.intent.category.DEFAULT" />
9
+ <category android:name="android.intent.category.BROWSABLE" />
10
+ <data android:scheme="${deepLinkScheme}" android:host="@string/deep_link_host" />
11
+ </intent-filter>
12
+ </activity>
13
+ </application>
14
+ </manifest>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:x="http://schemas.android.com/apk/res/android">
3
+ <application>
4
+ <activity x:name=".MainActivity" x:exported="true">
5
+ <intent-filter>
6
+ <action x:name="android.intent.action.MAIN" />
7
+ <category x:name="android.intent.category.LAUNCHER" />
8
+ </intent-filter>
9
+ </activity>
10
+ </application>
11
+ </manifest>
@@ -0,0 +1,22 @@
1
+ plugins {
2
+ id("com.android.application")
3
+ id("org.jetbrains.kotlin.android")
4
+ }
5
+
6
+ android {
7
+ namespace = "com.example.multimodule.app"
8
+ compileSdk = 34
9
+
10
+ defaultConfig {
11
+ applicationId = "com.example.multimodule.app"
12
+ minSdk = 24
13
+ targetSdk = 34
14
+ versionCode = 1
15
+ versionName = "1.0"
16
+ }
17
+ }
18
+
19
+ dependencies {
20
+ implementation(project(":core"))
21
+ implementation(project(":feature-login"))
22
+ }
@@ -0,0 +1,3 @@
1
+ package com.example.multimodule.app
2
+
3
+ class ExampleInstrumentedTest