YAACC - UPNP Client and Server
Loading...
Searching...
No Matches
de.yaacc.yxc.YxcMonitor Class Reference

Keeps the YxcDeviceState of the devices that speak the protocol up to date for the receiver row. More...

Collaboration diagram for de.yaacc.yxc.YxcMonitor:
Collaboration graph

Classes

interface  Cancellable
 
interface  Listener
 
interface  Scheduler
 
interface  TransportFactory
 

Public Member Functions

 YxcMonitor (YxcDiscovery discovery, YxcEventSource.Factory sourceFactory, TransportFactory transports, Executor io, Scheduler scheduler)
 
void subscribe (Listener listener, Map< String, String > devices)
 Registers the listener and watches the devices.
 
synchronized void unsubscribe (Listener listener)
 Removes the listener; the last one leaving stops the monitor after STOP_DELAY_MILLIS.
 
synchronized YxcDeviceState getState (String udn)
 
synchronized List< YxcDeviceSnapshot > snapshot ()
 
YxcClient newClient (String udn)
 
synchronized YxcEndpoint getEndpoint (String udn)
 
void refreshGroupInfoNow (Collection< String > udns)
 Reads the group information of the given devices now, on the calling thread, whether the monitor runs or not.
 
void refreshGroupInfoNow (Collection< String > udns, long budgetMillis)
 Like refreshGroupInfoNow(Collection), but no device is started on once the budget is used up (one that is under way finishes within the transport's own limits).
 
void prepareNow (Map< String, String > devices)
 Makes sure the given devices are watched and, for the ones not looked at yet, finds out on the calling thread whether they speak the protocol.
 
void prepareNow (Map< String, String > devices, long budgetMillis)
 Like prepareNow(Map); no device is looked at once the budget is used up.
 
synchronized String getLastPlainInput (String udn)
 
synchronized boolean isActive ()
 
synchronized void refreshNow (String udn)
 Asks for a complete read of one device now, for example after the app changed something on it.
 
synchronized void refreshPlayInfoNow (String udn)
 Asks for the play info of one device now (the network source and, on the tuner input, the tuner), for example while a tuner scan runs: the tuner's own events are not used (they flood).
 

Static Public Member Functions

static synchronized YxcMonitor getShared ()
 The app-wide monitor with the real network, threads and clock.
 

Static Public Attributes

static final long STOP_DELAY_MILLIS = 30_000L
 
static final long POLL_INTERVAL_MILLIS = 30_000L
 
static final long DEBOUNCE_MILLIS = 500L
 
static final long DEFAULT_NOW_BUDGET_MILLIS = 5_000L
 The time a send gives the reads that decide where it goes (prepareNow, refreshGroupInfoNow).
 

Detailed Description

Keeps the YxcDeviceState of the devices that speak the protocol up to date for the receiver row.

Lifetime. Everything runs only while somebody is subscribed (a sheet or the receiver tab on screen). The UDP event source is opened with the first subscriber and closed STOP_DELAY_MILLIS after the last one left, so switching between the tab and the sheet does not close and reopen it; polling stops at the same time.

Reading. A device is first looked at by YxcDiscovery (once per UDN); only devices that speak the protocol are ever talked to again. Every POLL_INTERVAL_MILLIS all of them are read completely: that is the fallback when events do not arrive (a firewall, a device that dropped the registration) and it renews the registration, which every request carries. Events are applied at once when they carry the value (power, volume, mute, input); flags that only say "changed" ask for a read of the matching call, after DEBOUNCE_MILLIS without a further such event, so a burst of five datagrams makes one read.

Trust. An event counts only when it comes from the address of a device found by our own discovery and, if it names a device_id, the one of that device. Everything else is dropped.

Threads. The listeners are called on a worker or scheduler thread, never with the lock held; a listener that touches views posts to the main thread. The clock, the threads and the network are injected so the behavior is tested on the JVM without waiting.

Member Function Documentation

◆ getEndpoint()

synchronized YxcEndpoint de.yaacc.yxc.YxcMonitor.getEndpoint ( String udn)
Returns
the endpoint of a watched device that speaks the protocol, null for any other

Referenced by de.yaacc.yxc.YxcMonitorEnvironment.members().

Here is the caller graph for this function:

◆ getLastPlainInput()

synchronized String de.yaacc.yxc.YxcMonitor.getLastPlainInput ( String udn)
Returns
the last input of the device that was not the link input, null if it was never seen

Referenced by de.yaacc.yxc.YxcMonitorEnvironment.lastPlainInput().

Here is the caller graph for this function:

◆ getState()

synchronized YxcDeviceState de.yaacc.yxc.YxcMonitor.getState ( String udn)
Returns
the last state of a watched device that speaks the protocol, null for any other

◆ isActive()

synchronized boolean de.yaacc.yxc.YxcMonitor.isActive ( )
Returns
whether the events are being received right now (for tests and diagnostics)

◆ newClient()

YxcClient de.yaacc.yxc.YxcMonitor.newClient ( String udn)
Returns
a client for a watched device that speaks the protocol, null for any other. It sends no event port, so it does not change what the device pushes to the monitor.

Referenced by de.yaacc.yxc.YxcMonitor.refreshGroupInfoNow().

Here is the caller graph for this function:

◆ prepareNow()

void de.yaacc.yxc.YxcMonitor.prepareNow ( Map< String, String > devices)

Makes sure the given devices are watched and, for the ones not looked at yet, finds out on the calling thread whether they speak the protocol.

For a send that is decided before any screen has subscribed (the selection of receivers is stored, the monitor starts empty). Does not start polling or the event source. Blocks for the time of the description fetches (bounded; a verdict is remembered).

Parameters
devicesUDN to the URL the registry fetched its description from

Referenced by de.yaacc.yxc.YxcMonitor.prepareNow().

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

◆ refreshGroupInfoNow() [1/2]

void de.yaacc.yxc.YxcMonitor.refreshGroupInfoNow ( Collection< String > udns)

Reads the group information of the given devices now, on the calling thread, whether the monitor runs or not.

For the moment a send is decided: the last state of a device may be older than the last change of the group. Devices that are not watched or do not speak the protocol are skipped; one that does not answer is marked unreachable. Blocks for at most the time of the transport's timeouts per device.

Referenced by de.yaacc.yxc.YxcMonitor.refreshGroupInfoNow().

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

◆ refreshGroupInfoNow() [2/2]

void de.yaacc.yxc.YxcMonitor.refreshGroupInfoNow ( Collection< String > udns,
long budgetMillis )

Like refreshGroupInfoNow(Collection), but no device is started on once the budget is used up (one that is under way finishes within the transport's own limits).

A send must not wait minutes for slow devices.

Here is the call graph for this function:

◆ refreshPlayInfoNow()

synchronized void de.yaacc.yxc.YxcMonitor.refreshPlayInfoNow ( String udn)

Asks for the play info of one device now (the network source and, on the tuner input, the tuner), for example while a tuner scan runs: the tuner's own events are not used (they flood).

Cheaper than refreshNow.

◆ snapshot()

synchronized List< YxcDeviceSnapshot > de.yaacc.yxc.YxcMonitor.snapshot ( )
Returns
the watched devices that speak the protocol and were read at least once, with their last states; the view the group logic works on

Referenced by de.yaacc.yxc.YxcMonitorEnvironment.members().

Here is the caller graph for this function:

◆ subscribe()

void de.yaacc.yxc.YxcMonitor.subscribe ( Listener listener,
Map< String, String > devices )

Registers the listener and watches the devices.

Devices already watched are not read again at once, new ones are; if the monitor had stopped, everything is read again (events were missed).

Parameters
devicesUDN to the URL the registry fetched its description from

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