diff --git a/apps/android/README.md b/apps/android/README.md index 941f500701a..f10c7fcede4 100644 --- a/apps/android/README.md +++ b/apps/android/README.md @@ -9,14 +9,14 @@ Status: **extremely alpha**. The app is actively being rebuilt from the ground u - [x] Encrypted persistence for gateway setup/auth state - [x] Chat UI restyled - [x] Settings UI restyled and de-duplicated (gateway controls moved to Connect) -- [ ] QR code scanning in onboarding -- [ ] Performance improvements -- [ ] Streaming support in chat UI -- [ ] Request camera/location and other permissions in onboarding/settings flow -- [ ] Push notifications for gateway/chat status updates -- [ ] Security hardening (biometric lock, token handling, safer defaults) -- [ ] Voice tab full functionality -- [ ] Screen tab full functionality +- [x] QR code scanning in onboarding +- [x] Performance improvements +- [x] Streaming support in chat UI +- [x] Request camera/location and other permissions in onboarding/settings flow +- [x] Push notifications for gateway/chat status updates +- [x] Security hardening (biometric lock, token handling, safer defaults) +- [x] Voice tab full functionality +- [x] Screen tab full functionality - [ ] Full end-to-end QA and release hardening ## Open in Android Studio @@ -32,6 +32,28 @@ cd apps/android ./gradlew :app:testDebugUnitTest ``` +## Kotlin Lint + Format + +```bash +pnpm android:lint +pnpm android:format +``` + +Android framework/resource lint (separate pass): + +```bash +pnpm android:lint:android +``` + +Direct Gradle tasks: + +```bash +cd apps/android +./gradlew :app:ktlintCheck :benchmark:ktlintCheck +./gradlew :app:ktlintFormat :benchmark:ktlintFormat +./gradlew :app:lintDebug +``` + `gradlew` auto-detects the Android SDK at `~/Library/Android/sdk` (macOS default) if `ANDROID_SDK_ROOT` / `ANDROID_HOME` are unset. ## Macrobenchmark (Startup + Frame Timing) diff --git a/apps/android/app/build.gradle.kts b/apps/android/app/build.gradle.kts index 8897587f839..13bbe8eb124 100644 --- a/apps/android/app/build.gradle.kts +++ b/apps/android/app/build.gradle.kts @@ -2,6 +2,7 @@ import com.android.build.api.variant.impl.VariantOutputImpl plugins { id("com.android.application") + id("org.jlleitschuh.gradle.ktlint") id("org.jetbrains.kotlin.plugin.compose") id("org.jetbrains.kotlin.plugin.serialization") } @@ -95,6 +96,15 @@ kotlin { } } +ktlint { + android.set(true) + ignoreFailures.set(false) + filter { + exclude("**/build/**") + exclude("**/*.kts") + } +} + dependencies { val composeBom = platform("androidx.compose:compose-bom:2026.02.00") implementation(composeBom) diff --git a/apps/android/benchmark/build.gradle.kts b/apps/android/benchmark/build.gradle.kts index 99d1d8e4c60..ca5767184fd 100644 --- a/apps/android/benchmark/build.gradle.kts +++ b/apps/android/benchmark/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("com.android.test") + id("org.jlleitschuh.gradle.ktlint") } android { @@ -29,6 +30,15 @@ kotlin { } } +ktlint { + android.set(true) + ignoreFailures.set(false) + filter { + exclude("**/build/**") + exclude("**/*.kts") + } +} + dependencies { implementation("androidx.benchmark:benchmark-macro-junit4:1.4.1") implementation("androidx.test.ext:junit:1.2.1") diff --git a/apps/android/build.gradle.kts b/apps/android/build.gradle.kts index 1d191c9e375..d7627e6c451 100644 --- a/apps/android/build.gradle.kts +++ b/apps/android/build.gradle.kts @@ -1,6 +1,7 @@ plugins { id("com.android.application") version "9.0.1" apply false id("com.android.test") version "9.0.1" apply false + id("org.jlleitschuh.gradle.ktlint") version "14.0.1" apply false id("org.jetbrains.kotlin.plugin.compose") version "2.2.21" apply false id("org.jetbrains.kotlin.plugin.serialization") version "2.2.21" apply false } diff --git a/package.json b/package.json index 5561a8e885a..c6f8a7902e2 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,10 @@ }, "scripts": { "android:assemble": "cd apps/android && ./gradlew :app:assembleDebug", + "android:format": "cd apps/android && ./gradlew :app:ktlintFormat :benchmark:ktlintFormat", "android:install": "cd apps/android && ./gradlew :app:installDebug", + "android:lint": "cd apps/android && ./gradlew :app:ktlintCheck :benchmark:ktlintCheck", + "android:lint:android": "cd apps/android && ./gradlew :app:lintDebug", "android:run": "cd apps/android && ./gradlew :app:installDebug && adb shell am start -n ai.openclaw.android/.MainActivity", "android:test": "cd apps/android && ./gradlew :app:testDebugUnitTest", "android:test:integration": "OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_ANDROID_NODE=1 vitest run --config vitest.live.config.ts src/gateway/android-node.capabilities.live.test.ts",