From ac06b114d51437cbda9594c4ec58f5565b565bb0 Mon Sep 17 00:00:00 2001 From: keyar Date: Mon, 11 May 2026 13:04:12 -0300 Subject: [PATCH] Android App Shortcuts for Samsung/Google Routines Add static App Shortcuts (Connect/Disconnect) so Samsung Routines and Google Routines can trigger VPN connect/disconnect actions natively. Changes: - Create shortcuts.xml with static shortcut declarations - Add vector drawable icons for connect/disconnect - Handle shortcut intents in MainActivity (onCreate + onNewIntent) - Add shortcut-specific string resources The shortcuts target MainActivity with custom intent actions (SHORTCUT_CONNECT/SHORTCUT_DISCONNECT). When triggered, they call startVPN()/stopVPN() directly and finish() the activity immediately. Existing Tasker/broadcast functionality via IPNReceiver is preserved. Updates https://github.com/tailscale/tailscale/issues/9531 Signed-off-by: keyar --- android/src/main/AndroidManifest.xml | 3 ++ .../java/com/tailscale/ipn/MainActivity.kt | 32 +++++++++++++++++++ .../main/res/drawable/ic_shortcut_connect.xml | 11 +++++++ .../res/drawable/ic_shortcut_disconnect.xml | 11 +++++++ android/src/main/res/values/strings.xml | 3 ++ android/src/main/res/xml/shortcuts.xml | 30 +++++++++++++++++ 6 files changed, 90 insertions(+) create mode 100644 android/src/main/res/drawable/ic_shortcut_connect.xml create mode 100644 android/src/main/res/drawable/ic_shortcut_disconnect.xml create mode 100644 android/src/main/res/xml/shortcuts.xml diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 9633e2b2bd..ba9826cfee 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -57,6 +57,9 @@ + { + TSLog.d(TAG, "Shortcut: Connect VPN triggered") + App.get().startVPN() + finish() + true + } + action == ACTION_SHORTCUT_DISCONNECT || shortcutAction == "disconnect" -> { + TSLog.d(TAG, "Shortcut: Disconnect VPN triggered") + App.get().stopVPN() + finish() + true + } + else -> false + } + } + private fun login(urlString: String) { // Launch coroutine to listen for state changes. When the user completes login, relaunch // MainActivity to bring the app back to focus. diff --git a/android/src/main/res/drawable/ic_shortcut_connect.xml b/android/src/main/res/drawable/ic_shortcut_connect.xml new file mode 100644 index 0000000000..23e8b183c4 --- /dev/null +++ b/android/src/main/res/drawable/ic_shortcut_connect.xml @@ -0,0 +1,11 @@ + + + + diff --git a/android/src/main/res/drawable/ic_shortcut_disconnect.xml b/android/src/main/res/drawable/ic_shortcut_disconnect.xml new file mode 100644 index 0000000000..71015e64ac --- /dev/null +++ b/android/src/main/res/drawable/ic_shortcut_disconnect.xml @@ -0,0 +1,11 @@ + + + + diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml index 608f1f2a2e..aabe0a0a8c 100644 --- a/android/src/main/res/values/strings.xml +++ b/android/src/main/res/values/strings.xml @@ -7,6 +7,9 @@ None Connect Disconnect + Connect to Tailscale + Disconnect from Tailscale + Tailscale shortcut is not available Unknown user Connected Using exit node (%s) diff --git a/android/src/main/res/xml/shortcuts.xml b/android/src/main/res/xml/shortcuts.xml new file mode 100644 index 0000000000..1cd710cbb3 --- /dev/null +++ b/android/src/main/res/xml/shortcuts.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + +