The CommonsBlog


Random Musings on the Android 15 Beta 1

When Google releases a new beta, I rummage through the API differences report, the high-level overviews, and even the release blog post, to see if there are things that warrant more attention from developers. I try to emphasize mainstream features that any developer might reasonably use, along with things that may not get quite as much attention, because they are buried in the JavaDocs.

As often happens with the first beta, we had a bunch of stuff deleted, meaning it shipped in a developer preview then was removed. My assumption is that these represent things that did not quite “make the cut” and are going to be revisited.

That said, we did get a decent bunch of new things as well.

What Might Break You Next Year

Edge-to-edge will be enabled by default on Android 15, for apps that target Android 15. This means that new apps should be built from the ground up to be edge-to-edge. Ideally, existing apps that do not fully support edge-to-edge should take the next 1.5 years to adopt an edge-to-edge presentation. There is a new android:windowOptOutEdgeToEdgeEnforcement attribute, probably for <activity>, that you can set to true to perhaps buy more time. However, the docs for that attribute say that it will be deprecated and disabled “in a future SDK level”. If they do that in next year’s Android 16, the attribute will not buy you any meaningful time. Frankly, Google’s penchant for mandating their particular preferred aesthetics is annoying — as somebody told me on Stack Overflow over a decade ago, if I wanted somebody forcing their designs on me, I’d be programming for iOS.

What Makes Me Go 🤨

They added E2eeContactKeysManager. On the one hand, it provides first-class support for end-to-end encryption keys. On the other hand, it is tied to the user’s contacts app, which seems rather limiting.

They added cover screen support in an earlier developer preview, and the docs still refer to it. But they removed the actual property (COMPAT_SMALL_COVER_SCREEN_OPT_IN) from the SDK. My guess is that the docs are wrong and this feature was removed.

WindowManager now has the concept of “trusted presentations”. Basically, you can find out if your window is only partially shown or is being shown mostly translucent. For a multi-window environment, I can see the value in knowing these things, as it might impact how often you update your UI, or you might pause media playback. The “trusted”, though, makes me wonder if there is a security aspect.

They re-added FINGERPRINT_SERVICE.

The blog post’s section on “Secured background activity launches” doesn’t seem to point to anything new to Beta 1, so I am uncertain what they are referring to.

What Has Nothing to Do With Police Procedural Dramas

We now have access to a ProfilingManager system service for requesting certain types of profiling, including heap dumps and system traces.

What Else Is Interesting

ACTION_CHOOSER, which powers the “share sheet”, now supports EXTRA_CHOOSER_CONTENT_TYPE_HINT. The one documented value for this hint is CHOOSER_CONTENT_TYPE_ALBUM, to hint that the content being shared represents an “album”.

There is a new SecurityStateManager system service, which can return the system patch level and kernel version.

A View can now have an associated “credential request” tied to CredentialManager.

Wallet apps can now be set as the default recipient of NFC contactless payments via a new wallet role.

The concept of parent and child activities is being unwound: getParent() and isChild() on Activity are deprecated. There are better solutions for this nowadays, as multi-activity UIs slowly fade from existence.

Apr 13, 2024


Random Musings on the Android 15 Developer Preview 2

When Google releases a new developer preview, I rummage through the API differences report (even when Google does not seem to link to them 🙃), the high-level overviews, and even the release blog post, to see if there are things that warrant more attention from developers. I try to emphasize mainstream features that any developer might reasonably use, along with things that may not get quite as much attention, because they are buried in the JavaDocs.

This release is much larger than was the previous developer preview. It feels like Developer Preview 1 was “low-hanging fruit”, to give developers an additional month or so on the major changes for Android 15.

What Might Break You This Year

If your app is force-stopped, all pending intents are cancelled. This change affects all apps, not just those targeting Android 15. I thought this was already the behavior, but apparently it is not. For some devices that ship with “task managers” that apply force-stop logic instead of only terminating app processes, this change may really impact your users. Fortunately, at least, you will now get ACTION_BOOT_COMPLETED broadcast to your app so you can re-establish anything that was canceled. However, there also is a new ACTION_PACKAGE_UNSTOPPED broadcast that you might consider. PackageManager also now has an isPackageStopped() function, so external parties can see if your app was force-stopped.

FINGERPRINT_SERVICE was removed from Context, further impacting the already-deprecated FingerprintManager.

What Might Break You Next Year

Once you target Android 15, you will not be allowed to start some types of foreground services at boot time. I can see this causing problems for a fair number of apps.

Also, once you target Android 15, if your app supports Arabic, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam, Odia, Telugu or Thai, then Android will use a taller font by default. This may cause UI glitches, such as text being cut off due to lack of sufficient vertical space.

What I Like of the Prominent Changes

Google taking PDF rendering seriously is a nice improvement. PdfRenderer was designed for use in print previews, but developers have been trying to use it for arbitrary PDFs, with varying results. And since many developers really do not want to use the user’s preferred PDF reader, we were stuck with various workarounds. The fact that the improved PdfRenderer is being backported and apparently will be wrapped in a Jetpack library also helps a great deal.

Support for deeplink filtering on query parameters and fragments is something that developers have been requesting for several years, so it is good that we are getting it, even if that is not something that can be backported.

Granular line-break controls, so we can keep titles contiguous, is a long-awaited text rendering improvement.

Similarly, developers have been asking for how to find out why the app was started for quite some time.

Screen recording detection provides a nice middle ground between being oblivious to screen recording and using FLAG_SECURE to block it entirely. Note that you need a new normal permission to enable this capability.

What Makes Me Go “Hmmmmm…”

Resources now has a registerResourcePaths() method. “This will collect the package resources’ paths from its ApplicationInfo and add them to all existing and future contexts while the application is running”.

Getting and setting the system bar colors is now deprecated.

What Else You Might Have Missed

Your manifest components (activities, services, receivers, and providers) can be protected with android:systemUserOnly="true". This is supposed to limit that component to at most one instance, and that instance can only be interacted with by the system user. My hope is that we can use this for specific places where we want to plug into the framework but want to preclude arbitrary other apps from trying to use the component.

Through DevicePolicyManager, eligible apps can mandate “content protection” or can allow user choice. In this case, “content protection” means “scanning for deceptive apps”. Similarly, a device owner or policy owner can block NFC for certain users.

For app stores, ACTION_UNARCHIVE_PACKAGE might prove interesting. Also, PackageInstaller now has a new set of APIs related to archiving apps.

There are new KeyEvent key code values for dedicated emoji picker and screenshot keys.

We can now limit drag-and-drop to be just within our app, even if we have multiple windows. We can also specify an activity IntentSender to use for unhandled drops.

Mar 23, 2024


Random Musings on the Android 15 Developer Preview 1

Wow, it’s February again already?

When Google releases a new developer preview, I rummage through the API differences report, the high-level overviews, and even the release blog post, to see if there are things that warrant more attention from developers. I try to emphasize mainstream features that any developer might reasonably use, along with things that may not get quite as much attention, because they are buried in the JavaDocs.

Last year, a common complaint was how small Android 14 felt. This year, Android 14 seems huge by comparison. Android 15 DP1 is so small, Google did not bother writing a high-level overview of the changes, or at least it has not been published in an obvious location. Google usually does a bit of “sandbagging” in early developer previews, preferring to talk about changes one release later than when they are introduced. Still, this total lack of docs is rather stunning.

What Gives Me Security Concerns

AccessibilityService has long been used for things other than accessibility. Google tried for a while to enforce this at the Play Store level, but if I recall correctly they backed off.

AccessibilityService now offers the ability to attach overlays to displays (and to windows). These are designed for UI that controls the accessibility itself, apparently.

I worry a bit that users will enable accessibility for an app for other reasons (e.g., help with playing some game), then get bitten by tapjacking attacks initiated by these overlays. Hopefully, these overlays have system-supplied “chrome” that helps prevent this.

See also getOverlaySupport() on Display.

What Claims to Have Integrity

FileIntegrityManager has been around for a few years, but without a lot of functionality. Now we can call setupFsVerity() for a File, enabling some amount of tampering detection. However, the documentation for applying it (in setupFsVerity()) is seriously confusing.

What We Also Got In Android 14, Sorta

Android 14’s QPR2 added support for partial screen sharing, powered by MediaProjection. This change is also folded into Android 15 DP1.

What Else Is Interesting

PackageManager offers parseAndroidManifest(). This is designed for APKs that perhaps have not yet been installed. You get an XmlResourceParser back, letting you traverse the manifest akin to using XmlPullParser.

SystemClock now offers uptimeNanos(), the time since last boot, measured in nanoseconds.

JobManager, via JobInfo, now offers debug tags and trace tags for help with logging and traces.

MediaRoute2Info now supports a bunch of additional remote media routes: to cars, computers, game consoles, other phones, watches, tablets, or docked tablets.

We can now create notifications that have TV extensions, presumably for cases where a phone is tied to an Android TV device.

The parade of screen densities continues, as there is now support for a 390-dpi density.

Feb 17, 2024


Security and Third-Party Transports

A couple of weeks ago, news broke that governments might be spying on push messages delivered through Apple’s push notification system or Google’s Firebase Cloud Messaging.

(hat tip to Prof. Matthew Green for raising awareness)

IMHO, governments are only part of the problem. Apple and Google can read your push messages. While both firms claim that messages are encrypted, that is only for “data in motion”, as they are sent over the Internet. Messages in their servers are unencrypted. Not only can they access the data, but they can hand it to whoever they want to, not just governments.

While the current focus is on “Big Tech” push message systems, the problem is more general than that. Any third-party data transport system has the same sort of problem. Services like PubNub, Amazon SNS, Stream, and others that offer “publish/subscribe” and similar sorts of message-based APIs are very useful, but generally their data is encrypted in motion and not at rest. Those firms can see your messages, as can anyone that those firms allow.

Roughly speaking, I see two main ways of addressing this.

The best is to not send anything of significance in the message itself. Use it as a trigger mechanism only. So, the message might contain some sort of verb identifying what it wants the app to do, but nothing else. The app would then use other communications options (e.g., Web service calls) to do whatever it is the trigger is requesting. This allows you to focus on securing those other communications options, and you care less about spying on your messages.

The other is to encrypt your message payloads so that only the recipient can read them. This can work, but key management is a pain as always. IMHO, use this approach only if the messages do not require any other communications to be useful — if you are going to have to make a Web service call anyway, there is little value in packing data into the message itself.

Neither of these approaches help much with metadata. The message system providers (e.g., Google) and their favored partners (e.g., governments) can still examine which apps are getting messages, at what times and for what accounts (e.g., Google accounts). The only way to avoid that is to avoid using a message system provider, such as hosting your own messaging server. That has its own problems (e.g., background process limits in Android).

Using a push message system provider often is unavoidable. Letting them have your data is avoidable, by encrypting that data or not having any meaningful data in the messages themselves.

Dec 16, 2023


TV: Now What?

News broke recently that Amazon might move Fire TV away from Android and to their own in-house fork of Linux. TV app development would be done in React Native.

This really leaves TV Compose in the lurch. It will be used primarily for Android TV (a small fraction of the streaming device space) and for an ever-shrinking number of older Fire TV devices.

However, it further opens up an opportunity for some entrepreneur who wants to go after it.

App development for first-class TV devices will be highly fragmented now:

  • Roku uses a proprietary language and UI toolkit
  • Future Fire TV devices will use React Native
  • Legacy Fire TV devices and Android TV use Android frameworks like TV Compose
  • Apple TV uses macOS-style frameworks
  • Samsung, LG, and some other TV manufacturers offer their own stores and platforms

Here, “first-class TV devices” means devices where the app is installed on the device. Platforms like Chromecast, where the app is installed elsewhere, work substantially differently.

To me, this level of fragmentation, coupled with the nature of content-centric TV apps, suggests that a server-defined UI approach might work well. The TV apps would be largely white-labeled containers pointing to dedicated endpoints that serve the UI and the content viewed by that UI. Part of that server-defined UI would be a “stylesheet” for branding elements (color scheme, logos, etc.). The browsing and playback UI would be driven by a mix of the available content and some general presentation patterns, with customization as desired by the customer.

I am uncertain if Roku’s system will support this approach, as it is very proprietary and reminds me of 1990’s Visual Basic as much as anything.

It used to be that Roku plus Android would be 80+% of the North American TV streaming market. Eventually, that will become Roku plus React Native, as Amazon migrates to the new OS. Perhaps some enterprising developers will come up with something interesting to help bridge this gap and pick up the other smaller platforms as well.

Nov 18, 2023


Older Posts