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.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) {

@ -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

@ -220,6 +220,8 @@
<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="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 -->
<string name="permissions">Permissions</string>

@ -140,4 +140,12 @@
android:key="Hostname"
android:restrictionType="string"
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>
Loading…
Cancel
Save