The Onboarding module is the gateway to the application, designed to guide users through a complex configuration process. Given the app’s nature (likely a digital wellbeing or focus tool), it requires several “sensitive” Android permissions.This module transforms a tedious technical checklist into a premium user experience using:
Educational Storytelling: Explaining the “Philosophy” before asking for data.
Visual Feedback: Using to provide fluid, organic transitions.
Reactive Validation: Real-time permission polling to allow the user to progress only when requirements are met.
The “Brain” of the module. It acts as a bridge between the and the Compose UI. It does not store data in a database; instead, it treats the Android OS as its “Source of Truth.”
Uses a HorizontalPager to manage the linear flow of onboarding. It implements custom graphicsLayer transformations to create a “fade and slide” transition between steps, ensuring the experience feels cohesive rather than fragmented.
Unlike standard apps that check permissions once, this module uses a LifecycleEventObserver. When the user returns from the System Settings (after granting a permission), the ON_RESUME event triggers viewModel.checkPermissions(context). This creates a seamless “Auto-advance” feel.
The “Data” in this module is the SetupUiState. The ViewModel performs a series of transformations to simplify the UI logic:
Source Mapping: It maps complex system checks (e.g., checking if an AccessibilityService is specifically enabled for this package) into simple Boolean flags.
Validation Logic: It computes a derived property allPermissionsGranted which the UI uses to enable/disable the final “Complete” action.
String Synthesis: The getMissingPermissionMessage() function acts as a small data transformer, joining a list of missing requirements into a human-readable string for the .
AndroidX Graphics Shapes: Powers the complex polygon morphing.
Konfetti: Provides the celebration effect on the final “Features” page.
System Services:
AppOpsManager: For Usage Stats.
AccessibilityManager: For Accessibility Service status.
PowerManager: For Battery Optimization whitelisting.
Settings: For Overlay (Draw over apps) permissions.
Copy
// Example of the reactive transformation in the ViewModel_uiState.update { it.copy( usageStatsPermissionGranted = checkUsageStats(context), overlayPermissionGranted = Settings.canDrawOverlays(context), // ... other mappings )}