Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do we need remote.getAvailability()? #39

Closed
mfoltzgoogle opened this issue May 20, 2016 · 7 comments

Comments

@mfoltzgoogle
Copy link
Contributor

commented May 20, 2016

I think the use of a separate Availability object for remote playback device for this use case causes some problems for the spec.

  • What does it mean to call getAvailability() multiple times on the same MediaElement? Is the same object returned or different object?
  • If the source list changes, will the developer need to discard the old object and get a new one?
  • What if the media element is detached from the document: will the availability object keep it alive? What would its behavior be in this case?

One alternative would be to have an enum + event to track availability changes on the remote object itself, which would seem to address the issues above. Availability would be kept in sync with both device availability and the media source list.

partial interface RemotePlayback : EventTarget {

    readonly attribute RemotePlaybackAvailability availability;

    attribute EventHandler onavailabilitychange;

    enum RemotePlaybackAvailability {
            "available",
            "unavailable",
            "unknown"   // Background monitoring not supported.
    };
};
@jernoble

This comment has been minimized.

Copy link

commented May 23, 2016

@mfoltzgoogle said:

What does it mean to call getAvailability() multiple times on the same MediaElement? Is the same object returned or different object?

Since this is an object returned from a method (and not a property), it would be a different object for each
call.

If the source list changes, will the developer need to discard the old object and get a new one?

No; the onchange event might fire though.

What if the media element is detached from the document: will the availability object keep it alive? What would its behavior be in this case?

Since there's no way to get from a RemotePlaybackAvailability object to its associated media object, no, the availability object would not keep the element from being collected.

@avayvod

This comment has been minimized.

Copy link
Contributor

commented May 24, 2016

I think the main problem with the property + event handler is the same as it was with the Presentation API - either the UA doesn't know when to monitor availability and has to do it all the time for every live (and visible) media element just to keep availability up-to-date or it has to add weird side effects of adding an event listener (if the availability is known to the user agent at the time, fire an event immediately). Perhaps unknown state could be used to mitigate that:

partial interface RemotePlayback : EventTarget {

    // both attributes are defined if and only if the user agent supports background monitoring
    readonly attribute RemotePlaybackAvailability availability;
    attribute EventHandler onavailabilitychange;

    enum RemotePlaybackAvailability {
            "available",
            "unavailable",
            "unknown"   // the availability is unknown - monitoring algorithm is still running or hasn't run yet
    };
};

I also think that having a RemotePlaybackAvailability object without the media element is odd, the availability object may cache the last known media source to track availability for but there's no way to initiate remote playback with the media element gone so monitoring availability is kind of pointless.

@mounirlamouri

This comment has been minimized.

Copy link
Member

commented May 24, 2016

As @avayvod pointed, we can't really have a simple attribute+event unless we add an unknown state but still, in that case, we would need the developer to be able to request availability check so we might need to add startDiscovery (and stopDiscovery ?) for websites that want to show a remote playback button.

Actually, a pattern that start emerging on the platform is to have an observe() method, as used in Intersection Observer and IndexedDB observer. It would make the API surface simpler. We could add unobserve() if we believe it's needed. The availabilitychange event would only be fired if observe() was called.

@tidoust

This comment has been minimized.

Copy link
Contributor

commented May 24, 2016

Discussed at F2F:
http://www.w3.org/2016/05/24-webscreens-minutes.html#item03

ACTION: Anton to craft a PR to use observe/unobserve pattern for availability

Open question still remains on whether to add a specific feature for devices that do not support background monitoring for web apps to tell the difference between "there are remote devices available" and "there may be remote devices available but I cannot tell you until you call connect".

@avayvod

This comment has been minimized.

Copy link
Contributor

commented Jun 28, 2016

I've looked at the IntersectionObserver and IDBObserver. Both seem a bit too complex for our use case, creating new objects and all. I think I'd settle for using what Mark initially proposed - live availability attribute with an unknown value for when the state is unobserved or the media element source has changed, but using an observer pattern to work around the event handler issue of having to dispatch a fake change event for the listeners attached when the availability is known:

enum RemotePlaybackAvailability {
    "available",
    "unavailable",
    "unknown"
};

partial interface RemotePlayback {
    // "unknown" if there's no callbacks observing its changes or if observers are not supported.
    // May become "available" or "unavailable" if and only if there're any observers registered with
    // |observeAvailability|.
    readonly attribute RemotePlaybackAvailability availability;

    // The returned promise is fullfilled if the website should expect the callback to be called,
    // meaning the background monitoring of remote playback device availability is supported.
    // The |availability| may now change from "unknown" to other values.
    Promise<void> observeAvailability(RemotePlaybackAvailabilityCallback callback);

    // Stops calling the specified |callback| whenever |availability| changes. May stop the background
    // availability monitoring and change |availability| to "unknown".
    // If no callback is specified, stops calling any callbacks and changes |availability| to "unknown".
    // |availability| becomes "unknown".
    void unobserveAvailability(optional RemotePlaybackAvailabilityCallback callback);
};

// |available| is the new value that indicates if the devices are now available or not
// for the |element|.
callback RemotePlaybackAvailabilityCallback = void(boolean available);

In the essence this adds special versions addEventListener/removeEventListener methods to RemotePlayback to workaround the "adding/removing event handlers should have no side effects" rule.

@avayvod

This comment has been minimized.

Copy link
Contributor

commented Jun 29, 2016

We simplified it a bit today in an offline discussion with Mounir:

partial interface RemotePlayback {
    // Registers a callback to get called with the availability for the media element and its currently
    // selected source for remote playback. The callback maybe called immediately after the
    // returned promise is resolved if the availability is already known, the user agent
    // may keep running the monitoring algorithm as long as there's at least one callback registered
    // and call all the callbacks with the new value when it changes.
    // The promise is rejected if background monitoring is not available. Otherwise it's fulfilled with an id
    // that could be used to unregister the callback to save resources.
    Promise<long> watchAvailability(RemotePlaybackAvailabilityCallback callback);

    // Unregisters the callback with the specified id, or all callbacks if the id is not specified.
    // No-op if id is invalid.
    void cancelWatchAvailability(optional long id);
};

// |available| is the new value that indicates if the devices are now available or not.
callback RemotePlaybackAvailabilityCallback = void(boolean available);
@avayvod

This comment has been minimized.

Copy link
Contributor

commented Jul 11, 2016

Fixed by #49. Feel free to discuss the name (watch vs monitor vs observe, etc) in a new issue.

@avayvod avayvod closed this Jul 11, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.