Skip to content

android: support text and link sharing#814

Draft
willh-ts wants to merge 1 commit into
mainfrom
will/taildrop/links
Draft

android: support text and link sharing#814
willh-ts wants to merge 1 commit into
mainfrom
will/taildrop/links

Conversation

@willh-ts

Copy link
Copy Markdown

This enhances the Android share feature as follows:

  • Text and URLs will be recognized and shared via the .tdpl encapsulation described below
  • Files, text, and URLs will now show a small banner atop the devices list, mirroring iOS behavior.
  • If multiple taildrops arrive, tapping the banner will open a bottom sheet to take action on them individually.
  • Files can be opened or the enclosing taildrop folder opened.
  • Text can be copied.
  • URLs can be opened in the default browser.
  • "Recently Used" taildrop targets will be locally cached and presented atop the list. Presentation & max length matches iOS behavior.
  • Simple polling for online status is added to avoid the need to reload the share sheet to find devices that connect while it is visible.
  • Fixes a bug that can cause the share sheet to be non-functional if you share; don't exit the view; share again

The iOS and macOS share extensions are currently receiving minor Taildrop enhancements to support sharing of Text and URLs from the OS-level share menu. Rather than sending text/urls raw and fighting OS differences or adding a different Tailscale feature beyond taildrop to support this, text and URLs will be encapsulated preflight in a minimal, json-formatted envelope, named [hash].tdpl

Parallel PRs:

.tdpl ("taildrop payload") was chosen both to conform to a 4-letter file deduplication suffix requirement and because it is not already a well-known extension. For version 1, the structure is simply:

{version:1, content:"the text or url", kind:"text|url"}

iOS & macOS (in https://github.com/tailscale/corp/pull/44001), Android (with these changes), and soon Windows and Linux will recognize these file types and respond accordingly upon receipt of .tdpl files:

  • Kind "text": Notification presented to "copy" the text to the clipboard.
  • Kind "url": Notification presented to "open" the link

For platforms that lack in-app notifications, the files will additionally be unwrapped & saved to the Taildrop folder as "Text [timestamp].txt", "URL [timestamp].webloc", or "URL [timestamp].url". This addresses a limitation for users who explicitly opt-out of app notifications. Those users would otherwise receive no transferred content whatsoever.

All other taildrop file transfer functionality remain unchanged.

updates tailscale/tailscale#4896
updates tailscale/tailscale#4996
fixes tailscale/tailscale#16850

@willh-ts willh-ts requested review from barnstar and kari-ts June 26, 2026 20:09
@willh-ts willh-ts force-pushed the will/taildrop/links branch from 2d7aa5b to cbda6b1 Compare June 26, 2026 21:09
Comment thread android/src/main/java/com/tailscale/ipn/ui/viewModel/MainViewModel.kt Outdated
val title =
intent.getCharSequenceExtra(Intent.EXTRA_SUBJECT)?.toString()?.takeIf { it.isNotBlank() }

val kind =

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe require http/https when classifying?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep this permissive for any valid protocol. Mac and (hopefully soon) iOS, for example, support tailscale: deep-link navigation. e.g., "share a link to open device or service XYZ details", "open Settings > Accounts", etc.

Users could legitimately want to Taildrop tel:, sms:, mailto:, ftp:, ssh: or other app-defined links between their devices, and the Android share sheet hands us all of those. The classifier just decides between "URL" and "text" presentation (tap to open vs. tap to copy). If the scheme isn't browsable, BrowserOpener.openInDefaultBrowser will fail and we should fall back to the text / clipboard copy path. Restricting here would force valid links down the text path and lose the "tap to open" affordance.

Comment thread android/src/main/java/com/tailscale/ipn/ui/view/TaildropBannerView.kt Outdated
object BrowserOpener {
// Pin the ACTION_VIEW to the user's default browser package so non-browser
// apps that also claim http(s) (e.g. the Google app) don't trigger the chooser.
fun openInDefaultBrowser(context: Context, uri: Uri): Boolean {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we restrict to http/https uris?

@willh-ts willh-ts Jun 29, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated slightly to let this handle both http/https and any supported protocol:

Tested, functional

  • http:, https:, tel:, sms:, mailto:.

Tested, not yet supported, falls through to "copy" handler on tap:

  • tailscale:

Tested, fails & falls through to "copy" handler:

  • invalid:

The latter 2 could be improved slightly (i.e., we could show "copy" instead of "open" for the subtitle) if we used PackageManager.resolveActivity to preemptively check whether a URL can be handled, but as I understand it, older Android versions and some OEM flavors restrict access to that.

Screenshot_20260629_120306

Comment thread android/src/main/java/com/tailscale/ipn/util/TaildropUsageTracker.kt Outdated
@willh-ts willh-ts force-pushed the will/taildrop/links branch 2 times, most recently from e2e4765 to 5598b66 Compare June 29, 2026 16:00
This enhances the Android share feature as follows:
- Text and URLs will be recognized and shared via the .tdpl encapsulation described below
- Files, text, and URLs will now show a small banner atop the devices list, mirroring iOS behavior.
- If multiple taildrops arrive, tapping the banner will open a bottom sheet to take action on them individually.
- Files can be opened or the enclosing taildrop folder opened.
- Text can be copied.
- URLs can be opened in the default browser.
- "Recently Used" taildrop targets will be locally cached and presented atop the list. Presentation & max length matches iOS behavior.
- Simple polling for online status is added to avoid the need to reload the share sheet to find devices that connect while it is visible.
- Fixes a bug that can cause the share sheet to be non-functional if you share; don't exit the view; share again

The iOS and macOS share extensions are currently receiving minor
Taildrop enhancements to support sharing of Text and URLs from
the OS-level share menu. Rather than sending text/urls raw and fighting
OS differences or adding a different Tailscale feature beyond taildrop
to support this, text and URLs will be encapsulated preflight in
a minimal, json-formatted envelope, named [hash].tdpl

.tdpl ("taildrop payload") was chosen both to conform to a 4-letter
file deduplication suffix requirement and because it is not already a
well-known extension. For version 1, the structure is simply:

`{version:1, content:"the text or url", kind:"text|url"}`

iOS & macOS (in tailscale/corp#44001), Android
(with these changes), and soon Windows and Linux will recognize these
file types and respond accordingly upon receipt of .tdpl files:
- Kind "text": Notification presented to "copy" the text to the clipboard.
- Kind "url": Notification presented to "open" the link

For platforms that lack in-app notifications, the files will additionally
be unwrapped & saved to the Taildrop folder as "Text [timestamp].txt",
"URL [timestamp].webloc", or "URL [timestamp].url". This addresses
a limitation for users who explicitly opt-out of app notifications. Those
users would otherwise receive no transferred content whatsoever.

All other taildrop file transfer functionality remain unchanged.

updates tailscale/tailscale#4896
updates tailscale/tailscale#4996
fixes tailscale/tailscale#16850

Signed-off-by: Will Hannah <willh@tailscale.com>
@willh-ts willh-ts force-pushed the will/taildrop/links branch from 5598b66 to f0f55e3 Compare June 29, 2026 16:33
@willh-ts willh-ts marked this pull request as draft June 30, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Taildrop sharing should share text if stream is unavailable

2 participants