android-sdd 1.0.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.
- package/dist/index.js +143 -0
- package/package.json +27 -0
- package/skills/Android Ecosystem/Baseline Profile Generator/SKILL.md +277 -0
- package/skills/Android Ecosystem/Glance/SKILL.md +315 -0
- package/skills/Android Platform/Configuration/SKILL.md +201 -0
- package/skills/Android Platform/Filesystem/SKILL.md +216 -0
- package/skills/Android Platform/Lifecycle/SKILL.md +233 -0
- package/skills/Android Platform/Manifest/SKILL.md +226 -0
- package/skills/Android Platform/Process Death Recovery/SKILL.md +214 -0
- package/skills/Android Platform/Resources/SKILL.md +234 -0
- package/skills/Android Platform/SavedStateHandle/SKILL.md +217 -0
- package/skills/Android Platform/State Restoration/SKILL.md +210 -0
- package/skills/Architecture/Bounded Context/SKILL.md +207 -0
- package/skills/Architecture/Clean Architecture/SKILL.md +229 -0
- package/skills/Architecture/Domain Modeling/SKILL.md +236 -0
- package/skills/Architecture/Entity Design/SKILL.md +243 -0
- package/skills/Architecture/Feature Isolation/SKILL.md +216 -0
- package/skills/Architecture/MVI/SKILL.md +224 -0
- package/skills/Architecture/MVVM/SKILL.md +198 -0
- package/skills/Architecture/Modularization/SKILL.md +194 -0
- package/skills/Architecture/Offline First/SKILL.md +249 -0
- package/skills/Architecture/Repository Pattern/SKILL.md +216 -0
- package/skills/Architecture/Side Effect Management/SKILL.md +278 -0
- package/skills/Architecture/State Management/SKILL.md +229 -0
- package/skills/Architecture/Unidirectional Data Flow/SKILL.md +196 -0
- package/skills/Architecture/Use Case Design/SKILL.md +244 -0
- package/skills/Architecture/Value Object/SKILL.md +226 -0
- package/skills/Build Infrastructure/Build Orchestration/SKILL.md +257 -0
- package/skills/Build Infrastructure/Dependency Compatibility Resolver/SKILL.md +259 -0
- package/skills/Build Infrastructure/Environment Validator/SKILL.md +311 -0
- package/skills/Build System/Build Cache/SKILL.md +233 -0
- package/skills/Build System/Build Flavor Strategy/SKILL.md +171 -0
- package/skills/Build System/Build Variant/SKILL.md +215 -0
- package/skills/Build System/Convention Plugin/SKILL.md +288 -0
- package/skills/Build System/Dependency Management/SKILL.md +261 -0
- package/skills/Build System/Gradle/SKILL.md +284 -0
- package/skills/Build System/Incremental Build/SKILL.md +199 -0
- package/skills/Build System/KAPT/SKILL.md +198 -0
- package/skills/Build System/KSP/SKILL.md +263 -0
- package/skills/Build System/Module Dependency Graph Validation/SKILL.md +223 -0
- package/skills/Build System/Specialized/C++/SKILL.md +308 -0
- package/skills/Build System/Specialized/JNI/SKILL.md +306 -0
- package/skills/Build System/Specialized/NDK/SKILL.md +264 -0
- package/skills/Build System/Version Catalog/SKILL.md +304 -0
- package/skills/Concurrency/Background Processing/SKILL.md +185 -0
- package/skills/Concurrency/Channel/SKILL.md +207 -0
- package/skills/Concurrency/Coroutine/SKILL.md +200 -0
- package/skills/Concurrency/Flow/SKILL.md +179 -0
- package/skills/Concurrency/Mutex Strategy/SKILL.md +185 -0
- package/skills/Concurrency/SharedFlow/SKILL.md +171 -0
- package/skills/Concurrency/StateFlow/SKILL.md +175 -0
- package/skills/Concurrency/Structured Concurrency/SKILL.md +197 -0
- package/skills/Concurrency/Synchronization Policy/SKILL.md +192 -0
- package/skills/Core Language/Annotation Processing/SKILL.md +224 -0
- package/skills/Core Language/DSL/SKILL.md +186 -0
- package/skills/Core Language/Extension Functions Design/SKILL.md +191 -0
- package/skills/Core Language/Immutability/SKILL.md +156 -0
- package/skills/Core Language/KMP/SKILL.md +182 -0
- package/skills/Core Language/Kotlin/SKILL.md +187 -0
- package/skills/Core Language/Reactive State Management/SKILL.md +228 -0
- package/skills/Core Language/Reactive Streams/SKILL.md +235 -0
- package/skills/Core Language/Serialization/SKILL.md +191 -0
- package/skills/Data Layer/Cache Strategy/SKILL.md +261 -0
- package/skills/Data Layer/Conflict Resolution/SKILL.md +248 -0
- package/skills/Data Layer/DAO/SKILL.md +225 -0
- package/skills/Data Layer/DTO Mapping/SKILL.md +269 -0
- package/skills/Data Layer/DataStore/SKILL.md +264 -0
- package/skills/Data Layer/Database Versioning Strategy/SKILL.md +215 -0
- package/skills/Data Layer/Encrypted Database/SKILL.md +212 -0
- package/skills/Data Layer/File Storage/SKILL.md +247 -0
- package/skills/Data Layer/Indexing/SKILL.md +184 -0
- package/skills/Data Layer/Key-Value Store Strategy/SKILL.md +185 -0
- package/skills/Data Layer/Merge Strategy/SKILL.md +240 -0
- package/skills/Data Layer/Migration/SKILL.md +243 -0
- package/skills/Data Layer/Paging/SKILL.md +264 -0
- package/skills/Data Layer/Proto DataStore/SKILL.md +250 -0
- package/skills/Data Layer/Room/SKILL.md +244 -0
- package/skills/Data Layer/SQLite/SKILL.md +255 -0
- package/skills/Data Layer/Sync Engine/SKILL.md +268 -0
- package/skills/Dependency Injection/Dagger/SKILL.md +283 -0
- package/skills/Dependency Injection/Hilt/SKILL.md +345 -0
- package/skills/Dependency Injection/Koin/SKILL.md +282 -0
- package/skills/Developer Experience/Detekt/SKILL.md +272 -0
- package/skills/Developer Experience/Lint Rule/SKILL.md +281 -0
- package/skills/Google Ecosystem/Analytics/SKILL.md +281 -0
- package/skills/Google Ecosystem/Crashlytics/SKILL.md +234 -0
- package/skills/Google Ecosystem/Firebase/SKILL.md +200 -0
- package/skills/Google Ecosystem/Firebase Messaging/SKILL.md +266 -0
- package/skills/Media/Audio/SKILL.md +257 -0
- package/skills/Media/Camera/SKILL.md +229 -0
- package/skills/Media/CameraX/SKILL.md +295 -0
- package/skills/Media/ExoPlayer/SKILL.md +258 -0
- package/skills/Media/Video/SKILL.md +228 -0
- package/skills/Meta Skills/Domain Error Model/SKILL.md +238 -0
- package/skills/Meta Skills/Error Handling/SKILL.md +255 -0
- package/skills/Meta Skills/Error Mapping/SKILL.md +232 -0
- package/skills/Meta Skills/Failure Strategy/SKILL.md +294 -0
- package/skills/Meta Skills/Migration Strategy/SKILL.md +305 -0
- package/skills/Meta Skills/User Friendly Errors/SKILL.md +334 -0
- package/skills/Navigation/Deep Navigation/SKILL.md +209 -0
- package/skills/Navigation/Navigation/SKILL.md +215 -0
- package/skills/Navigation/Nested Navigation/SKILL.md +214 -0
- package/skills/Networking/API Contract/SKILL.md +220 -0
- package/skills/Networking/Authentication/SKILL.md +210 -0
- package/skills/Networking/Certificate Pinning/SKILL.md +167 -0
- package/skills/Networking/Fallback Strategy/SKILL.md +182 -0
- package/skills/Networking/Ktor/SKILL.md +219 -0
- package/skills/Networking/Multipart Upload/SKILL.md +213 -0
- package/skills/Networking/OkHttp/SKILL.md +193 -0
- package/skills/Networking/REST/SKILL.md +178 -0
- package/skills/Networking/Rate Limiting/SKILL.md +170 -0
- package/skills/Networking/Retrofit/SKILL.md +241 -0
- package/skills/Networking/Retry-Backoff/SKILL.md +181 -0
- package/skills/Networking/Server-Sent Events (SSE)/SKILL.md +196 -0
- package/skills/Networking/WebSocket/SKILL.md +224 -0
- package/skills/Observability/Crash Reporting/SKILL.md +219 -0
- package/skills/Observability/Logging/SKILL.md +168 -0
- package/skills/Observability/Metrics/SKILL.md +227 -0
- package/skills/Observability/Structured Logging/SKILL.md +234 -0
- package/skills/Performance/ANR Prevention/SKILL.md +192 -0
- package/skills/Performance/Allocation Optimization/SKILL.md +179 -0
- package/skills/Performance/App Startup/SKILL.md +183 -0
- package/skills/Performance/Baseline Profile/SKILL.md +205 -0
- package/skills/Performance/Battery Optimization/SKILL.md +192 -0
- package/skills/Performance/Benchmark/SKILL.md +182 -0
- package/skills/Performance/Bitmap Optimization/SKILL.md +178 -0
- package/skills/Performance/Compose Optimization/SKILL.md +187 -0
- package/skills/Performance/Heap Management/SKILL.md +184 -0
- package/skills/Performance/Macrobenchmark/SKILL.md +214 -0
- package/skills/Performance/Memory Leak Prevention/SKILL.md +218 -0
- package/skills/Performance/Rendering Performance/SKILL.md +205 -0
- package/skills/Performance/Startup Optimization/SKILL.md +219 -0
- package/skills/Security/Biometric/SKILL.md +224 -0
- package/skills/Security/Certificate Transparency/SKILL.md +158 -0
- package/skills/Security/Cryptography/SKILL.md +244 -0
- package/skills/Security/Encrypted Storage/SKILL.md +273 -0
- package/skills/Security/Frida Detection/SKILL.md +230 -0
- package/skills/Security/Hook Detection/SKILL.md +197 -0
- package/skills/Security/Keystore/SKILL.md +272 -0
- package/skills/Security/Network Security Config/SKILL.md +186 -0
- package/skills/Security/Obfuscation/SKILL.md +226 -0
- package/skills/Security/Proguard/SKILL.md +202 -0
- package/skills/Security/R8/SKILL.md +234 -0
- package/skills/Security/Reverse Engineering Resistance/SKILL.md +267 -0
- package/skills/Security/Root Detection/SKILL.md +220 -0
- package/skills/Security/Secure Networking/SKILL.md +220 -0
- package/skills/System Integration/AlarmManager/SKILL.md +182 -0
- package/skills/System Integration/App Widget/SKILL.md +182 -0
- package/skills/System Integration/Deep Link/SKILL.md +187 -0
- package/skills/System Integration/Foreground Service/SKILL.md +212 -0
- package/skills/System Integration/Notification/SKILL.md +237 -0
- package/skills/System Integration/WorkManager/SKILL.md +256 -0
- package/skills/System Integration/clipboard/SKILL.md +155 -0
- package/skills/System Integration/share-intent/SKILL.md +182 -0
- package/skills/Testing/Compose Testing/SKILL.md +296 -0
- package/skills/Testing/Espresso/SKILL.md +292 -0
- package/skills/Testing/Fake Data/SKILL.md +245 -0
- package/skills/Testing/Integration Testing/SKILL.md +288 -0
- package/skills/Testing/Mocking/SKILL.md +229 -0
- package/skills/Testing/Snapshot Testing/SKILL.md +259 -0
- package/skills/Testing/UI Testing/SKILL.md +293 -0
- package/skills/Testing/Unit Testing/SKILL.md +309 -0
- package/skills/UI System/Bottom Sheet Patterns/SKILL.md +279 -0
- package/skills/UI System/Compose/SKILL.md +296 -0
- package/skills/UI System/Compose Animation/SKILL.md +281 -0
- package/skills/UI System/Compose Multiplatform/SKILL.md +261 -0
- package/skills/UI System/Compose Navigation/SKILL.md +255 -0
- package/skills/UI System/Compose Performance/SKILL.md +274 -0
- package/skills/UI System/Design System/SKILL.md +217 -0
- package/skills/UI System/Empty State Strategy/SKILL.md +208 -0
- package/skills/UI System/Keyboard Navigation/SKILL.md +214 -0
- package/skills/UI System/Loading Strategy/SKILL.md +254 -0
- package/skills/UI System/Material 3/SKILL.md +279 -0
- package/skills/UI System/RTL/SKILL.md +179 -0
- package/src/index.ts +182 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: module-dependency-graph-validation
|
|
3
|
+
description: >
|
|
4
|
+
Validating and enforcing module dependency rules in Android multi-module projects.
|
|
5
|
+
Load this skill when enforcing architecture boundaries between modules,
|
|
6
|
+
preventing circular dependencies, or visualizing the module dependency graph.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Module Dependency Graph Validation
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
In a multi-module Android project, modules must depend on each other in a controlled, directed way. Without enforcement, modules accumulate arbitrary dependencies — creating cycles, slow builds, and architectural drift. Dependency graph validation catches violations at build time.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Core Principles
|
|
17
|
+
|
|
18
|
+
- Module dependencies must be **directed and acyclic** — no cycles ever
|
|
19
|
+
- Feature modules must **not depend on other feature modules**
|
|
20
|
+
- Only `:app` can depend on all feature modules — it's the composition root
|
|
21
|
+
- Core modules can be depended upon by everyone but depend on nothing above them
|
|
22
|
+
- Validate the graph **at build time** — not in code reviews alone
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Module Layer Architecture
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
:app
|
|
30
|
+
├── :feature:home
|
|
31
|
+
├── :feature:auth
|
|
32
|
+
├── :feature:profile
|
|
33
|
+
│
|
|
34
|
+
├── :core:ui
|
|
35
|
+
├── :core:network
|
|
36
|
+
├── :core:database
|
|
37
|
+
├── :core:domain
|
|
38
|
+
└── :core:common
|
|
39
|
+
|
|
40
|
+
Rules:
|
|
41
|
+
- :feature:* → :core:* ✅
|
|
42
|
+
- :feature:* → :feature:* ❌
|
|
43
|
+
- :core:domain → :core:common ✅
|
|
44
|
+
- :core:network → :core:domain ❌ (domain must be pure)
|
|
45
|
+
- :app → everything ✅
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Dependency Guard Plugin
|
|
51
|
+
|
|
52
|
+
```toml
|
|
53
|
+
# libs.versions.toml
|
|
54
|
+
[plugins]
|
|
55
|
+
dependency-guard = { id = "com.dropbox.dependency-guard", version = "0.5.0" }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```kotlin
|
|
59
|
+
// app/build.gradle.kts
|
|
60
|
+
plugins {
|
|
61
|
+
alias(libs.plugins.dependency.guard)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
dependencyGuard {
|
|
65
|
+
configuration("releaseRuntimeClasspath")
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ✅ Generate baseline
|
|
69
|
+
// ./gradlew dependencyGuard
|
|
70
|
+
|
|
71
|
+
// ✅ Verify on CI — fails if deps changed without updating baseline
|
|
72
|
+
// ./gradlew dependencyGuardVerify
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Module Graph Plugin
|
|
78
|
+
|
|
79
|
+
```toml
|
|
80
|
+
[plugins]
|
|
81
|
+
module-graph = { id = "com.jraska.module.graph.assertion", version = "2.5.0" }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```kotlin
|
|
85
|
+
// root build.gradle.kts
|
|
86
|
+
plugins {
|
|
87
|
+
alias(libs.plugins.module.graph)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
moduleGraphAssert {
|
|
91
|
+
maxHeight = 4 // max allowed module depth
|
|
92
|
+
|
|
93
|
+
// ✅ Assert no feature-to-feature dependencies
|
|
94
|
+
restricted = arrayOf(
|
|
95
|
+
":feature:.* -> :feature:.*" // regex: feature modules can't depend on each other
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
// ✅ Assert specific allowed paths
|
|
99
|
+
allowed = arrayOf(
|
|
100
|
+
":feature:.* -> :core:.*", // features can use core
|
|
101
|
+
":app -> :.*" // app can use everything
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ✅ Run validation
|
|
106
|
+
// ./gradlew assertModuleGraph
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Custom Gradle Task Validation
|
|
112
|
+
|
|
113
|
+
```kotlin
|
|
114
|
+
// build-logic/convention/src/main/kotlin/ModuleGraphValidationPlugin.kt
|
|
115
|
+
class ModuleGraphValidationPlugin : Plugin<Project> {
|
|
116
|
+
override fun apply(target: Project) {
|
|
117
|
+
target.tasks.register("validateModuleDependencies") {
|
|
118
|
+
group = "verification"
|
|
119
|
+
description = "Validates module dependency rules"
|
|
120
|
+
|
|
121
|
+
doLast {
|
|
122
|
+
val violations = mutableListOf<String>()
|
|
123
|
+
val featureModules = target.rootProject.subprojects
|
|
124
|
+
.filter { it.path.startsWith(":feature:") }
|
|
125
|
+
|
|
126
|
+
featureModules.forEach { featureModule ->
|
|
127
|
+
featureModule.configurations
|
|
128
|
+
.filter { it.name == "implementation" }
|
|
129
|
+
.flatMap { it.dependencies }
|
|
130
|
+
.filterIsInstance<ProjectDependency>()
|
|
131
|
+
.filter { it.dependencyProject.path.startsWith(":feature:") }
|
|
132
|
+
.forEach { dep ->
|
|
133
|
+
violations.add(
|
|
134
|
+
"${featureModule.path} -> ${dep.dependencyProject.path} " +
|
|
135
|
+
"(feature-to-feature dependency not allowed)"
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (violations.isNotEmpty()) {
|
|
141
|
+
throw GradleException(
|
|
142
|
+
"Module dependency violations:\n${violations.joinToString("\n")}"
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ✅ Run before every build
|
|
149
|
+
target.tasks.named("preBuild") {
|
|
150
|
+
dependsOn("validateModuleDependencies")
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Visualizing the Module Graph
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# ✅ Generate dependency graph image (requires graphviz)
|
|
162
|
+
./gradlew generateModuleGraph
|
|
163
|
+
|
|
164
|
+
# ✅ Using project-report plugin
|
|
165
|
+
./gradlew projectDependencies > module-deps.txt
|
|
166
|
+
|
|
167
|
+
# ✅ Using gradle-dependency-graph-generator plugin
|
|
168
|
+
plugins {
|
|
169
|
+
id("com.vanniktech.dependency.graph.generator") version "0.8.0"
|
|
170
|
+
}
|
|
171
|
+
# ./gradlew generateProjectDependencyGraph
|
|
172
|
+
# Output: build/reports/dependency-graph/
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Detecting Cycles
|
|
178
|
+
|
|
179
|
+
```kotlin
|
|
180
|
+
// ✅ Gradle detects cycles automatically — build fails with:
|
|
181
|
+
// "Circular dependency between the following tasks: ..."
|
|
182
|
+
|
|
183
|
+
// For module-level cycle detection — custom task
|
|
184
|
+
fun detectCycles(modules: List<Project>): List<List<String>> {
|
|
185
|
+
val graph = buildDependencyGraph(modules)
|
|
186
|
+
return findCycles(graph)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ✅ Or use: ./gradlew dependencies
|
|
190
|
+
// Circular module dependencies cause Gradle to fail immediately
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Enforcing in CI
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
# .github/workflows/build.yml
|
|
199
|
+
- name: Validate module graph
|
|
200
|
+
run: ./gradlew assertModuleGraph
|
|
201
|
+
|
|
202
|
+
- name: Verify dependency guard
|
|
203
|
+
run: ./gradlew dependencyGuardVerify
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Anti-Patterns
|
|
209
|
+
|
|
210
|
+
- Feature modules importing other feature modules — breaks independent build and test
|
|
211
|
+
- No automated enforcement — violations accumulate silently
|
|
212
|
+
- `:core:network` depending on `:core:domain` — domain must be framework-free
|
|
213
|
+
- Circular dependencies — Gradle fails but error message can be cryptic
|
|
214
|
+
- Skipping graph validation in CI — local dev can bypass it
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Related Skills
|
|
219
|
+
- `modularization` — multi-module architecture design
|
|
220
|
+
- `multi-module-architecture` — module structure patterns
|
|
221
|
+
- `gradle` — Gradle build configuration
|
|
222
|
+
- `dependency-management` — managing what modules depend on
|
|
223
|
+
- `build-orchestration` — building modules in the right order
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: c++
|
|
3
|
+
description: >
|
|
4
|
+
C++ patterns and best practices for Android NDK development.
|
|
5
|
+
Load this skill when writing C++ code for Android native libraries,
|
|
6
|
+
using modern C++17 features, managing memory safely, handling
|
|
7
|
+
concurrency in native code, or structuring native C++ modules.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# C++
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
Modern C++ (C++17) for Android NDK focuses on safety, expressiveness, and performance. Android's Clang toolchain fully supports C++17. Using RAII, smart pointers, and the standard library eliminates most memory management bugs that plague native Android code.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Core Principles
|
|
18
|
+
|
|
19
|
+
- **C++17** is the minimum target — use structured bindings, `std::optional`, `std::variant`
|
|
20
|
+
- **RAII everywhere** — resources are always tied to object lifetime
|
|
21
|
+
- **Smart pointers** instead of raw `new`/`delete` — `unique_ptr`, `shared_ptr`
|
|
22
|
+
- **`std::string` not `char*`** — except at JNI boundaries
|
|
23
|
+
- **No raw arrays** — use `std::vector`, `std::array`, `std::span`
|
|
24
|
+
- **const-correctness** — mark everything `const` that doesn't need to change
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Memory Management
|
|
29
|
+
|
|
30
|
+
```cpp
|
|
31
|
+
// ✅ unique_ptr — single ownership
|
|
32
|
+
std::unique_ptr<AESContext> ctx = std::make_unique<AESContext>(key);
|
|
33
|
+
ctx->encrypt(data); // auto-deleted when ctx goes out of scope
|
|
34
|
+
|
|
35
|
+
// ✅ shared_ptr — shared ownership
|
|
36
|
+
std::shared_ptr<KeyStore> keyStore = std::make_shared<KeyStore>();
|
|
37
|
+
auto cipher = std::make_shared<AESCipher>(keyStore);
|
|
38
|
+
|
|
39
|
+
// ✅ RAII wrapper for Android resources
|
|
40
|
+
class AssetGuard {
|
|
41
|
+
public:
|
|
42
|
+
explicit AssetGuard(AAsset* asset) : asset_(asset) {}
|
|
43
|
+
~AssetGuard() {
|
|
44
|
+
if (asset_) AAsset_close(asset_);
|
|
45
|
+
}
|
|
46
|
+
// Disable copy
|
|
47
|
+
AssetGuard(const AssetGuard&) = delete;
|
|
48
|
+
AssetGuard& operator=(const AssetGuard&) = delete;
|
|
49
|
+
// Enable move
|
|
50
|
+
AssetGuard(AssetGuard&& other) noexcept : asset_(other.asset_) {
|
|
51
|
+
other.asset_ = nullptr;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
AAsset* get() const { return asset_; }
|
|
55
|
+
bool valid() const { return asset_ != nullptr; }
|
|
56
|
+
|
|
57
|
+
private:
|
|
58
|
+
AAsset* asset_;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Usage
|
|
62
|
+
AssetGuard asset(AAssetManager_open(mgr, "config.json", AASSET_MODE_BUFFER));
|
|
63
|
+
if (!asset.valid()) return {};
|
|
64
|
+
// asset is auto-closed when AssetGuard leaves scope
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Modern C++17 Features
|
|
70
|
+
|
|
71
|
+
```cpp
|
|
72
|
+
// ✅ Structured bindings
|
|
73
|
+
std::map<std::string, int> scores = {{"ali", 90}, {"sara", 85}};
|
|
74
|
+
for (const auto& [name, score] : scores) {
|
|
75
|
+
LOGI("%s: %d", name.c_str(), score);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ✅ std::optional — nullable without pointers
|
|
79
|
+
std::optional<std::string> findKey(const std::string& id) {
|
|
80
|
+
auto it = keyMap.find(id);
|
|
81
|
+
if (it == keyMap.end()) return std::nullopt;
|
|
82
|
+
return it->second;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
auto key = findKey("user_key");
|
|
86
|
+
if (key.has_value()) {
|
|
87
|
+
encrypt(data, *key);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ✅ std::variant — type-safe union
|
|
91
|
+
using Result = std::variant<std::vector<uint8_t>, std::string>;
|
|
92
|
+
|
|
93
|
+
Result encrypt(const std::vector<uint8_t>& data) {
|
|
94
|
+
if (data.empty()) return std::string("Empty input");
|
|
95
|
+
return performEncryption(data);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
auto result = encrypt(data);
|
|
99
|
+
std::visit([](auto&& val) {
|
|
100
|
+
using T = std::decay_t<decltype(val)>;
|
|
101
|
+
if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
|
|
102
|
+
// success path
|
|
103
|
+
} else {
|
|
104
|
+
LOGE("Error: %s", val.c_str());
|
|
105
|
+
}
|
|
106
|
+
}, result);
|
|
107
|
+
|
|
108
|
+
// ✅ if constexpr — compile-time branching
|
|
109
|
+
template<typename T>
|
|
110
|
+
void logValue(T value) {
|
|
111
|
+
if constexpr (std::is_integral_v<T>) {
|
|
112
|
+
LOGI("int: %lld", static_cast<long long>(value));
|
|
113
|
+
} else if constexpr (std::is_floating_point_v<T>) {
|
|
114
|
+
LOGI("float: %f", static_cast<double>(value));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ✅ std::string_view — zero-copy string reference
|
|
119
|
+
void processName(std::string_view name) {
|
|
120
|
+
LOGI("Processing: %.*s", static_cast<int>(name.size()), name.data());
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Error Handling
|
|
127
|
+
|
|
128
|
+
```cpp
|
|
129
|
+
// ✅ Return std::expected-like result (C++23) or use std::optional / std::variant
|
|
130
|
+
struct Error {
|
|
131
|
+
int code;
|
|
132
|
+
std::string message;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Custom Result type for C++17
|
|
136
|
+
template<typename T>
|
|
137
|
+
class Result {
|
|
138
|
+
public:
|
|
139
|
+
static Result<T> ok(T value) {
|
|
140
|
+
Result r;
|
|
141
|
+
r.value_ = std::move(value);
|
|
142
|
+
return r;
|
|
143
|
+
}
|
|
144
|
+
static Result<T> err(Error error) {
|
|
145
|
+
Result r;
|
|
146
|
+
r.error_ = std::move(error);
|
|
147
|
+
return r;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
bool isOk() const { return value_.has_value(); }
|
|
151
|
+
bool isErr() const { return error_.has_value(); }
|
|
152
|
+
const T& value() const { return *value_; }
|
|
153
|
+
const Error& error() const { return *error_; }
|
|
154
|
+
|
|
155
|
+
private:
|
|
156
|
+
std::optional<T> value_;
|
|
157
|
+
std::optional<Error> error_;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Usage
|
|
161
|
+
Result<std::vector<uint8_t>> encryptData(const std::vector<uint8_t>& data) {
|
|
162
|
+
if (data.empty()) {
|
|
163
|
+
return Result<std::vector<uint8_t>>::err({-1, "Empty input"});
|
|
164
|
+
}
|
|
165
|
+
auto encrypted = performEncryption(data);
|
|
166
|
+
return Result<std::vector<uint8_t>>::ok(std::move(encrypted));
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Concurrency
|
|
173
|
+
|
|
174
|
+
```cpp
|
|
175
|
+
#include <mutex>
|
|
176
|
+
#include <thread>
|
|
177
|
+
#include <atomic>
|
|
178
|
+
|
|
179
|
+
// ✅ Thread-safe cache with mutex
|
|
180
|
+
class KeyCache {
|
|
181
|
+
public:
|
|
182
|
+
std::optional<std::vector<uint8_t>> get(const std::string& id) {
|
|
183
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
184
|
+
auto it = cache_.find(id);
|
|
185
|
+
if (it == cache_.end()) return std::nullopt;
|
|
186
|
+
return it->second;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
void set(const std::string& id, std::vector<uint8_t> key) {
|
|
190
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
191
|
+
cache_[id] = std::move(key);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
void clear() {
|
|
195
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
196
|
+
cache_.clear();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private:
|
|
200
|
+
std::mutex mutex_;
|
|
201
|
+
std::unordered_map<std::string, std::vector<uint8_t>> cache_;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// ✅ Atomic for simple counters
|
|
205
|
+
std::atomic<int> requestCount{0};
|
|
206
|
+
requestCount.fetch_add(1, std::memory_order_relaxed);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Containers and Algorithms
|
|
212
|
+
|
|
213
|
+
```cpp
|
|
214
|
+
// ✅ Prefer standard containers
|
|
215
|
+
std::vector<uint8_t> buffer(1024); // dynamic array
|
|
216
|
+
std::array<uint8_t, 16> iv{}; // fixed-size array
|
|
217
|
+
std::unordered_map<std::string, Key> keys; // hash map
|
|
218
|
+
std::string_view view = "hello"; // non-owning string ref
|
|
219
|
+
|
|
220
|
+
// ✅ Range-based algorithms
|
|
221
|
+
#include <algorithm>
|
|
222
|
+
#include <numeric>
|
|
223
|
+
|
|
224
|
+
std::vector<int> values = {3, 1, 4, 1, 5, 9};
|
|
225
|
+
|
|
226
|
+
// Sort
|
|
227
|
+
std::sort(values.begin(), values.end());
|
|
228
|
+
|
|
229
|
+
// Find
|
|
230
|
+
auto it = std::find(values.begin(), values.end(), 5);
|
|
231
|
+
if (it != values.end()) { /* found */ }
|
|
232
|
+
|
|
233
|
+
// Transform
|
|
234
|
+
std::vector<std::string> names;
|
|
235
|
+
std::transform(values.begin(), values.end(),
|
|
236
|
+
std::back_inserter(names),
|
|
237
|
+
[](int v) { return std::to_string(v); });
|
|
238
|
+
|
|
239
|
+
// Accumulate
|
|
240
|
+
int sum = std::accumulate(values.begin(), values.end(), 0);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Secure Memory Handling
|
|
246
|
+
|
|
247
|
+
```cpp
|
|
248
|
+
// ✅ Zero sensitive memory before freeing
|
|
249
|
+
void secureClear(std::vector<uint8_t>& data) {
|
|
250
|
+
volatile uint8_t* ptr = data.data();
|
|
251
|
+
for (size_t i = 0; i < data.size(); i++) {
|
|
252
|
+
ptr[i] = 0;
|
|
253
|
+
}
|
|
254
|
+
data.clear();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ✅ Secure string for passwords
|
|
258
|
+
class SecureString {
|
|
259
|
+
public:
|
|
260
|
+
explicit SecureString(std::string s) : data_(std::move(s)) {}
|
|
261
|
+
~SecureString() {
|
|
262
|
+
volatile char* ptr = &data_[0];
|
|
263
|
+
for (size_t i = 0; i < data_.size(); i++) ptr[i] = '\0';
|
|
264
|
+
}
|
|
265
|
+
const std::string& get() const { return data_; }
|
|
266
|
+
SecureString(const SecureString&) = delete;
|
|
267
|
+
SecureString& operator=(const SecureString&) = delete;
|
|
268
|
+
private:
|
|
269
|
+
std::string data_;
|
|
270
|
+
};
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Logging Macro
|
|
276
|
+
|
|
277
|
+
```cpp
|
|
278
|
+
#include <android/log.h>
|
|
279
|
+
|
|
280
|
+
#define LOG_TAG "NativeLib"
|
|
281
|
+
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
|
282
|
+
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
|
283
|
+
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
|
284
|
+
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
|
285
|
+
|
|
286
|
+
// Usage
|
|
287
|
+
LOGI("Initialized with key size: %zu", keySize);
|
|
288
|
+
LOGE("Failed to decrypt: error code %d", errorCode);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Anti-Patterns
|
|
294
|
+
|
|
295
|
+
- Raw `new`/`delete` — use `make_unique` / `make_shared`
|
|
296
|
+
- `char*` for strings in business logic — use `std::string` or `std::string_view`
|
|
297
|
+
- `int` for sizes and indices — use `size_t` or `std::ptrdiff_t`
|
|
298
|
+
- Ignoring return values of security functions — always check errors
|
|
299
|
+
- `std::endl` in log-heavy code — use `"\n"`; `endl` flushes and is slow
|
|
300
|
+
- Capturing `this` in lambdas stored beyond object lifetime — dangling reference
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Related Skills
|
|
305
|
+
- `jni` — JNI bridge between C++ and Kotlin
|
|
306
|
+
- `ndk` — NDK toolchain and build system
|
|
307
|
+
- `cryptography` — native crypto implementations
|
|
308
|
+
- `reverse-engineering-resistance` — native code as security layer
|