# 39. Android App — Push Notifications, Biometrics, Voice Enrollment, Call Screening

meta:
  id: shieldai-unified-restructure-39
  feature: shieldai-unified-restructure
  priority: P1
  depends_on: [shieldai-unified-restructure-34, shieldai-unified-restructure-35, shieldai-unified-restructure-36, shieldai-unified-restructure-37, shieldai-unified-restructure-38]
  tags: [android, jetpack-compose, native-features, push, biometrics, call-screening, mobile]

objective:
- Implement native Android features that differentiate the mobile experience: push notifications via FCM, biometric authentication, voice enrollment with audio recording, and call screening integration for SpamShield.

deliverables:
- `android/app/src/main/java/com/shieldai/android/service/FCMService.kt` — Firebase Cloud Messaging:
  - Extends `FirebaseMessagingService`
  - `onMessageReceived` — processes incoming notifications
  - `onNewToken` — sends token to backend (task 14)
  - Creates notification channels for different alert types
  - Rich notifications with images and actions
  - Deep links to relevant screens based on payload
- `android/app/src/main/java/com/shieldai/android/ui/screens/auth/BiometricAuthScreen.kt` — Biometric prompt:
  - Uses `BiometricPrompt` from `androidx.biometric:biometric`
  - Face/fingerprint authentication
  - Fallback to device PIN/pattern/password
  - Stores credential in `EncryptedSharedPreferences`
- `android/app/src/main/java/com/shieldai/android/ui/screens/voiceprint/RecordingScreen.kt` — Voice recording:
  - Real-time waveform visualization using `AudioRecord` + `Canvas`
  - Record / stop / playback controls
  - Duration timer
  - Quality check (minimum duration, amplitude threshold)
  - Submit enrollment to API
- `android/app/src/main/java/com/shieldai/android/service/CallScreeningService.kt` — Call screening:
  - Extends `CallScreeningService` (API 29+)
  - Intercepts incoming calls
  - Queries `spamshield.checkNumber` via API
  - Displays caller info overlay with reputation score
  - Auto-blocks known spam numbers based on user rules
  - Logs screened calls for history
- `android/app/src/main/java/com/shieldai/android/util/PermissionManager.kt` — Permission handling:
  - Centralized manager for all runtime permissions
  - Camera, microphone, phone, notifications, call screening
  - Handles permission rationale and denied states
- `android/app/src/main/AndroidManifest.xml` — Updated permissions and services:
  - `INTERNET`, `RECORD_AUDIO`, `READ_PHONE_STATE`, `CALL_PHONE`
  - `BIND_CALL_SCREENING_SERVICE`
  - `RECEIVE_BOOT_COMPLETED` (for starting services)
  - FCM service declaration
  - Call screening service declaration

steps:
1. **Push Notifications (FCM)**:
   - Add `google-services.json` to `app/` directory
   - Add `com.google.gms:google-services` plugin to build.gradle
   - Create `FCMService.kt` extending `FirebaseMessagingService`
   - `onNewToken`: send to backend via `api.notification.registerDevice`
   - `onMessageReceived`:
     - Parse notification payload
     - Create notification channel if not exists (Android 8+)
     - Show notification with `NotificationManager`
     - Handle data messages (silent pushes) for background sync
   - Add `FirebaseMessaging.getInstance().subscribeToTopic("alerts")` for broadcast alerts
   - Handle notification tap: extract `screen` and `id`, navigate via deep link
2. **Biometric Auth**:
   - `BiometricPrompt` with `BiometricPrompt.PromptInfo`
   - `setDeviceCredentialAllowed(true)` for fallback
   - `setConfirmationRequired(false)` for faster auth
   - On success: unlock `EncryptedSharedPreferences`
   - Show prompt on app launch if biometric is enabled
3. **Voice Recording**:
   - Request `RECORD_AUDIO` permission at runtime
   - `AudioRecord` with `MediaRecorder.AudioSource.MIC`
   - Configuration: 16kHz, mono, 16-bit PCM
   - Real-time waveform: read amplitude in a coroutine, update `Canvas` path
   - Minimum duration: 5 seconds
   - Save as WAV file
   - Playback with `MediaPlayer`
   - Submit to API via multipart upload
4. **Call Screening**:
   - Extend `CallScreeningService`
   - `onScreenCall(details)` callback when incoming call arrives
   - Extract phone number from `Call.Details`
   - Query API: `spamshield.checkNumber` (use cached result if available)
   - `respondToCall` with `CallResponse.Builder`:
     - If spam: `setDisallowCall(true)`, `setRejectCall(true)`, `setSkipCallLog(false)`
     - If suspicious: `setDisallowCall(false)` but show warning notification
     - If clean: `setDisallowCall(false)`
   - Show custom incoming call UI overlay (optional, requires additional permissions)
   - Log all screened calls to local DB
5. **Permission Manager**:
   - `checkPermission(permission)` → boolean
   - `requestPermission(permission, rationale)` → shows dialog, then system prompt
   - `handlePermissionResult(requestCode, permissions, grantResults)`
   - Guides user to Settings if permission permanently denied
6. Update manifest:
   - Add all required permissions
   - Declare FCM service with `android:exported="false"`
   - Declare call screening service with `android:permission="android.permission.BIND_CALL_SCREENING_SERVICE"`
7. Test on physical device (emulator cannot test FCM, biometrics, or call screening accurately).

steps:
- Unit: FCMService parses notification payload correctly
- Unit: BiometricPrompt configuration is valid
- Unit: PermissionManager returns correct status for each permission
- Integration: FCM token registration sends correct data to backend
- E2E: Receive test push notification and verify deep link navigation
- E2E: Record voice sample and submit enrollment successfully
- E2E: Simulate incoming call and verify screening logic

acceptance_criteria:
- [ ] App registers for FCM and sends device token to backend
- [ ] Incoming push notifications display correctly with channels and actions
- [ ] Tapping a notification deep links to the correct screen
- [ ] Face/fingerprint authentication works for app unlock
- [ ] Voice recording captures audio, shows waveform, and submits enrollment
- [ ] Call screening intercepts incoming calls and blocks known spam
- [ ] All permission requests include explanatory rationale
- [ ] Denied permissions show helpful guidance to Settings app
- [ ] Native features work on phones with API 26+

validation:
- Test push notifications using Firebase Console
- Verify biometric auth on device with face/fingerprint sensor
- Record a 10-second voice sample and verify enrollment created in backend
- Simulate incoming call using `adb shell am start -a android.intent.action.CALL -d tel:1234567890`
- Run `./gradlew test` for unit tests

notes:
- FCM requires a `google-services.json` file from Firebase Console. Add setup instructions to README.
- Call screening (`CallScreeningService`) is only available on Android 10+ (API 29+). For older versions, use a broadcast receiver for `PHONE_STATE` changes as fallback.
- The call screening service runs in the background and must be lightweight. Offload API calls to a coroutine.
- For call screening UI, the system provides a default incoming call screen. Custom UI overlays require `SYSTEM_ALERT_WINDOW` permission and are complex to implement correctly.
- Voice recording quality matters for ML model accuracy. Use 16kHz mono WAV — this matches the web app's preprocessing pipeline.
- Biometric auth should be optional. Users can always use password login.
- Consider adding a Quick Settings tile for toggling call screening on/off.
- For Android 14+ (API 34+), use the new `android.telecom.Call Screening` APIs if available.
