11package io.homeassistant.companion.android.onboarding
22
33import android.app.Activity
4- import android.content.pm.PackageManager
54import android.net.Uri
65import androidx.annotation.VisibleForTesting
7- import androidx.compose.ui.util.fastAny
8- import androidx.core.content.ContextCompat
96import androidx.navigation.NavController
107import androidx.navigation.NavGraphBuilder
118import androidx.navigation.NavOptions
@@ -42,7 +39,6 @@ import io.homeassistant.companion.android.onboarding.wearmtls.navigation.wearMTL
4239import io.homeassistant.companion.android.onboarding.welcome.navigation.WelcomeRoute
4340import io.homeassistant.companion.android.onboarding.welcome.navigation.welcomeScreen
4441import io.homeassistant.companion.android.util.canGoBack
45- import io.homeassistant.companion.android.util.compose.locationPermissions
4642import io.homeassistant.companion.android.util.compose.navigateToUri
4743import kotlinx.serialization.Serializable
4844
@@ -84,23 +80,25 @@ data class WearOnboardingRoute(val wearName: String, val urlToOnboard: String? =
8480 * - Server accessibility (local vs public)
8581 * - App flavor (full with Google Play Services vs minimal FOSS)
8682 * - Connection security (HTTP vs HTTPS)
87- * - Permission state (location access)
8883 *
8984 * ## Flow Overview
90- * 1. Welcome screen (only shown if [skipWelcome] is false)
91- * 2. Server discovery (only shown if [urlToOnboard] is empty)
92- * 3. Connection
93- * 3. Device naming and registration
94- * 4. Location/security configuration (conditional)
95- * 5. Home network configuration (if applicable)
85+ * 1. Welcome screen (skipped if [skipWelcome] is true)
86+ * 2. Server discovery (skipped if [urlToOnboard] is provided)
87+ * 3. Connection and authentication
88+ * 4. Device naming and registration
89+ * 5. Post-registration flow based on server configuration:
90+ * - Local-only servers: Local first screen → (full flavor only: Location sharing →) Secure connection (HTTP) or done (HTTPS)
91+ * - Public servers with full flavor: Location sharing → Secure connection (HTTP) or done (HTTPS)
92+ * - Public servers with minimal flavor: Secure connection (HTTP) or done (HTTPS)
93+ * 6. Home network configuration (if user opts for secure-only connection)
9694 *
9795 * @param navController Navigation controller for managing navigation actions
9896 * @param onShowSnackbar Callback to display snackbar messages to the user
9997 * @param onOnboardingDone Callback invoked when onboarding completes successfully
10098 * @param urlToOnboard Optional server URL to onboard directly, bypassing server discovery
10199 * @param hideExistingServers When true, hides already registered servers from discovery
102100 * @param skipWelcome When true, skips the welcome screen and goes directly to server discovery or connection
103- * @param hasLocationTracking Whether location tracking is available (default to full flavor = true, minimal = false)
101+ * @param hasLocationTracking Whether location tracking is available (full flavor = true, minimal = false)
104102 */
105103internal fun NavGraphBuilder.onboarding (
106104 navController : NavController ,
@@ -172,7 +170,7 @@ internal fun NavGraphBuilder.onboarding(
172170 navOptions = navOptions,
173171 )
174172 } else {
175- navController.navigateForMinimalFlavor (
173+ navController.navigateToLocationForSecureConnectionConditionally (
176174 serverId = serverId,
177175 hasPlainTextAccess = hasPlainTextAccess,
178176 navOptions = navOptions,
@@ -187,12 +185,12 @@ internal fun NavGraphBuilder.onboarding(
187185 navController.navigateToUri(URL_GETTING_STARTED_DOCUMENTATION )
188186 },
189187 onGotoNextScreen = { serverId, hasPlainTextAccess ->
190- navController.navigateForMinimalFlavor (
188+ navController.navigateToLocationForSecureConnectionConditionally (
191189 serverId = serverId,
192- hasPlainTextAccess = hasPlainTextAccess,
193190 navOptions = navOptions {
194191 popUpTo<LocationSharingRoute > { inclusive = true }
195192 },
193+ hasPlainTextAccess = hasPlainTextAccess,
196194 onOnboardingDone = onOnboardingDone,
197195 )
198196 },
@@ -297,26 +295,13 @@ private fun NavGraphBuilder.commonScreens(navController: NavController, wearName
297295 )
298296}
299297
300- /* *
301- * Checks if location permissions need to be requested.
302- *
303- * @return `true` if any location permission is not granted, `false` if all are granted
304- */
305- private fun NavController.shouldRequestLocationPermissions (): Boolean {
306- return locationPermissions.fastAny {
307- ContextCompat .checkSelfPermission(context, it) == PackageManager .PERMISSION_DENIED
308- }
309- }
310-
311298/* *
312299 * Navigates to the appropriate next screen after device registration based on server configuration.
313300 *
314- * This function encapsulates the complex decision tree for post-registration navigation,
315- * considering:
316- * - Whether the server is publicly accessible
317- * - Whether location tracking is available (full vs minimal flavor)
318- * - Whether the connection uses plain text HTTP
319- * - Whether location permissions are already granted
301+ * Navigation decision tree:
302+ * - Local-only server (!isPubliclyAccessible) → Local first screen
303+ * - Public server with location tracking (full flavor) → Location sharing screen
304+ * - Public server without location tracking (minimal flavor) → Secure connection (HTTP) or done (HTTPS)
320305 *
321306 * @param serverId The ID of the registered server
322307 * @param hasPlainTextAccess Whether the server connection uses HTTP (insecure)
@@ -346,8 +331,7 @@ private fun NavController.navigateAfterDeviceRegistration(
346331 hasPlainTextAccess = hasPlainTextAccess,
347332 navOptions = navOptions,
348333 )
349- // Minimal flavor: handle location and security based on connection type
350- else -> navigateForMinimalFlavor(
334+ else -> navigateToLocationForSecureConnectionConditionally(
351335 serverId = serverId,
352336 hasPlainTextAccess = hasPlainTextAccess,
353337 navOptions = navOptions,
@@ -357,14 +341,13 @@ private fun NavController.navigateAfterDeviceRegistration(
357341}
358342
359343/* *
360- * Navigates to the appropriate screen for minimal flavor after location-related setup .
344+ * Conditionally navigates to the secure connection screen based on connection security .
361345 *
362- * For minimal flavor (without location tracking), the flow is:
363- * - If HTTPS: onboarding is complete
364- * - If HTTP and no location permission: ask for location to enable secure connection detection
365- * - If HTTP and has location permission: configure home network
346+ * Navigation decision:
347+ * - HTTPS connection (!hasPlainTextAccess) → Onboarding complete
348+ * - HTTP connection → Navigate to secure connection screen to configure home network detection
366349 */
367- private fun NavController.navigateForMinimalFlavor (
350+ private fun NavController.navigateToLocationForSecureConnectionConditionally (
368351 serverId : Int ,
369352 hasPlainTextAccess : Boolean ,
370353 navOptions : NavOptions ,
@@ -376,12 +359,7 @@ private fun NavController.navigateForMinimalFlavor(
376359 return
377360 }
378361
379- // HTTP connection: need location for secure connection detection
380- if (shouldRequestLocationPermissions()) {
381- navigateToLocationForSecureConnection(serverId = serverId, navOptions = navOptions)
382- } else {
383- navigateToSetHomeNetworkRoute(serverId = serverId, navOptions = navOptions)
384- }
362+ navigateToLocationForSecureConnection(serverId = serverId, navOptions = navOptions)
385363}
386364
387365/* *
0 commit comments