Conversation
Both keys are declared in util/syspolicy/pkey, in the block described
there as keys whose string value controls visibility, and both are
documented in KB 1315 — but only for Windows. On Android they were not
exposed in MDMSettings, so app_restrictions.xml never advertised them to
MDM providers and nothing in the UI honored them.
AdminConsole shows or hides the admin console link in the settings
screen. PreferencesMenu shows or hides the settings screen itself, along
with its entry point in the main view.
The settings route is gated as well, not only its entry point: it is
reachable through the tailscale://navigate/settings deep link handled by
DeepLinkNavigator. It is gated rather than removed from the graph, since
a dozen sub-screens use backTo("settings") as their back destination;
gating it there also closes the screen if an administrator applies the
policy while it is open.
Avatar applied focusable() and clickable() unconditionally, so the
avatar that MainView now passes action = null still took D-pad focus and
showed a ripple while doing nothing. Both modifiers are gated on
action != null, which also drops a phantom focus stop in UserView, whose
avatar never had an action: there the ListItem itself carries the
clickable when the row is interactive.
Both keys default to show, so behavior is unchanged when they are not
set.
Updates tailscale/tailscale#21381
🤖 Généré avec Claude Code
Signed-off-by: Sarcouy <sarcouy@protonmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
AdminConsoleandPreferencesMenualready exist inutil/syspolicy/pkeybut were never read bythe Android client. This wires them up. No new key names, defaults unchanged.
The problem
On a fully managed Android device — Device Owner, always-on VPN with lockdown, restrictions pushed
through
setApplicationRestrictions— an administrator has no way to hide the settings screen orthe admin console link.
Both keys are declared in
tailscale.com/util/syspolicy/pkey, in the block described there as"keys with a string value that controls visibility", enforced by each platform's UI code, and both
are documented in KB 1315 — but only for Windows. On Android they were not exposed in
MDMSettings, so they were never advertised to MDM providers throughapp_restrictions.xml, andnothing in the UI honored them.
Same shape as #648, which defined
OnboardingFlowon Android.What the code does
MDMSettings: twoShowHideMDMSettingvalues.allSettingsreflects overdeclaredMemberProperties, so they are registered — and appear in the MDM debug view — with nofurther wiring.
app_restrictions.xml,strings.xml: the two restrictions, reusing the existingshow_hidearrays so MDM providers discover them automatically.
SettingsView: the admin console link is gated onAdminConsole.MainView: the settings entry point is gated onPreferencesMenu. When hidden, the avatar isstill rendered as an identity indicator but is no longer a navigation target (
action = null).MainActivity: thesettingsroute is gated as well, not only its entry point, because theroute is reachable through the
tailscale://navigate/settingsdeep link handled byDeepLinkNavigator. It is gated rather than removed from the graph, since a dozen sub-screens usebackTo("settings")as their back destination; gating it there also closes the screen if anadministrator applies the policy while it is open.
Avatar:focusable()andclickable()are now gated onaction != null. They were appliedunconditionally, so the avatar that
MainViewnow passesaction = nullstill took D-pad focusand showed a ripple while doing nothing. This also drops a phantom focus stop in
UserView,whose avatar never had an action: there the
ListItemitself carries theclickablewhen the rowis interactive.
Both keys default to
ShowHide.Show, so behavior is unchanged wherever they are not set.What the gate covers
PreferencesMenu: hidegates thesettingsroute and its entry point, not the sub-screensreachable from it (
userSwitcher,splitTunneling,dnsSettings, …). Those are siblingNavHostdestinations, and a
NavHostcomposes only the current back-stack entry, so a user already insideone when the policy arrives is not pushed back out. Entering them still requires passing through the
gated
settingsroute.That matches how the existing
ShowHidekeys behave on Android —ExitNodesPicker,ManageTailnetLockandRunExitNodeeach gate their entry point and leave their route reachable —so this change keeps the convention rather than diverging for a single key. Whether these keys
should gate routes rather than only entry points is a cross-platform question, raised in
tailscale/tailscale#21381 along with the
PreferencesMenumapping and the two screens that stillhave no policy of their own.
Updates tailscale/tailscale#21381
🤖 Generated with Claude Code