Copyright © 2006-2013 Quantoa LLC.
All rights reserved.
A while back Andy Rubin stated that "A lot of guys have private APIs. We don't." After spending several days dealing with changes in Android 4.2 (a.k.a. Jelly Bean MR1), this is not the case for some Android functionality today, and hasn't been for a while.
There is a policy direction that the Google's Android team is continuing to move in that seems broken... by design. Specifically, they are making decisions that limit or remove functionality available to developers often based on the premise of protecting users. The problem is that they are doing this for functionality that has legitimate and often pre-existing use cases. I'm all for protecting users, and where there is functionality that a malicious developer could use that would harm users, action needs to be taken to provide protection. And Google has... unfortunately, they've taken the wrong action in that they are removing functionality rather than providing a more transparent means for developers to declare the need the functionality and allowing users to make an informed decision.
I'm not proposing that Google allow apps do whatever they want without any safeguards or disclosure. Android keeps apps sandboxed and limits their functionality using a permissions-based security model. This is a good thing and what is being proposed is simply using this capability more and the current policy direction less. So rather than say 'no, you can't do that' why not instead say 'we think this is a potentially dangerous function that you can only access by explicitly declaring a permission in order to use it'. Feel free to classify said permission as dangerous and warn users as has been done with other permissions where this was warranted.
Otherwise, the usefulness of the Android platform is reduced every time Google says 'you can't do that' or worse decides that 'your app can't do that but ours can'. The short term harm is that it breaks apps and limits functionality available to users. The long term harm is that the lack of vision will limit what kinds of apps can and will be built. Sure, developers could provide the capability provided power users have rooted and/or installed a 3rd party ROM on their devices but given the relatively small number of users who will do this, most developers are unlikely to make the effort to support that scenario.
There are a number of apps in the the Google Play app store that allow users to toggle functionality on and off. (Full disclosure: one of them is mine) Developers wrote these because they wanted to provide a faster means of turning things on and off, or even make changes to settings, than what is often buried a couple of levels down in the settings screens. Some of these require utilizing publicly available system calls, but because there isn't an explicit API to provide the functionality in question they are categorized as hacks. Two examples are toggling the cellular radio and airplane mode states on and off. Users seem to like this functionality. Apparently so does Google as 4.2 now includes a Quick Settings menu. However, at the same time they are removing developers ability to provide these and other types of apps that require this functionality. As of 4.2, only Google is allowed to turn airplane mode on and off... so there's not even an argument to be made that this API change was made to protect users: they just don't want 3rd party apps doing so. An earlier decision was made to remove the ability of developers to turn the cellular radio on and off. Using the above as examples, why not just add android.permission.MODIFY_CELLULAR_RADIO_STATE and android.permission.MODIFY_AIRPLANE_MODE_STATE permissions and everyone is happy?
Another example with far broader impact is the policy to require that apps taking pictures need to display a preview image to the user. In general, this is a good idea... except when it isn't. Previously, it was possible to work around that policy for apps that needed it but preliminary testing with 4.2 seems to indicate that if it's not now impossible to do, it probably will be in a future Android release. Using the toggle example above, many of these apps provide a feature to allow users to use their camera LED flash for use as a flashlight. Unfortunately, there is no API that allows an app to just turn the flash on or off so the solution has been to tell the system you are a camera app and pretend to take pictures when really all you're doing is enabling the camera so that you can turn the LED on and off. There's no sneakiness involved with this: you declare a permission of android.permission.CAMERA so the system will let the app do what it needs and users will know what the app is doing. Ideally, there should be an API and related permission android.permission.MODIFY_CAMERA_LED_STATE which would allow these types of apps to eliminate the camera permission entirely and go about their business in a more straightforward manner. Also, most of these toggle apps run as a service and are either activated via widgets on the home screen or as buttons on the notification menu. So even if it made sense to have a preview image, which it doesn't in this case, how exactly are they supposed to display it?
OK, so enough about apps that turn things on and off. After all, that's just one use case and one that Google is (sort of) filling as of 4.2. Besides, it could be argued that all of these apps are at least sidestepping of not outright abusing existing API's. Fair point... but there are other use cases that Google isn't filling but is also moving in the direction of disallowing related to just the camera preview policy: apps that run as services or parts of apps that run in the background (and therefore have no UI) either by design or necessity. Why not have a android.permission.TAKES_PICTURES_WITHOUT_USER_INTERACTION permission and stop this insanity?
An example use case would be a security app that when triggered starts taking pictures and uploading to a server to assist the user in their attempt to recover a stolen device. If the phone's been stolen and the thief sees pictures being taken, how long do you think this app will remain running? Or how about a photo a day style time lapse photo app where the user wants the app to run in the background so that they can continue to use their device normally while the app takes periodic pictures. Finally, I recall a use case presented by another app developer had a photo processing app that would display multiple preview images... but not the raw images, rather only post-processed images as it was an effects app. There you have three quick examples of cases where apps using the camera have good reason not to display a preview image as Android policy requires. Sure, the capability not to do so could be misused. How is this any different than apps that have permissions for access to the internet as well as the users email/calendar/etc. that is quietly sending this data back to a server without the users knowledge or consent? Obviously, this isn't just speculation as it has happened before repeatedly and been widely reported. Bad behavior will happen regardless of the limitations imposed on above-board developers.
The Nexus 7 that provides a good example of how and why these hacks begin to be used. The Nexus 7 includes a front facing camera, users know this and wonder why none of their existing 3rd party apps can use it, developers see a way to provide the functionality and do so. Obviously, Google's goal in including the camera was to allow Nexus 7 users to participate in Google+ hangouts while omitting a higher quality, higher cost rear facing camera which is fine if that's all users wanted to use it for. If a developer follows the rules, their app sees no camera. If the developer follows the rules and list the app as requiring a camera, Nexus 7 owners won't even see the app listed in the Play store. By implementing what is effectively a hack and not listing a camera as required and ignoring the recommended method of determining if a device has a camera or not, users will see your app in the Play store and be able to use it in your app. But for how long? Most developers are likely hoping that Google provides the camera functionality in a more straightforward manner in the future and would be fine changing their app to provide the functionality in a cleaner manner. But what if Google instead decides that no, this will not be allowed for 3rd party apps and removes the capability in the future? I can't think of a single reason why Google would want to remove this functionality... but then again, I can't think of a single reason why they've eliminated the previously discussed functionality either.
When all is said and done, it's very easy to identify when one of these broken policy decisions has happened: just watch some of the Google Developers hangouts and listen for when a Google employee says that developers are either not allowed to do something or are forced to do something in a specific way that that limits their app in order to 'protect users' (not the only reason given, but seems to be a popular one) even though there is a legitimate use case. Please stop right there and rethink the solution, Google. A better approach would be to restrict the needed functionality to apps that explicitly declare the need for it and provide an API to do it properly. This would be trivial to do as most of the scenarios involve already existing functionality.
I'll close with the full quote from the Andy Rubin interview linked above that does a fine job of making an argument in support of what is being requested in this post in his own words: "We have an SDK we give to developers. and when we write our Gmail app, we use the same SDK. A lot of guys have private APIs. We don’t. That’s on policy and on technology. If there’s a secret API to hook into billing system we open up that billing system to third parties. If there’s a secret API to allow application multitasking, we open it up. There are no secret APIs. That is important to highlight for Android sake. Open is open and we live by our own implementations."
Copyright © 2006-2013 Quantoa LLC.
All rights reserved.