YAACC - UPNP Client and Server
Loading...
Searching...
No Matches
de.yaacc.browser.ShareIntentHandler Class Reference

Takes what another app shared to yaacc (ACTION_SEND): a link (text) or ONE file. More...

Collaboration diagram for de.yaacc.browser.ShareIntentHandler:
Collaboration graph

Classes

interface  FilePreparer
 What opens, registers and builds the item of a confirmed file (replaceable in tests). More...
 

Public Member Functions

 ShareIntentHandler (Context appContext, UpnpClient upnpClient)
 
void handle (Intent intent, Runnable onPlayersStarted)
 Reads a shared link from the intent and plays it.
 
void handle (Intent intent, Runnable onPlayersStarted, BrowserHost pickHost)
 Same as handle(Intent, Runnable), and for a shared file tells pickHost (BrowserHost#onPendingShare) that the user has to pick receivers.
 
void shutdown ()
 Releases the worker thread.
 
void confirm (String token, Set< String > chosenReceiverIds, Runnable afterStarted, Runnable finished)
 The user picked receivers for the pending share.
 
void confirm (String token, Set< String > chosenReceiverIds, Runnable afterStarted)
 Same without a finish callback.
 
void confirm (String token, Set< String > chosenReceiverIds)
 Same without a hook.
 
void cancel (String token)
 The user dismissed the picker: releases the pending share (nothing was opened).
 

Detailed Description

Takes what another app shared to yaacc (ACTION_SEND): a link (text) or ONE file.

Link. The shared text is untrusted. It is only checked by ShareUriPolicy (length cap, http or https only), parsed with Uri#parse(String) and handed to UpnpClient#createPlayableItem(Uri). It is never used to build an intent, a PendingIntent or a file path, and it is never logged.

In the new layout (the host owns the receiver bar) a link is not played at once either: it becomes the one pending share (named by a fixed text, never by the link), the host opens the receiver picker, and only confirm with the chosen receivers stores them, builds the item and plays. It never falls back to this device. Classic and a missing host keep the old behavior (wait for receivers, else this device).

File. An audio, video or image type selects the file path (exactly one of the two paths runs per intent). The activity can be started directly by any app, so nothing the launcher checked is trusted: StreamIntake repeats the checks (exactly ONE ClipData item whose URI is the only one read, never EXTRA_STREAM; no data; the read grant in the intent's own flags; the content policy; no provider of this app). The intent is consumed at once (rotation and recents never replay it). A file is accepted only if the intent carries a valid launch token (LaunchNonces): only LauncherActivity, after its checks, mints one, so a file sent straight to an exported browser activity is dropped. On a worker thread, with a timeout, the provider is asked for its type and display name; the MIME type is SharedContentPolicy#chooseMimeType output only. Then ONE share becomes pending (PendingShare): it holds only the validated URI text, the cleaned name and the type, no descriptor, no copy, no registry slot. The host is told (BrowserHost#onPendingShare); only confirm with the token (the user picked receivers) opens the file, registers the share for exactly the chosen receivers and plays it. cancel or the timeout just drops the pending state. Nothing is ever played without a confirmation, and a file never falls back to this device.

handle, confirm, cancel and shutdown are for the main thread. Only the application context is kept.

Constructor & Destructor Documentation

◆ ShareIntentHandler()

de.yaacc.browser.ShareIntentHandler.ShareIntentHandler ( Context appContext,
UpnpClient upnpClient )
Parameters
appContextany context; only the application context is kept
upnpClientthe client used to find receivers and create the playable item

Member Function Documentation

◆ cancel()

void de.yaacc.browser.ShareIntentHandler.cancel ( String token)

The user dismissed the picker: releases the pending share (nothing was opened).

A wrong token does nothing.

Referenced by de.yaacc.browser.BrowserActivity.onPendingShare(), and de.yaacc.browser.TabBrowserActivity.onPendingShare().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ confirm()

void de.yaacc.browser.ShareIntentHandler.confirm ( String token,
Set< String > chosenReceiverIds,
Runnable afterStarted,
Runnable finished )

The user picked receivers for the pending share.

Takes the share (once: a wrong, stale or second token does nothing), then on a worker opens the file, registers it for exactly these receivers, waits for the local server and plays it. Every failure closes what was opened, deletes a copy and removes the registry key, and tells the user.

Parameters
tokenthe token BrowserHost#onPendingShare delivered
chosenReceiverIdsthe ids of the receivers the user ticked; empty means nothing is played and the share is released (a file never plays on this device by default)
afterStartedruns on the main thread, once, after the receivers were stored and the playback was attempted (started or not), so the caller can clear or restore the receiver selection; not called if the selection was never changed (wrong token, empty selection, nothing opened or built); may be null
finishedruns exactly once, after afterStarted and on whichever thread ends the work, in EVERY case (a played share, a failed one, a wrong token, an empty selection, a shut-down handler): the caller ends its single flight here. May be null.

Referenced by de.yaacc.browser.ShareIntentHandler.confirm(), and de.yaacc.browser.ShareIntentHandler.confirm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle() [1/2]

void de.yaacc.browser.ShareIntentHandler.handle ( Intent intent,
Runnable onPlayersStarted )

Reads a shared link from the intent and plays it.

Does nothing for other actions. The text is removed from the intent so that a recreated activity does not play it twice.

Parameters
intentthe intent received by the activity
onPlayersStartedruns on the main thread after the players have been started, may be null

Referenced by de.yaacc.browser.ShareIntentHandler.handle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle() [2/2]

void de.yaacc.browser.ShareIntentHandler.handle ( Intent intent,
Runnable onPlayersStarted,
BrowserHost pickHost )

Same as handle(Intent, Runnable), and for a shared file tells pickHost (BrowserHost#onPendingShare) that the user has to pick receivers.

The handler holds the host only until shutdown().

Parameters
pickHostthe activity that shows the picker, may be null (the pending share then waits for its timeout)
Here is the call graph for this function:

◆ shutdown()

void de.yaacc.browser.ShareIntentHandler.shutdown ( )

Releases the worker thread.

Call from onDestroy. A share that is already waiting for receivers still plays (a rotation must not drop it): a graceful shutdown() lets scheduled tasks run and ends the thread afterwards. The handler ignores later calls to handle(Intent, Runnable).


The documentation for this class was generated from the following file: