- From: Mounir Lamouri <mounir@lamouri.fr>
- Date: Thu, 24 Jan 2013 20:57:05 +0000
- To: public-device-apis@w3.org
Hi, There has been a lot of discussions lately regarding the Network Information API. I took some time today to think about what has been said and how it could be solved. The first part of the API is the 'bandwidth' attribute. The intent of the specification with this attribute is to have a clear way to check if a client has enough speed to do a certain type of actions. A few use cases would be: I want to provide high resolution images by default if the client has a bandwidth of at least X kb/s; or, I want to automatically fetch email attachments if the client has at least X kb/s (to not kill its connection); even, I will not try to sync emails if the client has less than X kb/s of bandwidth (think of fetching emails when you are on Edge). It is up to the user agent to decide how the bandwidth is computed. It might indeed be hard to have a precise bandwidth for each domain the client is accessing but this is actually not the intent of the specification. The user agent should provide something that has enough precision to be usable (not 1 Mb/s precision for example) but it doesn't need to be very precise (like 1 kb/s precision). The spirit of the specification is that the vendors will come up with more or less sophisticated implementations. For example, the experimental implementation in Firefox for Android is simplistic and has space for improvements. We currently have hard-coded values that are returned depending on the connection type. There are different ways to improve that: we can randomize the returned value, we can have steps (there is no need to differentiate 22kb/s and 28kb/s for example). A more complex way to improve that would be to estimate the bandwidth while Firefox is running (on a given Mozilla server for example) and use it as a value for all websites. Actually, that kind of information could be used by a mobile browser for various reasons. None of those improvements would fully follow the specifications because the estimation wouldn't be compared to the current document but to an arbitrary server. However, those improvements are not complex and would make the implementation closer to the ideal one without having to change the specification nor the web pages. The only alternative I've been able to come up with is to change the bandwidth attribute to an enum. The enum might look like it would ease the implementation complexity but this is not really the case. In addition, it would make the attribute's behaviour hard to specify so hard to understand for the authors. Indeed, we could have something like { "slow", "fast" } or { "very-slow", "slow", "fast", "very-fast" } but "slow" or "fast" have a relative meaning. The speed of a connection depends on what you want to do, the type of connection you have and the country you are in, etc. It is very hard for a user agent to know if a website will consider a given connection speed as fast or slow. In addition, using an enum wouldn't really ease the implementation, it will just be less visible that the implementation is simplistic: it is very simple to see that an implementation is returning pre-defined values for the bandwidth as a double but it is harder to see that if the bandwidth is an enum. In my opinion, the only real alternative to the current bandwidth specification is to simply remove it from the specification because it is proven unrealistic and not implementable. Although that has often been said, no actual implementer came here to give its feedback. Therefore, I think the attribute should stay as-is until an implementer formally express its incapacity to implement it - taking in consideration what has been said above. Regarding the second attribute, 'metered', I think the intent of the specification has often been misunderstood. The attribute should return true if the connection is sensitive to heavy data usage. Again, that doesn't mean that any connection with a cap should be marked as metered. If the cap is at 100GB, there is no point in marking it metered as long as the user is far from the 100GB. The use cases for this attribute are pretty much obvious and very useful in a mobile word. It can be summarized as preventing [large] downloads while using a metered connection. Typical examples would be app updates, email fetching, synchronisation frequency... As bandwidth, the metered attribute has been said to be not implementable. Currently, the Firefox for Android implementation simply mark mobile data connections as metered and others as not metered. This is indeed a poor implementation. However, since this specification has been written, Android came with an API to get that information [1], such as Windows 8 [2]. This make this attribute easily implementable on those platforms and is a proof that it is actually implementable. In addition, as for bandwidth, even if the first implementations are not perfect, metered can always be improved. An implementation like the one in Firefox for Android is always better than nothing and it is possible to improve it with the Android API now. The implementation could have been/be improved also by an option in the user interface to mark the current connection as metered. Maybe even having a first run experience that asked the user if his/her mobile connection is metered. There were two major ideas to improve this behaviour of the metered attribute. The first one is to make it more granular: how bad is it metered? or why is it metered? As much as I agree that could be an interesting idea, in practice, it is likely too early to go that far. I think introducing another attribute later like "meteringType" if needed would be a better idea. The other idea was to make metered a tri-state: { true, false, unknown }. I think that could be interesting but I see two major culprits because of the fact that such a tri-state would require 'true' or 'false' to be always exact and 'unknown' being the fallback value (otherwise, unknown would be useless): - you can't rely on implementations to have something not perfect and improve over time because strictly following the specification, most of them would have to return 'unknown' for the moment; - using an API like the one in Android that only returns true/false would be a violation from the specification because it is certain that Android doesn't know for sure and fallback to a value or an heuristic. I also think that having an 'unknown' value wouldn't help web developers because they will not be able to know what to do if the returned value is 'unknown'. Likely, they will follow the true or false path. Relying on the user agent to do the right thing seems better for everybody I believe. I would be really interested in feedback. If you are implementing or tried to implement this specification, I would love to hear about your experience. [1] https://developer.android.com/reference/android/net/ConnectivityManager.html#isActiveNetworkMetered%28%29 [2] http://msdn.microsoft.com/en-us/library/windows/apps/hh465399.aspx#adapt Thank you for reading. -- Mounir
Received on Thursday, 24 January 2013 20:57:34 UTC