W3C home > Mailing lists > Public > public-device-apis@w3.org > June 2010

Re: API patterns and requirements

From: <Frederick.Hirsch@nokia.com>
Date: Fri, 18 Jun 2010 17:35:58 +0200
To: <rich.tibbett@gmail.com>
CC: <Frederick.Hirsch@nokia.com>, <wmaslowski@opera.com>, <public-device-apis@w3.org>
Message-ID: <3062C9A5-EFEC-4F03-B1A8-3619D101C6D2@nokia.com>
I think this demonstrates the value of an access control mechanism such as the Policy Framework, where each navigator.system.GET('item') triggers a policy decision based on policy, avoiding needless user interaction on each call while allowing the granularity as specified by policy.

regards, Frederick

Frederick Hirsch
Nokia



On Jun 18, 2010, at 8:40 AM, ext Rich Tibbett wrote:

2010/6/18 Wojciech Masłowski <wmaslowski@opera.com<mailto:wmaslowski@opera.com>>
W dniu 2010-06-17 16:23, Rich Tibbett pisze:
I've been thinking about the general interface patterns that we are using in the some of the APIs, particularly with a focus on Contacts and System-Info.

On the one hand there is a requirement that API calls be asynchronous. On the other hand, in order to ensure a reasonable user experience (i.e. don't bombard the user with more than one permission request at a time) I think we should include a requirement for serial access to each API (or collectively, all APIs) - that no more than one API call should be executable concurrently. I'd like to explore if this is a reasonable assumption for e.g. Contacts and whether any changes to the pattern used may be required for this.

[original code snipped]
I don't really think that mandating that only one call is going to help with a problem of annoying user with security requests in any way.

Security requests may be unavoidable where we don't have any pre-defined trust relationships. This proposal does not remove the need for security requests but only ensures that a web app cannot bombard the user with those security requests.

Consider the following use case: web app wants to get power and network info. With your suggested solution it would look like that.

navigator.system.request.onsuccess = function() {
    doSomethingWithBatteries(navigator.system.request.result);
    navigator.system.request.onsuccess = function() {
        doSomethingWithNetworks(navigator.system.request.result);
    };
    navigator.system.get('Network'); // triggers 2nd permission request
};
navigator.system.request.onerror = function() {
    // even if we don't get access to Power we want to try to get Network info

    navigator.system.request.onsuccess = function() {
        doSomethingWithNetworks(navigator.system.request.result);
    };
    navigator.system.get('Network'); // triggers 2nd permission request
};
navigator.system.get('Power'); // triggers 1st permission request

If we allow concurrent request the code looks like this

navigator.system.get('Power', doSomethingWithBatteries ); // triggers 1st permission request
navigator.system.get('Network' doSomethingWithNetworks); // triggers 2nd permission request

In both examples the user will be asked for permission twice. The first one is much more complicated.

It looks a little more complex but the application is presenting a clearer interaction flow in the first example than in the second. Developers actually have to design their web application from a user interaction perspective in the first snippet: each nested API call probably requires a subsequent security request and the pattern requires the developer to plan that appropriately (and limit the number of permission requests being called). So I actually still prefer the first example. The second example could also generate race conditions if we're not careful (e.g. if the web app requires that 'Power' completes before examining 'Network' but 'Network' returns first).

Using the second example, if a web application executes 1000 API calls up front would the user will be presented with 1000 security dialogs? The proposal would mitigate such malicious usage of Device APIs.


Additionally with your solution we have to specify what happens in this case :

navigator.system.request.onsuccess = fun1
navigator.system.get('Network');
navigator.system.request.onsuccess = fun2

will fun1 be called or fun2?


fun2 would be called. Just like any other ECMAScript variable, navigator.system.request.onsuccess has been overwritten with a new value in the snippet above.

This pattern provides two additional benefits over the current APIs:

1. only one async method (e.g. in the Contacts API this includes find(), save() and remove()) can be requested at any one time (i.e. serial access only).
I don't see how mandating only one async call gives advantage over possibility of many concurrent calls. In both cases developer will spam user with permission requests if he requests data too often.

I see the following advantages of serializing access to API calls.

- it throttles the user interaction (e.g. security/permissions opt-in) required with the app. A malicious app cannot send 10000 requests to a Device API.
- Developers are required to plan their applications intelligently around a clear Device API access flow.
- Race conditions are removed (e.g. performing a 'save contact process' while performing a 'find contacts process' could result in such a race condition and inconsistent responses).
- User interaction is less confusing - only one permission request at a time for the user to authorize.

...FWIW, I do question the SysInfo API model: if a user is required to authorize each SysInfo API call seperately it would probably make more sense for a web app to be able to request a bunch of System Information in a single API call (and hence a single permission request). The current SysInfo API does not have the ability to provide that yet :-(


- Richard

[1] http://www.w3.org/TR/IndexedDB/

[2] http://dev.w3.org/html5/spec/Overview.html#file-upload-state

[3] http://dev.w3.org/2009/dap/contacts/contacts_picker.png




Received on Friday, 18 June 2010 15:37:28 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Wednesday, 9 May 2012 00:14:10 GMT