PSA: WebView, Chrome Accept Revoked SSL Certificates

TL;DR: If your app uses WebView (whether the new 4.4 Chromium-flavored one or the classic one), and it loads a Web page that presents a revoked SSL certificate (whether due to a server configuration error, a Martian-in-the-middle attack, or whatever), WebView will load and show the page anyway, with no warning to the user.

This came up due to due to this issue filed a day ago on the Android issue tracker, pointing out that the Chrome browser on Android blows past revoked SSL certificates as well. A lot of SSL certificates are being revoked now as a result of heartbleed, and the person filing the issue felt that it was important that Chrome do what some other Android browsers do, like Firefox, and alert the user to the potential security issue.

Google, both in that issue and the original issue filed against Chrome, disagrees.

I do not know of an in-WebView way of addressing this; if I hear of one, I will blog about it.

However, based on some light testing, HttpURLConnection and OkHttp do seem to pay attention to the revocation status of the SSL certificate. Leastways, if I load this Web page in Chrome or a WebView, the page comes up, but if I try to download the page contents using HttpURLConnection or OkHttp, I get an empty response. I don’t see an SSLHandshakeException as I would have expected, though, which worries me a fair bit.

Note that I have not tested HttpClient on Android and so do not know if it will or will not pay attention to an SSL certificate’s revocation status.

If you have any additional insights on this issue, feel free to contact me.

Apr 17, 2014


Really Blank Activity (Or, Why AppCompat Is Shoved Down Your Throat)

It seems like this question or one just like it shows up almost every day on StackOverflow nowadays. Variations on the theme include:

  • Why do I get a new appcompat_v7 directory in my Eclipse workspace every time I create a new project or activity?

  • Why is it adding appcompat_v7 to my project anyway?

  • How do I get rid of this extra stuff that’s getting generated in my project?

  • HOW DO I MAKE IT STOP???!?

The issue is that the activity templates in Eclipse’s ADT — or at least BlankActivity, as I have not bothered with the others very recently — are set up to have you use ActionBarActivity and appcompat_v7. Technically, creating a project via the new-project wizard does not add appcompat_v7, but creating an activity via the new-activity wizard does. This includes checking the “create activity” checkbox in the new-project wizard, which effectively chains to the new-activity wizard.

There are two major solutions to this at this time, besides learning to love appcompat_v7:

  1. Stop using the ADT wizards to create activities.

  2. Install an activity template that does not use appcompat_v7.

Buried in the SDK source code repo lies documentation on creating ADT templates. Given all the development work on Android Studio, how well or for how long this template format will be honored is anyone’s guess. And, AFAICT, they didn’t actually bother documenting how to install these things (hint: you wind up with directories like extras/templates/activities in your SDK installation).

But they are a solution.

For example, Jeff Gilfelt’s template library has seven total templates, including five for activities, none of which will install appcompat_v7.

And I just tossed together a “Really Blank Activity” template. As the name suggests, the template generates an activity that is pretty darn blank, with just a simple “Hello, world” layout resource. No menu resources, no fragments, no libraries, no cruft.

With luck, a template like this one will ship with some future update to the ADT. Otherwise, you’re welcome to give mine a try.

Apr 15, 2014


The Storage Situation: Where Developers Go Astray

There is a lot of confusion regarding Android’s storage model. That confusion has only increased with Android 4.4’s changes to that storage model. There are countless StackOverflow questions and the like where they clearly do not quite grok the various pieces of Android’s storage model.

This is the final post in a five-part series covering this storage model, to help clarify what is going on. Today, we will look at how developers have exacerbated the problem with Android 4.4’s changes to removable storage.


If your app uses risky code, you must communicate those risks to users

Here, by “risky code” I mean stuff that has above-average chance of breaking across devices or in future Android versions, because the code uses techniques that are:


Let’s go back to the quote from Dianne Hackborn:

…keep in mind: until Android 4.4, the official Android platform has not supported SD cards at all except for two special cases: the old school storage layout where external storage is an SD card (which is still supported by the platform today), and a small feature added to Android 3.0 where it would scan additional SD cards and add them to the media provider and give apps read-only access to their files (which is also still supported in the platform today).

Android 4.4 is the first release of the platform that has actually allowed applications to use SD cards for storage. Any access to them prior to that was through private, unsupported APIs. We now have a quite rich API in the platform that allows applications to make use of SD cards in a supported way, in better ways than they have been able to before: they can make free use of their app-specific storage area without requiring any permissions in the app, and can access any other files on the SD card as long as they go through the file picker, again without needing any special permissions.

This is not news.

While it could be called out better in the documentation (e.g., an programming anti-patterns section, to line up with the design anti-patterns), we have been told that removable media was unsupported for quite some time. I personally have pointed this out in a variety of StackOverflow answers, of which this one is the highest-regarded (and just updated to reflect these 4.4 changes).

If you find yourself doing any of these things, you are using techniques that are undocumented, unsupported, and unreliable across devices and OS releases:

  • Examining Linux system files (e.g., /proc/mounts)

  • Running Linux system commands (e.g., mount)

  • Using reflection to get at classes and methods that are marked as @hide and therefore are not part of the Android SDK

  • Hard-coding references to Google-proprietary or AOSP apps, such as package names and ContentResolver Uri values

I am not saying that you cannot use these techniques. Quite obviously, you can. I am saying that either:

  • You should not use those techniques, but if you do…

  • …you need to warn your users that certain app features that depend upon such techniques may be unreliable across devices and OS releases

Here, by “warn” I don’t mean that you need to get the user to sign in blood somewhere that they understand the ramifications about this feature. At the same time, I don’t mean that you just keep the information to yourself.


There are plenty of possible analogies in the area of consumer product labeling and similar laws. For example, let’s think about the US Securities and Exchange Commission’s (SEC) requirements about risk disclosure:

Firms that are publicly traded need to publish certain information at the time they go public, plus periodic updates, with the SEC. One such annual filing is Form 10-K. As Wikipedia phrases it:

Although similarly named, the annual report on Form 10-K is distinct from the often glossy “annual report to shareholders,” which a company must send to its shareholders when it holds an annual meeting to elect directors (though some companies combine the annual report and the 10-K into one document). The 10-K includes information such as company history, organizational structure, executive compensation, equity, subsidiaries, and audited financial statements, among other information.

Specifically, section 1A of the 10-K is where a firm outlines “risk factors”, to disclose to potential investors known areas where there may be problems. Sometimes, those problems are purely internal, such as reliance upon innovative new engineering processes. Sometimes, the problems are external, such as pending litigation or “changes in regulatory climate” (i.e., lawmakers making laws). Generally, the risks are things that are relatively specific to the firm itself, or perhaps its market segment, rather than risks that are endemic to a region (e.g., natural disasters) or are otherwise broadly applied (e.g., zombie invasion).

For example, Google’s 10-K for the end of 2013 has 10 pages of risks just to the business, ranging from “intense competition” to “new technologies could block our ads”.

The reason for these disclosures is so that investors can be informed, to a degree, about the risks involved in investing in the firms. Tactically, this can be viewed as bad for the firm, as such disclosures can depress stock price. Strategically, these disclosures help with lawsuits and future regulation, by demonstrating that the firm is a “good citizen” and has reasonable transparency about the “known unknowns”. From the standpoint of public policy, such disclosures allow investors to be well-informed (if they read 10-K statements) or ill-informed (if they do not). The SEC is not trying to force investors to be well-informed, but is trying to ensure that investors have the opportunity to be well-informed if they so choose.


If you don’t want lawsuits, and you don’t want regulation to enforce “app labeling” on par with other consumer goods labeling (or, worse, civil or criminal penalties for failing to disclose known risk factors), you need to start documenting this stuff. To think that app developers live apart from the realities of other industries is sheer folly.

This does not have to be hard.

First, write documentation. Yes, this is boring. Yes, many users will not read it. Yes, do it anyway.

Second, when describing a feature that depends upon a risky technique, simply call it out (“NOTE: this feature, while wicked cool, relies upon some stuff that may not work across all devices and may not work in future versions of Android”).

Third, make sure that the documentation is reasonably easy to access, so that users cannot complain that they cannot find the documentation. If you want to host the documentation on your Web site, provide a “Help” overflow item in your activities that leads there.

Of course, some developers will resent my suggestion that they should be honest with their users, stating that it might depress sales of the app (or in-app purchases, or usage with resulting ad impressions, etc.). It probably will depress sales, at least in the short run.

Other developers will point out that users will still complain about lost features, even if the risk of that is pointed out. This too is true, as not all users will read the relevant bits of the documentation, let alone remember it. Using risky techniques is just that: risky. You are banking on the fact that the technique will stay working for enough devices and OS releases, so that you do well enough with the app to survive any downturn if and when the technique falls apart. That’s why I counsel against these techniques in the first place.

But, to look at it another way, you not telling your users about things that might break means that you are no better than Google. Google failed to communicate that they were planning on enforcing this removable media lockdown, and you were affected. You failed to communicate to your users that your removable media support was based on a series of assumptions, and your users were affected. Blaming Google for their behavior, while not taking responsibility for your own, is hypocritical, even if the scope is different (Google’s failure to communicate affects more people than did yours, unless your app is crazy popular).

There are other things that you can do that will help matters:

  • If you do not know if a certain technique is documented and supported, ask on StackOverflow or another developer support site.

  • If you feel that a certain capability is risky, but perhaps worth the risk, try to craft an open source library that wraps up the capability behind an as-opaque-as-possible API. The objective is to be able to allow many developers to share a single implementation, so that tweaks to overcome device differences can be made in one spot. Also, it provides a spot for trying to supply workarounds in case the capability is flat-out blocked, as it was here for removable media writing. And, an organized group of developers writing and implementing a library for an unsupported capability is incrementally more likely to be able to find out about upcoming changes in Android that might affect that capability, so you can begin planning what to do.


Overall, there is little question in my mind that the changes to removable media in Android 4.4 could have been handled better. However, this isn’t the first time that Google has elected to change Android behavior in ways that break undocumented and unsupported techniques. It’s also unlikely to be the last time that they do so. All I can do is hope that:

  • Google starts communicating these changes better (e.g., the SMS changes in 4.4 were handled fairly well in terms of advance notice and descriptions of what to expect)

  • Developers start paying closer attention to the ramifications of using undocumented and unsupported techniques, and if nothing else start informing their users about potential problems before they become actual feature regressions

The Rest of the Posts

The entire blog post series covers:

Apr 11, 2014


The Storage Situation: Where Google Went Astray

There is a lot of confusion regarding Android’s storage model. That confusion has only increased with Android 4.4’s changes to that storage model. There are countless StackOverflow questions and the like where they clearly do not quite grok the various pieces of Android’s storage model.

This is the fourth post in a five-part series covering this storage model, to help clarify what is going on. Today, we will look at why Google may have done what it did with respect to removable storage, and what it should have done (or should be doing) as part of that decision.


If your offering differs from norms, you must communicate those differences.

The norms, in this case, are expectations for what can be done with removable media.


In 1973, three interesting things occurred, among other events:

  1. Larry Page was born

  2. Sergey Brin was born

  3. IBM released a read/write floppy disk drive

The floppy disk was adopted as a primary storage medium by the wave of “microcomputers” in the 1970’s, and the world’s relationship with removable media began.

Mr. Page and Mr. Brin recovered from being born in the middle of the disco era and went on to found a little firm named Google… in 1998.

Hence, people have been using removable media for far longer than Google has been around, and far longer than many Googlers have been around.

The world’s perception of how removable media is supposed to work has been based on their collective experiences with desktop operating systems, particularly Windows. Windows is the reason why removable media standardized on FAT, then FAT32, each of which offers limited security options. Programs running on Windows can generally read and write removable media with impunity, and that same behavior has continued with other desktop operating systems when working with FAT/FAT32 removable media.

It is safe to venture that most of the billion Android device users have, at one time or another, used removable media on a desktop OS, and therefore have a perception of how removable media should work based upon those experiences.

Android 4.4 breaks those expectations, at least where third-party apps are concerned. The offering (no write access to removable media for third-party apps) differs from the norms (anything can do anything).

This is not to say that Google’s decision here is the wrong one.

The security of removable media has been atrocious throughout history, as the NSA will readily attest to. Just because we made decisions back in the 1970’s and 1980’s about how removable media gets used does not mean that we have to stick with those decisions until the end of time. Google is getting a fair bit of pressure to better lock down external storage and removable storage for privacy reasons… even if the expectations of those privacy advocates also differs from the norms of society with respect to that removable media.

Google could have made a Solomonic “half a baby for everyone” decision, with some option in Settings to toggle removable media behavior between the Android 4.4 read-only state and unfettered access. Google has been reticent to add capabilities targeted at “power users” (e.g., optional/revocable permissions), and so it is not shocking that they decided that “one size fits all” in terms of removable media behavior.

And that’s fine, except for one thing: Google has not communicated much of anything about this. When the only information from Google that users and developers alike can get on a subject come from a handful of posts on the android-platform Google Group, we have a Cool Hand Luke-style “failure to communicate”.

If removable media were a Google invention, and there were no expectations for how it should behave, and Android 4.4 was the first release of Android, this lack of communications would be unfortunate but not unreasonable. However, not only has removable media been around for ~40 years, but Android itself had different behavior for removable media since 2008.

If your offering differs from norms, you must communicate those differences.

However, just because Google is unwilling to communicate does not mean that you should be unwilling to communicate… and that’s the topic that I will explore in tomorrow conclusion to this blog post series.

The Rest of the Posts

The entire blog post series covers:

Apr 10, 2014


The Storage Situation: Removable Storage

There is a lot of confusion regarding Android’s storage model. That confusion has only increased with Android 4.4’s changes to that storage model. There are countless StackOverflow questions and the like where they clearly do not quite grok the various pieces of Android’s storage model.

This is the third post in a five-part series covering this storage model, to help clarify what is going on. Today, we will look at removable storage, and the source of an unfortunate amount of angst.

What Your Users Think “Removable Storage” Means

Many of your users will have a device that has some sort of removable media. Often times this is a micro SD card. Some tablets or docks have a full SD card slot. Plus, USB mass storage is possible via USB On-The-Go connectors (not to mention devices or docks with a full USB host port).

Your users will think that they can work with removable storage much like they can with a desktop or notebook.

Unfortunately, your users are largely mistaken, and are even more mistaken with Android 4.4+. That’s because Google’s approach towards removable storage is… odd.

What Google Thinks “Removable Storage” Means

In the beginning, as was noted yesterday, external storage was often in the form of a removable micro SD card. At that time, many developers got in the habit of thinking that external storage == removable storage.

However, as Android 3.0 and higher started rolling out en masse, developers soon started to realize two things:

  1. External storage != removable storage on most of those devices

  2. There’s nothing in the Android SDK for removable storage

Wait, Wut?

That’s right: until Android 4.4, there was no official support for removable media in Android. Quoting Dianne Hackborn:

…keep in mind: until Android 4.4, the official Android platform has not supported SD cards at all except for two special cases: the old school storage layout where external storage is an SD card (which is still supported by the platform today), and a small feature added to Android 3.0 where it would scan additional SD cards and add them to the media provider and give apps read-only access to their files (which is also still supported in the platform today).

Android 4.4 is the first release of the platform that has actually allowed applications to use SD cards for storage. Any access to them prior to that was through private, unsupported APIs. We now have a quite rich API in the platform that allows applications to make use of SD cards in a supported way, in better ways than they have been able to before: they can make free use of their app-specific storage area without requiring any permissions in the app, and can access any other files on the SD card as long as they go through the file picker, again without needing any special permissions.

But… But… But… What About All These Apps That Use Removable Media?

They fall into three buckets:

  1. Some are just relying on MediaStore indexing. So, for example, a video player can find out about videos on all available media by querying the MediaStore, and if the device manufacturer hasn’t broken the MediaStore indexing of removable media, the player will be able to play back videos on removable media.

  2. Some are apps that ship with the hardware. The hardware manufacturer knows the device and what the rules of the game are for that device. The hardware manufacturer is also far less concerned about cross-device compatibility, as their apps aren’t (usually) shipping on the Play Store. Hence, a hardware manufacturer has carte blanche to work with removable media.

  3. Some are apps written by developers who decided to go past the boundaries of the Android SDK. There are various recipes online for examining various Linux system files (and file-like substances) to determine what “mount points” exist, and from there apply some heuristics to determine what represents removable media. While reliability across devices could easily be an issue, beyond that, these techniques worked… until Android 4.4, when everything changed.

What Happened in Android 4.4: The Good News

Two things happened in the timeframe of Android 4.4 that affect removable media.

On the plus side, we gained some measure of official Android SDK support for removable media. Specifically getExternalFilesDirs() and getExternalCacheDirs() (note the plural form) will not only return directories that we can use on “real” external storage, but also will return directories that we can use on any available and supported removable media. Our apps do not need any specific permissions to use any of those directories.

Also, the Storage Access Framework gives device manufacturers some options for exposing removable media to our apps in a more controlled fashion. Quoting Jeff Sharkey:

However, apps can create/write files outside of their package-specific directories on secondary external storage devices by using the new CREATE_DOCUMENT intent, which involves the user in the file creation process.

What Happened in Android 4.4: The Angst-Riddled News

Since Android 4.2, there has been a request from Google for device manufacturers to lock down removable media. Generally, this was ignored.

For Android 4.4, Google amended the Compatibility Test Suite (CTS) that device manufacturers must comply with in order to ship a device containing Google’s proprietary apps (e.g., Play Store, Maps, Gmail; otherwise known as “GMS”). Quoting Dave Smith:

However, new tests were added in CTS for 4.4 that validate whether or not secondary storage has the proper read-only permissions in non app-specific directories, presumably because of the new APIs to finally expose those paths to application developers. As soon as CTS includes these rules, OEMs have to support them to keep shipping devices with GMS (Google Play, etc.) on-board.

As a result, apps can read files on removable media using the various undocumented and unsupported tricks for finding removable media. However, apps cannot write to or otherwise modify such removable storage. Note that device manufacturers themselves may have ways of dealing with this, but ordinary app developers do not.

The android-platform Google Group has been the home of a rather epic discussion thread regarding Google’s decision here, including Dianne Hackborn’s entry linked to earlier in this post.

Despite the hand-wringing, I do not expect Google to backpedal on this issue. For every user that complains about how Android 4.4 makes their micro SD card useless, there’s a pundit complaining about how Android lets any app run amok and read stuff on storage, raising privacy and security issues. In fact, I would not be the least bit surprised if read access to removable media is blocked in the future, beyond an app’s own directory on that media.

Where Can I Learn More?

Two of the better resources for this topic are ones I linked to earlier in this post:

What We’ve Got Here Is Failure to Communicate

This episode is yet another in a continuing series of episodes that demonstrate communications breakdowns: from Google to developers, from Google to users, and from developers to users. I will explore those breakdowns in the remaining two posts.

The Rest of the Posts

The entire blog post series covers:

Apr 09, 2014


Older Posts