diff --git a/ipn/ipnstate/ipnstate.go b/ipn/ipnstate/ipnstate.go index 97eb78032..3a464c9be 100644 --- a/ipn/ipnstate/ipnstate.go +++ b/ipn/ipnstate/ipnstate.go @@ -588,6 +588,8 @@ func osEmoji(os string) string { return "🖥️" case "iOS": return "📱" + case "tvOS": + return "🍎📺" case "android": return "🤖" case "freebsd": diff --git a/version/prop.go b/version/prop.go index a6cc124c6..386fcd64e 100644 --- a/version/prop.go +++ b/version/prop.go @@ -28,6 +28,9 @@ func OS() string { // differentiate them. Then a later Go release added GOOS=ios as a separate // platform, but by then the "iOS" and "macOS" values we'd picked, with that // exact capitalization, were already baked into databases. + if IsAppleTV() { + return "tvOS" + } if runtime.GOOS == "ios" { return "iOS" } @@ -76,6 +79,19 @@ func IsMacSysExt() bool { }) } +var isAppleTV lazy.SyncValue[bool] + +// IsAppleTV reports whether this binary is part of the Tailscale network extension for tvOS. +// Needed because runtime.GOOS returns "ios" otherwise. +func IsAppleTV() bool { + if runtime.GOOS != "ios" { + return false + } + return isAppleTV.Get(func() bool { + return strings.EqualFold(os.Getenv("XPC_SERVICE_NAME"), "io.tailscale.ipn.tvos.network-extension") + }) +} + var isWindowsGUI lazy.SyncValue[bool] // IsWindowsGUI reports whether the current process is the Windows GUI.