Re: [discovery] DAP-ISSUE-131 Support UPnP device discovery by Device Type? (was RE: [discovery] Adding CORS to NSD API - proposal and issues)

On Wed, Oct 16, 2013 at 8:56 AM,  <Cathy.Chan@nokia.com> wrote:
>> From: ext Rich Tibbett [mailto:richt@opera.com]
>>
>> On Wed, Oct 16, 2013 at 1:41 AM, Giuseppe Pascale
>> <giuseppep@opera.com> wrote:
>> > On Tue, Oct 15, 2013 at 7:02 AM, Igarashi, Tatsuya
>> > <Tatsuya.Igarashi@jp.sony.com> wrote:
>> >>
>> >> Hi Giuseppe,
>> >>
>> >>
>> >> On Wed, Oct 16, 2013 at 1:41 AM, Giuseppe Pascale
>> <giuseppep@opera.com> wrote:
>> >>>
>> >>> I don't think this is the case, as how permission is asked is not
>> >>> mandated by the spec and the UA may request only once per device,
>> >>> regardless of the number of service searches you do (maybe by
>> >>> showing which services will be
>> >>> exposed)
>> >>>
>> >>
>> >> In the case that a web application specifies multiple types to the
>> >> getNetworkService method, do you mean how many dialogs pop-up is
>> >> implementation dependent ?
>> >>
>> >>
>> >>
>> >> promise = window . navigator . getNetworkServices ( type )
>> >>
>> >> Immediately returns a new Promise object and then the user is
>> >> prompted to select discovered network services that have advertised
>> >> support for the requested service type(s).
>> >>
>> >> In my understanding that UA must prompt per getNetworkServices
>> >> method. And I  assumed the case that a web application searches UPnP
>> >> Service B after searching UPnP Service A which is founded in the
>> >> Device Description of UPnP Device X. This case causes two popup
>> >> dialogs by the two getNetworkServices() methods. I do not think that
>> >> all web application must know what UPnP services are supported by
>> >> UPnP device in advance of getting UPnP device description.
>> >>
>>
>> While this type of API usage is technically possible it would be a less than
>> ideal pattern for web developers to use.
>>
>> Why? When we share a service with a web page that has not demonstrated
>> any prior awareness or interest in that service's corresponding type then
>> there is a good possibility that the web page does not know or does not need
>> to know how to interact with it if/when it received a service object of that
>> type.
>>
>> Calling getNetworkServices twice as you propose above - initially to
>> determine the services running on a device and then calling it again with a list
>> of all service types discovered from the first call - introduces this exact
>> problem. The argument is "I don't know exactly what services I want or will
>> receive but I just want them all for the sake of having them all". This does not
>> fulfil the key requirements of this API: being able to interact with all services
>> returned to a web page.
>>
>> Perhaps we could discuss a specific use case or scenario where a pattern of
>> calling getNetworkServices twice as above would be more useful than calling
>> getNetworkServices once against a list of service types that are well-known
>> to the requesting web page and thus are presumably handleable by that web
>> page should they be returned from that call?
>>
> The pattern of calling getNetworkServices twice would typically be useful in cases where a service type is common to multiple device types, and the web app is only interested in using it in the context of a specific device type and not others. (Giuseppe also pointed this use case out in [1].)
>
> I can give a concrete example.

Thank you Cathy. I have been requesting a good practical example of
the exact problem since this issue was raised.

>
> The definition of the UPnP MediaServer device type consists of a mandatory ContentDirectory service and an optional ConnectionManager service. The definition of the UPnP MediaRenderer device type consists of the mandatory AVTransport and RenderingControl services, and an optional ConnectionManager service.
>
> Let's say a user has a MediaServer device that implements both the ContentDirectory and ConnectionManager services, and a MediaRenderer device that implements all three services - AVTransport, RenderingControl and ConnectionManager services. He starts a web app that would discover locally connected MediaRenderer devices and stream content to it/them.
>
> If the web app can only do searches by UPnP service types, it would start by searching for the AVTransport and RenderingControl service types. The UA would ask the user to grant the web app access to the MediaRenderer device (where internally only the AVTransport and RenderingControl services are in scope of the permission request). After the user says yes, the web app would receive the two NetworkService objects corresponding to the AVTransport and RenderingControl services. Upon inspecting the config attribute of either NetworkService object, it would find out that the device also implements the ConnectionManager service. In order to take advantage of that service, the web app would have to initiate another search, this time for the AVTransport, RenderingControl and ConnectionManager service types*, in order to get the user's permission to use the all three services of the device. The UA would ask the user again to grant the web app access to the MediaRenderer device (where this time all three services are in scope). This duplicate prompt could be confusing for the user.
>
> * Slightly off-topic: it's unclear to me whether the second search should be only for ConnectionManager service or all three services. The spec says that
> [[There is no implied persistence to networked service sharing provided to a web page. It MUST NOT be possible to access a networked service previously granted to a web page without user authorization in all of the following cases:
>
>     If the current script is reloaded at any point in the same or different window.
>     if the current script reinvokes the getNetworkServices() method at any point in its execution.
>     If the user navigates forward or back in their history to reload the current page.
>     If a script is running in a different origin.]]
> To me, that means that the second invocation needs to include all three services. Either way, the second search would result in the UA asking the user again to grant the web app access to the MediaRenderer device.

If this prose is not clear then it needs to be cleaned up. The
intention with this is that services should not be exposed to users
unless those particular services are authorized by the user for the
current origin within the current browsing context.

The contentious point may be 'If the current script reinvokes the
getNetworkServices() method at any point in its execution'. That
shouldn't mean previously authorized services for the current page
should be lost to the web page when subsequent calls are made to the
API. In your example you shouldn't have to call all 3 services in the
second call since two of those services were already authorized and
shared in the first call.

But multiple calls to getNetworkServices() is clearly not an ideal
strategy if users need to opt-in to share services on each request
(i.e. it interrupts a user's workflow twice instead of once). We
should explore a way to fulfil this use case in a single call to the
API...

>
> While the web app could have started the search with all three service types, it would not be desirable either. Such a search would result in the UA prompting the user to grant the web app access to both the MediaRenderer device (to use all three services) and the MediaServer device (to use the ConnectionManager service). The user might question why the web app would try to access his MediaServer (and for many users, access to the MediaServer means access to their media library) and might call foul play on the web app.
>
> This issue would not have occurred if the web app was able to issue a search by device type. By searching for the MediaRenderer device type, the UA would prompt the user once to grant the web app access to the MediaRenderer device (to use all of its services), and the web app would receive information of all services to perform its function.
>
> This is a long-winded way to say, once again, that searching by device type has its uses and should not be dismissed so quickly.

In light of the motivating use case being presented here I can agree
with this sentiment.

The current specification provides no guarantee that all service types
requested will be from the same device and in the example provided (in
the second request you detail above) both the MediaRenderer and
MediaServer will match on the ConnectionManager service type when
really you wanted only want the ConnectionManager service belonging to
the same device as has been previously shared.

I understood the original intention of this use case to be as follows:
"I want a device (or plurality of devices) that MUST support service
type A + B and MAY support service type C." There is no way to do that
currently in our spec and doing that over multiple calls to
getNetworkServices() is tricky.

But actually, in light of this use case what we actually need is a
selection of services belonging to one 'device' (be that a top-level
device or sub-device). So I want to explore grouping here as a means
to fulfil this use case.

My app must have services A + B and optionally C to function at all.
Here is the syntax we could introduce to accomplish this:

getNetworkServices(['a; b; c', 'a; b']);

this means devices are matched and presented to the user if services
they provide match to the following provided rule:

(a AND b AND c) OR (a AND b)

This meets the needs of the provided use case without needing to
expose top-level UPnP devices directly. This means:

a.) we don't need to expose services belonging to devices that have
not been requested from the web page. i.e. the data sharing
minimization currently provided by the spec remains in place.
b.) two devices implementing a subset of identical services can be
considered equivalent regardless of their associated device type. i.e.
If a web page needs a device that supports both A and B then any
device that meets that criteria can be shared with the web page
equally.

There are a number of other examples we could then use here:

getNetworkServices(['a;b;c', 'd' ]) == (a AND b AND c) OR d
getNetworkServices(['a', 'b', 'c']) == a OR b OR c

With the introduction of AND grouping logic (semi-colon separation
within requested service type tokens) to compliment the already
existing OR logic (provided when supplying an array of services in the
spec) it seems we can cover the provided use case, maintain suitable
data sharing minimization to web pages and do all that in a single
call to getNetworkServices() instead of having to track devices across
multiple API calls.

We could also add this to the spec without too many changes since we
get to keep the services-first sharing concept intact. This is
important because it is the normalisation point we use in the spec
across all network service discovery protocols.

Best regards,

Rich

>
> [1] http://lists.w3.org/Archives/Public/public-device-apis/2013Oct/0097.html
>

Received on Wednesday, 23 October 2013 23:57:18 UTC