From b9993097fc46cf7a2374bffdd935de603cabff5f Mon Sep 17 00:00:00 2001 From: Zach Buchheit Date: Mon, 9 Jun 2025 12:20:31 -0700 Subject: [PATCH] mdm: define OnboardingFlow syspolicy on Android (#648) Adds an MDM setting `OnboardingFlow` which allows for the intro screen to be skipped when set to true. Adds MDM Setting update to the top of MainActivity onCreate to ensure the latest MDMSettings are accurate. When attempting to do this while relying on MDMSettings being update during onResume it created a race condition where occasionally OnboardingFlow was being evaluated to the default value `show` when in reality it should be set to `hide`. updates tailscale/corp#29482 Signed-off-by: zbuchheit --- .../main/java/com/tailscale/ipn/MainActivity.kt | 15 ++++++++++----- .../java/com/tailscale/ipn/mdm/MDMSettings.kt | 3 +++ android/src/main/res/values/strings.xml | 2 ++ android/src/main/res/xml/app_restrictions.xml | 8 ++++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/tailscale/ipn/MainActivity.kt b/android/src/main/java/com/tailscale/ipn/MainActivity.kt index 04b4724..a8549ce 100644 --- a/android/src/main/java/com/tailscale/ipn/MainActivity.kt +++ b/android/src/main/java/com/tailscale/ipn/MainActivity.kt @@ -49,6 +49,7 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import com.tailscale.ipn.mdm.MDMSettings +import com.tailscale.ipn.mdm.ShowHide import com.tailscale.ipn.ui.model.Ipn import com.tailscale.ipn.ui.notifier.Notifier import com.tailscale.ipn.ui.theme.AppTheme @@ -133,6 +134,9 @@ class MainActivity : ComponentActivity() { App.get() vpnViewModel = ViewModelProvider(App.get()).get(VpnViewModel::class.java) + val rm = getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager + MDMSettings.update(App.get(), rm) + // (jonathan) TODO: Force the app to be portrait on small screens until we have // proper landscape layout support if (!isLandscapeCapable()) { @@ -363,9 +367,7 @@ class MainActivity : ComponentActivity() { onNavigateHome = backTo("main"), backTo("userSwitcher")) } } - - // Show the intro screen one time - if (!introScreenViewed()) { + if (shouldDisplayOnboarding()) { navController.navigate("intro") setIntroScreenViewed(true) } @@ -523,8 +525,11 @@ class MainActivity : ComponentActivity() { startActivity(intent) } - private fun introScreenViewed(): Boolean { - return getSharedPreferences("introScreen", Context.MODE_PRIVATE).getBoolean("seen", false) + private fun shouldDisplayOnboarding(): Boolean { + val onboardingFlowShowHide = MDMSettings.onboardingFlow.flow.value.value + val introSeen = + getSharedPreferences("introScreen", Context.MODE_PRIVATE).getBoolean("seen", false) + return (onboardingFlowShowHide == ShowHide.Show && !introSeen) } private fun setIntroScreenViewed(seen: Boolean) { diff --git a/android/src/main/java/com/tailscale/ipn/mdm/MDMSettings.kt b/android/src/main/java/com/tailscale/ipn/mdm/MDMSettings.kt index c843d90..d8df61d 100644 --- a/android/src/main/java/com/tailscale/ipn/mdm/MDMSettings.kt +++ b/android/src/main/java/com/tailscale/ipn/mdm/MDMSettings.kt @@ -101,6 +101,9 @@ object MDMSettings { // Overrides the value provided by os.Hostname() in Go val hostname = StringMDMSetting("Hostname", "Device Hostname") + // Allows admins to skip the get started intro screen + val onboardingFlow = ShowHideMDMSetting("OnboardingFlow", "Suppress the intro screen") + val allSettings by lazy { MDMSettings::class .declaredMemberProperties diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml index 25ec4f1..ed1fa16 100644 --- a/android/src/main/res/values/strings.xml +++ b/android/src/main/res/values/strings.xml @@ -220,6 +220,8 @@ Run as exit node visibility Defines an auth key that will be used for login. Auth Key + Skips the intro page shown to users that open the app for the first time + Skip the Onboarding Flow Permissions diff --git a/android/src/main/res/xml/app_restrictions.xml b/android/src/main/res/xml/app_restrictions.xml index 363bfc5..b47cc58 100644 --- a/android/src/main/res/xml/app_restrictions.xml +++ b/android/src/main/res/xml/app_restrictions.xml @@ -140,4 +140,12 @@ android:key="Hostname" android:restrictionType="string" android:title="@string/hostname" /> + + \ No newline at end of file