App Widgets as Wearable UIs
Since I am attending Wearables DevCon here in scenic Burlingame (no, really, the walk along the bay is quite nice), this seemed to be a good time for me to grouse about developing apps for wearables.
Wearable devices — particularly those that run Android — are not that hard to adapt an Android app to. You have to deal with different screen sizes, be more judicious about your gestures, worry all the more about power consumption, and so on. But, at the end of the day, it’s still an Android app.
Where things start to get messy is with wearable accessories, where your app does not run on the wearable itself, but instead runs on a tethered phone or tablet. You use some manufacturer-supplied API to render a GUI and respond to touch input.
The reason why this is messy is two-fold:
The people who design those manufacturer-supplied APIs do not necessarily think about what is going to garner the most adoption of those APIs
Each manufacturer rolls their own, meaning that developers have several such APIs to mess with, if not today, then tomorrow
Now, in some cases, the wearable really does need a distinctive API, because the UI you would want to create is itself distinctive. Augmented spectacles, like Google Glass, would be one such example. However, writing an app for one wrist wearable should not be radically different than writing an app for another wrist wearable, at least for basic apps.
What makes this all the more grating is that wearable manufacturers have a perfectly good API already in Android that they could be using: app widgets.
A home screen app widget has three characteristics in common with wrist wearables UIs:
The UI is small
The UI does not support much in the way of touch events (taps, plus swipes on select widgets like
The information shown there is stuff that is supposed to be for ready access at any point
App widgets have been around since 2009. There are tens of thousands of Android apps out on the Play Store with app widgets, and many (if not most) of them would be right at home as an app on a wearable.
For a wearable accessory, the mediation app supplied by the manufacturer that runs on the phone or tablet would serve as an
AppWidgetHost. Rather than render the app widgets on the phone or tablet screen, though, it would render them to a
Canvas, sending the bitmap over to the wearable for display. Touch events would be handled either by forwarding them along to the
View hierarchy of the app widget (e.g., for swipes on a
ListView) or by triggering the
PendingIntent associated with a tap. From the standpoint of the app widget developer, everything would look just as if the device’s home screen were the one hosting the app widget.
And that’s the point.
Every line of code needed custom for a wearable is a barrier to adoption. Developers are not necessarily going to run and jump on every wearable that comes down the pike. By using an existing framework, one that is (reasonably) well-documented and in use elsewhere, wearables can get more app support more quickly with less proprietary stuff.
Now, the app widget API was not designed with wearables in mind, in all likelihood. There may be things that the wearable can do that go beyond the app widget. How much of that could be shoehorned into an extended version of the app widget framework (e.g.,
WearableWidgetProvider subclass of
AppWidgetProvider supporting additional broadcasts and methods) would depend up on the wearable. And offering a complete proprietary API as an alternative to using app widgets, for developers who want to deeply integrate with the wearable, is similarly reasonable.
Wearables are still a fringe technology in 2014, compared to their phone and tablet brethren. If wearable manufacturers want a lot of apps quickly, using app widgets would seem to be the route to go. The wearable needs to adapt to the developers, not the other way around. Or, as the saying goes, “If the mountain won’t come to Muhammad then Muhammad must go to the mountain.”
—Mar 06, 2014
The Busy Coder's Guide to Android Development Version 5.6 Released
Subscribers now have access to the latest release of The Busy Coder’s Guide to Android Development, known as Version 5.6, in all formats. Just log into your Warescription page and download away, or set up an account and subscribe!
This is a bit of a lateral release.
Since I am not going to be attempting to cover every different wrist wearable device on the market, and since my SONY SmartWatch coverage was for the first generation device (and its API), I elected to replace the SmartWatch chapter with a chapter on general issues involving wrist wearable devices.
I also needed to update my own Qualcomm MDP device and the Trepn profiler. That, in turn, led me to agree to a new Trepn license agreement, and at this point I am no longer comfortable with covering Trepn in the book, due to the agreement terms. I replaced the Trepn chapter with one discussing typical problem spots with power usage and, in some cases, how to try to reduce the power consumed by your app.
Beyond this, there’s a smattering of updates to:
the Gradle for Android coverage, particularly conditional dependencies for build types and product flavors
the material on custom permissions, integrating what I blogged about a week ago in terms of issues with other apps defining your permissions ahead of you
the chapter on external display support
Plus, there is a bumper crop of errata fixes, courtesy of a few contributors who went above and beyond the norm for bug reports. :-)
I apologize that this update wasn’t all I had planned on, but I ran into some challenges that stole away more time than I expected.
Version 5.7 should be out in ~4 weeks. Of note, I hope to add coverage of Google Cast to the book, in particular how to write apps that can deliver content to a Chromecast or to more traditional external displays (HDMI, MHL, SlimPort, Miracast, etc.). That, in turn, will require additional material on
MediaRouter and its associated action bar support.
As always, if you have questions or concerns with your update, contact me.
—Feb 18, 2014
Webinars: NFC Basics
Another webinar topic has been added to the roster, this one on the basics of using NFC, covering things like reading and writing tags, pushing data and files to other devices, and so on.
As with the other webinars, this one is scheduled for four different dates and times, to try to provide you with enough options to find one that you can attend.
Subscribers can visit their Warescription page to get the discount codes for these and the other scheduled webinars, though they are also open to the public.
If you have any questions regarding the webinars, let me know.
—Feb 17, 2014
Vulnerabilities with Custom Permissions
Mark Carter posted a comment on one of my StackOverflow answers. Based on his analysis, my own, and discussion of this with “Justin Case”, an Android security researcher, it appears that there’s been a limitation to how custom permissions work in Android, one that can leave apps that use them vulnerable to attack.
Specifically, it appears that Android works on a “first one in wins” strategy, and developers need to be aware of what this means.
If two apps define the same custom permission (via the
<permission> element in the manifest, with the same
android:name value), whichever app is installed first is the one whose definition is used.
On the one hand, this is not terribly surprising. “First one in wins” is a common approach to handling duplicate definitions of things.
However, unlike duplicate package names or duplicate
ContentProvider authorities — where the installation fails due to the duplicate — installation proceeeds in this case. That too is not terribly surprising, as this behavior can be rather useful in cases where the installation order of apps is not known in advance.
However, it does open up significant risks. An attacker can gain access to a defender’s secured components simply by:
- Declaring the same custom permission,
- Requesting that custom permission via
- Being installed first
Android never informs the user that the attacker requested this permission, and so the user is oblivious to the fact that the attacker has access to their data in the defender’s app (to the extent offered via this permission).
Worse, the attacker can decide to have its edition of the custom permission have a
android:protectionLevel, and this supersedes any
android:protectionLevel that may be established by the defender. The attacker not only can obtain this permission silently, but it does not need to have the matching signing key.
The Mea Culpa
I should have realized this a couple of years ago, at least. I did some research for determining how apps employing custom permissions can support arbitary installation order. My solution is to define the same permission in both apps, and that is precisely the scenario that an attacker would use. I was focused on enabling communications between apps and failed to do broader research about ensuring that there were no related vulnerabilities. I am deeply sorry that I failed to do this back then.
This issue is also apparently known about in Android security circles. The Android Security team has stated to methat this is “working as intended”.
I am blogging about it here as I suspect that it is not widely known among Android developers, and it needs to be better known. I have already notified the developers of one “brand name” Android app about the issue (since I had proved that they were vulnerable as part of my testing), and I am sure that there are countless others who use custom permissions and are unaware of the problem.
You can read a more in-depth write-up of my analysis of this issue.
That paper is in the repository of a new CWAC library, CWAC-Security, where I have a
PermissionUtils class that can help you detect, on first run of your app, if some other app has already defined one of your custom permissions. You can then take steps if needed (e.g., the app is not on some whitelist), to notify the user about the other apps and perhaps to record this information yourself to perhaps identify attackers.
I have also filed an enhancement request to try to improve Android’s handling of custom permissions. However,
b.android.com issues can rapidly become a cesspool. Please do not post “me too!” or “Google is teh evil!” comments on the issue, as those will merely make it less likely that this will be addressed. If you have additional analysis, thoughts on implementations, or the like, those would be fine comments, if you wanted.
If you find flaws in my analysis, or if you find flaws (or have enhancement suggestions) related to CWAC-Security, feel free to file an issue. If you find additional vulnerabilities in this area, contact the Android Security team, or contact me if you prefer. If you have general development questions in this area, post to StackOverflow in the
android tag or use your favorite Android developer support site.
I would once again like to thank Mark Carter and “Justin Case” for their assistance with this issue.
—Feb 12, 2014
Fighting Closed with Open
An article that is making the rounds is Ars Technica’s “Neither Microsoft, Nokia, nor anyone else should fork Android. It’s unforkable.”. The author (Peter Bright) early on states:
Google has worked to make Android functionally unforkable, with no practical way to simultaneously fork the platform and take advantage of its related strengths: abundant developers, and abundant applications.
There is a practical solution, one that can beat Google at its own closed-source game. However, it requires business executives who aren’t control freaks, which unfortunately makes it improbable.
Mr. Bright’s argument is that Android is only partly open source. Google Play Services is closed source, and Google certainly pushes this set of APIs. Only licensees have legitimate access to Play Services, and apps that require Play Services can therefore only run on licensed devices.
His conclusion, therefore, is:
The only way to solve the application issue is to be not merely an AOSP platform but a [Play Services] platform.
The only way to solve the application issue is to get developers to become less dependent on Play Services. And, IMHO, the only viable way to do that is for other vendors to collaborate and build up a competing suite of open APIs, ones that can plug into Play Services or into alternative implementations.
Mr. Bright posits that creating a replacement for Play Services is a lot of work, and he is correct. However, there are already replacements for much of it, whether in the open source arena (e.g., Open Street Map) or in the commercial realm (e.g., Amazon’s various replacements for use on the Kindle Fire series).
The problem isn’t a lack of alternatives. It’s a lack of a compelling reason for many developers to bother with those alternatives.
Google has done a reasonable job of ticking off the two major boxes for considering an API:
Making it fairly easy to adopt (e.g., from educational, technical, licensing, and operational standpoints)
Delivering a nice-sized audience for the results
Having an umbrella API, that plugs into Play Services or alternatives, can only expand the audience. Hence, if it becomes easy to adopt, sensible developers will certainly consider it.
The problem is that vendors like Amazon are focused on trying to be Google and have their own lock-in. Some percentage of Android developers will adopt such firms’ proprietary APIs, either for dedicated apps for such firms’ devices, or slogging through multiple implementations. But a lot of developers will not bother, just as a lot of developers do not bother with the Amazon AppStore for Android — and I’ve tried for years to get developers to think about distribution beyond the Play Store. If it isn’t easy, and it isn’t huge, it isn’t on most developers’ radar.
There’s nothing stopping some consortium, or a nicely-backed open source initiative, from taking a page from the same playbook, and aiming to give Android developers a reason to switch to a higher API that offers a larger audience. This would spread the effort amongst multiple interested parties, from major vendors (Amazon) and major ROM modders (Cyanogen, Inc.) to the countless firms who offer something in the Play Services sphere and would relish the opportunity to plug into a common API and not get trampled by all the elephants.
This still will not be easy. And, it would eliminate these vendors’ ability to achieve lock-in in the same areas that Play Services covers. Hence, I have no idea if there is a critical mass of players who would take on such a task. And it will take patience and time, once something is ready, to educate and convince developers to migrate to such a solution. But an open set of APIs would weaken Google’s lock-in ability with Play Services, and I would think that this might be an objective of some of these firms.
If you want to fight the closed Play Services, building fragmented closed alternatives is an unlikely solution. Instead, fight closed with open.
—Feb 08, 2014