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 <zachb@tailscale.com>
pull/613/merge
Zach Buchheit 6 months ago committed by GitHub
parent 5f59a367e3
commit b9993097fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -49,6 +49,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument import androidx.navigation.navArgument
import com.tailscale.ipn.mdm.MDMSettings import com.tailscale.ipn.mdm.MDMSettings
import com.tailscale.ipn.mdm.ShowHide
import com.tailscale.ipn.ui.model.Ipn import com.tailscale.ipn.ui.model.Ipn
import com.tailscale.ipn.ui.notifier.Notifier import com.tailscale.ipn.ui.notifier.Notifier
import com.tailscale.ipn.ui.theme.AppTheme import com.tailscale.ipn.ui.theme.AppTheme
@ -133,6 +134,9 @@ class MainActivity : ComponentActivity() {
App.get() App.get()
vpnViewModel = ViewModelProvider(App.get()).get(VpnViewModel::class.java) 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 // (jonathan) TODO: Force the app to be portrait on small screens until we have
// proper landscape layout support // proper landscape layout support
if (!isLandscapeCapable()) { if (!isLandscapeCapable()) {
@ -363,9 +367,7 @@ class MainActivity : ComponentActivity() {
onNavigateHome = backTo("main"), backTo("userSwitcher")) onNavigateHome = backTo("main"), backTo("userSwitcher"))
} }
} }
if (shouldDisplayOnboarding()) {
// Show the intro screen one time
if (!introScreenViewed()) {
navController.navigate("intro") navController.navigate("intro")
setIntroScreenViewed(true) setIntroScreenViewed(true)
} }
@ -523,8 +525,11 @@ class MainActivity : ComponentActivity() {
startActivity(intent) startActivity(intent)
} }
private fun introScreenViewed(): Boolean { private fun shouldDisplayOnboarding(): Boolean {
return getSharedPreferences("introScreen", Context.MODE_PRIVATE).getBoolean("seen", false) 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) { private fun setIntroScreenViewed(seen: Boolean) {

@ -101,6 +101,9 @@ object MDMSettings {
// Overrides the value provided by os.Hostname() in Go // Overrides the value provided by os.Hostname() in Go
val hostname = StringMDMSetting("Hostname", "Device Hostname") 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 { val allSettings by lazy {
MDMSettings::class MDMSettings::class
.declaredMemberProperties .declaredMemberProperties

@ -220,6 +220,8 @@
<string name="run_as_exit_node_visibility">Run as exit node visibility</string> <string name="run_as_exit_node_visibility">Run as exit node visibility</string>
<string name="defines_an_auth_key_that_will_be_used_for_login">Defines an auth key that will be used for login.</string> <string name="defines_an_auth_key_that_will_be_used_for_login">Defines an auth key that will be used for login.</string>
<string name="auth_key">Auth Key</string> <string name="auth_key">Auth Key</string>
<string name="skips_the_intro_page_shown_to_users_that_open_the_app_for_the_first_time">Skips the intro page shown to users that open the app for the first time</string>
<string name="onboarding_flow">Skip the Onboarding Flow</string>
<!-- Permissions Management --> <!-- Permissions Management -->
<string name="permissions">Permissions</string> <string name="permissions">Permissions</string>

@ -140,4 +140,12 @@
android:key="Hostname" android:key="Hostname"
android:restrictionType="string" android:restrictionType="string"
android:title="@string/hostname" /> android:title="@string/hostname" />
<restriction
android:description="@string/skips_the_intro_page_shown_to_users_that_open_the_app_for_the_first_time"
android:entries="@array/show_hide_labels"
android:entryValues="@array/show_hide"
android:key="OnboardingFlow"
android:restrictionType="choice"
android:title="@string/onboarding_flow" />
</restrictions> </restrictions>
Loading…
Cancel
Save