Coming next year: Storage Armageddon! Maybe?

While scoped storage is totally optional this year and shouldn't break anything, next year (in Android R) it sounds like we're going to be in for a wild ride. Here's Google's official statement from this blog post: "Scoped Storage will be required in next year’s major platform release for all apps, independent of target SDK level, so we recommend you add support to your app well in advance."

It really sounds like this is going to break everything. Making new changes that apply to "all apps, independent of target SDK level" is usually not the way Google does things. Breaking changes happen in new Android versions all the time, but usually they are only for apps that target the latest release. Developers get to pick which version of the Android API they are compatible with, so when a developer targets the latest APIs, this means they have updated their app with the latest version of Android in mind. Even though certain changes might have broken something, the "target SDK" system means the developer is aware of those changes and has coded around them. Apps that haven't been updated to target the latest API get backwards compatibility considerations, and the breaking changes are not applied to them. Changes never happen retroactively to all apps regardless of target API level.

Back before Google announced that scoped storage would be optional, the doom and gloom surrounding mandatory scoped storage made things sound really bad. It's not just that file accessing applications needed to be rewritten, but scoped storage has the potential to break thousands of third-party app libraries that developers rely on. So the problem isn't just with file managers—random apps from all over the place could break depending on what libraries the developer used.

I'm not really sure why Google is going with the destructive approach of changing the way storage works for all apps. The new API-freshness rules implemented in the Play Store means developers can only post new or updated apps with API targets that are, at most, one year old. In regularly updated apps, the old storage methods would have died a natural death eventually. This year everyone has to target the Android 9 Pie API or above, so all the security restrictions in Android 9 will apply to them. A normal progression would be to make scoped storage mandatory for new apps in Android R, then a year after Android R's release, the Play Store would make Android R APIs the baseline for new and updated apps. This is a good progression since supported apps are forced to get with the times, while abandonware (which never updates) can still continue to be listed on the Play Store and work.

Right now, it sounds like Android R is going to nuke older apps to enforce these storage restrictions. I have a hard time believing that will actually happen, since Google usually goes out of its way to protect backwards compatibility, but this is what the public facts point to currently. Maybe Android R will force all apps to use scoped storage but implement some kind of emulated storage sandbox for older apps, denying them access to user storage but not crashing them. There will be a lot of announcements and information between now and the launch of Android R next year, but this is definitely something to keep poking Google about.

Other privacy changes

New in Android 10 is the standalone "Privacy" section in the settings. There's really nothing new in here, as it only houses links to the app permissions page and a few other miscellaneous checkboxes. It looks pretty bare in this release. The emptiness here is highly suspicious, given that XDA's alpha build of Android Q contained a "Privacy Dashboard" that did not make it to any of the official betas or the final release. Google carved out all this space for "Privacy" features, and a dashboard would be a good fit.

Google hasn't officially said anything about more enhanced privacy tracking, but XDA's leaked build seemed to take a "Digital Wellbeing" approach to app privacy, tracking permissions access with charts and graphs. It would not surprise me to see this Privacy Dashboard pop back up around the time the Pixel 4 launches, and in that case this "Privacy" section won't seem so underdeveloped.

"Location" runtime permission gets another option besides "Allow" (which is now "Allow all the time") and "Deny," labeled "Allow only while using this app." Pick this and the app can only ping your location in the foreground, meaning it can't spy on you in the background. If a user picks "allow all the time," they'll also occasionally get a notification when an app accesses the location in the background. The whole permission settings screen has also gotten a new coat of paint along with the settings, and that's now called "Permission Manager."

A lot of device identifiers are being locked down in Android Q to make it harder for companies to track users without the appropriate permissions. Android 8.0 used a random MAC address when scanning for Wi-Fi networks, and Android 9 Pie tested always-randomized MAC addresses behind a developer mode flag. In Android 10, this is now on by default, stopping any listeners out there from building an activity history from your Wi-Fi traffic. If you're in an enterprise setting and actually want to track a device's MAC address, the enterprise "Device owner" app can pull from a new API that gives the actual MAC address. This is useful for companies with fleets of devices, but to use this API you'll need to be in full enterprise remote management mode using something like Android for Work.

Other identifiers like the IMEI and serial numbers are locked behind the "Phone" permission now. Access to the USB serial requires permission to access the USB device. For apps that target Android 10, access to telephony, Wi-Fi, and Bluetooth APIs now require the "location" permission, since those things can be used to derive a rough location.

Android 10 has put some limits on which apps can launch activities (activities are just an interface window) from the background, which will stop applications from randomly taking over the screen. It's not a total lockdown—there is a laundry list of caveats that will still allow for a background activity launch. A lot of them have to do with recency, as in, apps can launch an activity from the background if they have started recently, or closed recently, or are in the back stack of the current application. Certain apps with services bound by the system are allowed to launch activities, namely Accessibility apps, Autofill apps, NFC apps (read: Google Pay), Phone apps, Quick Settings tiles, Assistant apps, and VR apps. Intent requests from the OS or the current app can cause an app to launch an activity, so an app calling for a camera will still make the camera app open. Background app launches are also allowed for incoming calls, companion device apps (like the Wear OS app), and anything that is an enterprise device policy app. Whew.

The last privacy-inspired change has to do with clipboard apps. Unless an app is the currently selected keyboard or has focus, it cannot access clipboard data. This essentially kills clipboard apps. I can see how allowing access to every string the user copy-and-pastes could be a security and privacy concern, but why the lack of a clipboard app API? With this change, Google just killed a whole app category.

Bubbles—A "Developer Preview" of a floating app API

Ron Amadeo

Ron Amadeo

Ron Amadeo

Ron Amadeo

Ron Amadeo

Ron Amadeo

Ron Amadeo

Ron Amadeo

New in Android 10 is what Google is calling a "Developer preview" of a new feature called "Bubbles." Bubbles is another officially-sanctioned floating app API, which Google hopes will eventually find adopted alongside the existing picture-in-picture API. The feature works a lot like Facebook Messenger's old "Chat Heads" interface, a circular icon floats overtop of all your apps and has an interface panel attached to it. You can minimize the interface panel into the icon bubble and drag it around, giving you a fun multitasking interface.

Bubbles are created using the notification API. When they eventually work, these will be able to be spawned by an incoming notification or by the user pressing a button. In the Android Q beta, we were able to force some apps into bubbles that weren't designed for it, and they looked just like they do in the notification panel, just floating around. Apps designed for the Bubble API will be able to pack more interface into the bubble, but for now we only have Google's demo app and some mockups.

Originally floating apps used the "System Alert Window" API that introduced all the way back in Android 1.0. As you would expect from an API that old, it was not locked down or scoped appropriately at all. It was meant for actual system-level alerts, like a crash message or amber alert, but for some reason it was left open to apps. This super-power API lead to things like Chat Heads, but malicious apps could use System Alert Window to takeover the entire screen, which was possible since the API is able to draw overtop of every other window including the navigation bar. To make matters worse, the System Alert Window didn't attribute itself to the app that spawned it, so if you had a rogue system alert, it was hard to track down the culprit.

Google started to rein in the API in Android 6.0 Marshmallow, gating it behind the "Draw over other apps" permission. Android 8.0 Oreo killed the API for apps that targeted 8.0 or higher. It also made the API properly attributable on older APIs, spawning a "[App name] is displaying over other apps" notification whenever the System Alert API was used. Oreo also completely blocked System Alert Window in devices running the low-end "Go" version of Android, since the Alert Window becomes locked in memory and can cause performance issues.

In exchange for blocking the System Alert Window API for future apps, Oreo introduced a picture-in-picture API that is most commonly seen today in YouTube and Google Maps. Google wants Bubbles to co-exist with the picture-in-picture API, saying that PiP is for low-interaction tasks that you want to physically monitor, while Bubbles is for high interaction tasks. That seems fine, but I wish the Bubbles minimizing feature would come to PiP. There are several times when I've had a PiP window open and just wanted to get it temporarily off the screen.

Googlers referred to Bubbles as "Chat bubbles" a few times during Google I/O, and all the demos show a bubble containing a chat app. The documentation, though, says you could stick any activity in there, so theoretically you could build whatever you want into a bubble, like a floating calculator app. When they actually work, chat bubbles can be set to spawn for an incoming notification. But for now, Google is limiting those to incoming messages, calls, and things the users has personally flagged.

While bubbles might have been a feature you've seen elsewhere, at Google I/O 2019, System UI lead Dan Sandler explained this is actually a big part of how the System UI team works. When talking about the Bubbles API and gesture navigation, Sandler put up a slide showing the "System UI team loop." It read:

1. Notice a UI paradigm in the wild. 2. Make it safer, more reusable. 3. Add it to the framework.

As the leader of the Android ecosystem, Google is in a position to take all the crazy ideas that pop up in the Android ecosystem and make them officially, safely supported.

Bubbles is just a developer preview for now, so everything above can change. There are currently zero apps that actually use it, since you have to turn it on in the developer options. In the future Google says the bubble feature will be opt-in for users, and eventually it will shut down the System Alert Window API entirely, even for older apps. One problem I see with the Bubbles API is that, since it is exclusive to Android Q and its zero percent install base, developers will have a hard time justifying building in support for the feature. It would be nice to see some kind of backwards compatibility for bubbles, like maybe a library that gets it up and running on through the System Alert API. That way, even though Google wants to kill the System Alert API in a future version, these will always be active on old versions of Android.

Security

Google

Google

Google

The work on Android's security is never done. Besides making the "Stagefright" media components updatable through Project Mainline, Google is also splitting up the types of media codecs so they can more tightly constrained. With the launch of Project Treble in Android 8, the media codecs were placed in a hardware abstraction layer (HAL) so they could access the hardware acceleration that exists for some codecs. This HAL was a mix of software and hardware-accelerated codecs, though, and in Android 10, the two have been separated. Hardware-accelerated codecs get in a HAL with access to the device drivers, and the software codecs get less privileges. Google says that "With this move, we now have the two primary sources for media vulnerabilities tightly sandboxed within constrained processes."

Last year Google introduced the "biometrics API" in Android 9, replacing the old fingerprint API. The old fingerprint API was made only for capacitive fingerprint readers, and like the name suggests, the Biometrics API was built for more varied authentication. In Android 9, it added support for in-screen fingerprint readers, and now in Android 10 it supports facial recognition. This will probably come in handy for the Pixel 4, which is sporting all the usual FaceID sensors.

Also new in the biometrics API: When apps call up the interface, there are now options for an implicit or explicit confirmation. The implicit confirmation will automatically advance the interface as soon as you are authenticated, which is great for things like sign-in. The explicit confirmation requires you to hit a "confirm" button, which is more appropriate for things like payments. There's also an option for a fallback credential like a PIN for those times when a fingerprint or face scan won't work.

Google is making TLS 1.3 (Transport Layer Security) the default for all TLS connections. TLS 1.3 was finalized by the IETF last year, and it's faster and more secure than older versions. Google says that a faster handshake should make connection times up to 40% faster.

Android 10 is also adding support for WPA3, the newest security protocol for connecting to wireless networks. Right now there are not many routers that support WPA3.

We talk a lot about apps "targeting" a new release of Android, which gives them access to all the latest Android capabilities along with all the latest privacy and security restrictions. Starting around the release of Android 9, the Play Store and the Android OS have started deprecating old Android API levels, encouraging developers to switch to a newer version. On the Play Store, new and updated app submissions are only accepted if they target an API that is one year old or newer. And around the release of Android 10 (API level 29), the floor for app submissions will be bumped up to Android 9 (API level 28). In the Android OS itself, the system will also warns users the first time they run an app that uses an API that is very old. In Android 9, this was Android 4.2 Jelly Bean (API level 17), a six-year-old OS at the time, and in Android 10 this warning is being bumped up to Android 6.0 Marshmallow (API level 23), a four-year-old OS.

Adiantum—Storage encryption for everyone

Android always strives to bring the same powerful software to every smartphone, from the most expensive $2600 foldable phone to the cheapest $10 piece of junk you can find. Whether the hardware can handle all this software is a different story, and one of the features that has remained out the cheapest phones is storage encryption by default. Google's compatibility rules from Android 6 Marshmallow up to Android 9 (the Android 10 compatibility docs are not out yet) require storage encryption for devices with Advanced Encryption Standard (AES) crypto performance above 50MiB/sec. The way phones hit this number is with hardware acceleration for encryption and decryption, which usually comes with devices with the ARMv8 instruction set.

Today, encryption-by-default is on for the vast majority of Android phones. If we look at Qualcomm's lineup, nearly every single SoC is 64-bit and packing ARMv8, all the way down to the lowly Snapdragon 215. This is still not every phone, though, and the cheapest devices (usually devices sold in developing countries) still lack encryption. Usually in Android land, these are some (but not all!) of the low-end "Android Go" devices, like the $80 ZTE Tempo Go that we reviewed last year. The Snapdragon 210 in that device is still packing 32-bit Cortex A7 cores straight out of 2011, so it notably lacked encryption by default. You also can't get encryption on Android smartwatches (if those are still a thing) because they also only ship the Cortex A7 from 2011, thanks to Qualcomm.

So to get encryption on these cheaper devices, Googlers Paul Crowley and Eric Biggers developed "Adiantum," a new storage encryption technique designed to run on devices that lack hardware acceleration for AES. Google calls Adiantum "Encryption for the next billion users" and says it can run on "across everything from smart watches to internet-connected medical devices."

In Adiantum's introductory blog post, Google specifically calls out the ARM Cortex A7 CPU as an issue for encryption. "On these devices, AES is so slow that it would result in a poor user experience; apps would take much longer to launch, and the device would generally feel much slower." So Adiantum was written with devices like this in mind. Today there is encryption that works on these devices, and one example is the widely-used ChaCha stream cipher (this is used in, among other things, Google's HTTPS implementation in Chrome). ChaCha offers secure encryption fast on just about everything, because it exclusively uses operations that all CPUs natively support: additions, rotations, and XORs.

Adiantum takes the ChaCha encryption primitive and expands it to work across the entire file system. This involved solving a number of problems, mainly managing to use ChaCha in a "length-preserving" mode. The way ChaCha is used in Google's HTTPS implementation requires adding a few more bits to the original message for the cryptographic nonce and data integrity, which doesn't really work for a storage device. Storage is encrypted on a block-by-block basis, so if your output is bigger than your input, you have to hunt around for that extra space every time you want to decrypt and encrypt to make a read or write. On an already slow device, adding extra work to every single read and write will not be fast. Adiantum borrows some ideas from AES to make a length-preserving encryption mode for ChaCha, and the result is a speedy, secure encryption method for ancient ARM CPUs.

ChaCha implementations are labeled with a trailing number, which is how many times your data has been run through the cipher. Naturally, more is more secure. The best known attacks against ChaCha have broken ChaCha7, while Chrome's HTTPS goes with the extra-secure ChaCha20. On Android, Adiantum uses ChaCha12, which the Adiantum spec paper says "is consistently one of the fastest options for the 'armeabi' (32-bit ARM) architecture," aka the Cortex A7. Google's blog post promises big performance improvements over software AES, though. "On ARM Cortex-A7, Adiantum encryption and decryption on 4096-byte sectors is about 10.6 cycles per byte, around 5x faster than AES-256-XTS."

Any new encryption method should face some skepticism, but given that Adiantum is made up of other encryption primitives, it should be secure, too. As Biggers writes on the Linux Kernel mailing list, "Adiantum is a construction, not a primitive. Its security is reducible to that of XChaCha12 and AES-256, subject to a security bound; the proof is in Section 5 of our paper. Therefore, one need not 'trust' Adiantum; they only need trust XChaCha12 and AES-256."

With Adiantum, encryption will no longer be an option for Android devices. Google's blog post lays down the law, saying, "In Android Q, Adiantum will be part of the Android platform, and we intend to update the Android Compatibility Definition Document (CDD) to require that all new Android devices be encrypted using one of the allowed encryption algorithms." The two options, then, would be hardware AES or Adiantum. Now we just need some cheap devices with Android 10!