Random Musings on the Q Developer Preview 1
Each time 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.
As with the previous two releases, Q seems to be lacking a prominent user-facing feature. Q is certainly better, but I have no idea what I will tell my mother that she’ll gain if her phone gets the Q update at some point.
However, there are a number of changes for developers.
What Will Piss Off Developers
Google has done quite a bit over the past several releases to improve privacy and security in Android. That tends to be a double-edged sword, though, where the changes break existing app functionality. So, for example, developers of file managers are going to be rather disgruntled with scoped storage, which says that you can no longer access all of external storage via the filesystem.
The roles system is an
interesting concept. At one level, it might mostly be there for the benefit
of the Play Store and other app distribution channels, to better identify whether
apps are justified in holding certain permissions. However, the relationship
between roles and permissions is almost completely undocumented. For example,
does ROLE_SMS
“Can send and receive SMS messages; can read contacts” mean
that no other app can read the contacts, despite requesting the READ_CONTACTS
permission? The fact that we need to run experiments and attempt to reverse-engineer
the documentation is never a good sign.
Other things will just pour salt into existing wounds. For example, the “non-SDK interfaces” push continues in Q, so developers that dodged bullets in P might now run into problems in Q, if their preferred hack is no longer available.
Plus, there is your usual barrage of changes that won’t affect everyone but
might dramatically impact some developers. Starting an activity from the background
has long been considered to be poor form; developers who stuck with it
now have problems.
SYSTEM_ALERT_WINDOW
has been dodgy for years; developers who stuck with it
now have problems.
Background access to the clipboard is gone.
Using locations in the background is overhauled. And so on.
What Will Piss Off Me
Google says that they have changed onResume()
onPause()
, and android:resizeableActivity
,
but they did not seem to document what changed. ¯\_(ツ)_/¯
At least on the onResume()
/onPause()
stuff, prior reports indicate
that multi-window environments — including foldables — will now
leave apps in the resumed state even if they no longer have the input focus.
There appears to be a new onTopResumedActivityChanged()
activity callback to find out if this activity is now the “top resumed activity”,
which I am guessing means “the activity with the input focus”.
What Has Me Worried
There is a whole new set of APIs around “content capture”. Unfortunately, the central class has “TODO” for its documentation. However, it is tied to the detestable autofill APIs and seems to report when views come and go. In the hands of responsible individuals, this has interesting characteristics for app testing. In the hands of irresponsible individuals, this could be yet another privacy leak.
Similarly, there is an InspectionCompanion
“used to inspect views”. This, at
least, seems like it may be only some kind of in-process capability, even though
it is largely undocumented.
There is a new GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY
permission, which
“allows an application to get the screen lock complexity and prompt users to update the screen lock to a certain complexity level”.
On the surface, this seems fine, but this is a normal
permission, so users
are not prompted about it. Historically, this sort of functionality was limited
to device administration apps.
There is a new SMS_FINANCIAL_TRANSACTIONS
permission, which
“allows financial apps to read filtered sms messages”. However, I don’t know
how one defines either “financial apps” or “filtered sms messages”. The
protection level of this permission is undocumented.
There is a new setAllowSystemGeneratedContextualActions()
method on Notification.Builder
that “determines whether the platform can generate contextual actions for a notification. By default this is true.”
Frankly, the notion that Android will automatically put actions into our notifications
creeps me out.
What Has Me Wondering How Far Down the Rabbit Hole Goes
Google has been pushing us away from background services for a couple of releases,
forcing a lot of developers to switch to foreground services. Now, with Q,
there are “types” of foreground services, described via an android:foregroundServiceType
attribute (in the manifest?). Available types include phoneCall
,
mediaPlayback
, location
, dataSync
, and connectedDevice
. The
startForeground()
call can now also pass in the type of foreground service
it will be (or a FOREGROUND_SERVICE_TYPE_MANIFEST
flag to say “read the values
from the manifest”). So, now we have services, then foreground services, then
types of foreground services. What’s next? Subtypes? Plus, it remains to be seen
what the system does with this type information.
What Has Me Intrigued
RecoverableSecurityException
makes its return, having been in one of the past rounds of developer previews
but removed from the SDK prior to release. If you catch one of these, you
have a dedicated message and RemoteAction
for being able to help fix whatever
the problem is.
There is a new
android:useAppZygote
attribute for <service>
in the manifest.
It allows an isolated service (android:isolatedProcess
) to have its process
forked from “an Application Zygote, instead of the regular Zygote”. From the docs,
my guess is that this is here for Chrome and similar apps that may want to fork
lots of isolated processes for executing possibly-unsafe code. However, isolation
from the regular app zygote may also mean that attacks that affect the app
zygote (and therefore all normal app processes) might not affect these isolated services.
There is a new isRunningInUserTestHarness()
method on ActivityManager
.
This apparently is not to detect normal instrumentation tests, but rather some
other style of tests for “a device farm/testing harness (such as Firebase Test Lab)”.
The idea is that you would use this flag to skip over stuff that might screw
up such tests. It remains to be seen exactly where this is true
or false
.
In Android 8.0, we gained the ability to launch an activity into a particular
display. This is a useful alternative to the Presentation
API. Apparently,
though, there are some external displays that will show up in the system as
displays, but for which you cannot show an activity on them. There is a new
isActivityStartAllowedOnDisplay()
method on ActivityManager
to use to determine
if a particular display is good for activities. My best guess is that this
is for foldables, but that’s just a guess.
There are a bunch of new methods on NotificationManager
. A lot center around
the notion that you can allow some other app to post notifications on your
app’s behalf (a “delegate”).
Font
, FontFamily
, and related classes are now part of the framework APIs.
An entire MediaPlayer2
and related classes were added, apparently as a replacement
for MediaPlayer
. I have not worked with ExoPlayer, so I do not know how
MediaPlayer2
might relate to ExoPlayer in terms of API or implementation.
There is now a DnsResolver
class “for asynchronous dns querying”. In related
news, AWLTCLB (Abbreviations Would Like Their Capital Letters Back).
Uri
has toSafeString()
, which attempts to redact some information to make
the resulting text safe for logging purposes. My guess is that the resulting
string will then be useless for debugging, but perhaps I am being pessimistic.
They added a FileUtils
class, mostly containing various copy()
methods.
Environment
now offers dedicated public directories for audiobooks (DIRECTORY_AUDIOBOOKS
)
and screenshots (DIRECTORY_SCREENSHOTS
).
PowerManager
now offers methods to get the “thermal status” (i.e., is the device
being throttled to reduce its temperature) and register a callback for status changes.
This may be useful for games or other high-intensity apps, so they can provide
a UI indicator that explains why things are now running more slowly (so the device
can cool down).
The new settings panels seem nice, though I’m uncertain why bloggers keep insisting
this has something to do with slices. We show a settings panel via startActivity()
,
so most likely they are just activities themed as a bottom sheet dialog. Then
again, it would be nice if slices were used for something. Just sayin’.
What Is Now an Ex-API
The entire preference system, outside of SharedPreferences
, is deprecated.
This includes PreferenceManager
and the entire preference UI. Developers
are steered towards the AndroidX replacements.
ACTION_INSTALL_PACKAGE
and ACTION_UNINSTALL_PACKAGE
are deprecated.
Instead, we appear to need to use the more-cumbersome PackageInstaller
API.
ACTION_NEW_OUTGOING_CALL
is deprecated. There are new CallRedirectionService
and CallScreeningService
APIs for apps that formerly did that sort of work
by listening for ACTION_NEW_OUTGOING_CALL
broadcasts.
The “preferred activities” APIs in PackageManager
are now deprecated.
NetworkInfo
is deprecated, along with the methods on ConnectivityManager
that return a NetworkInfo
.
StorageVolume.createAccessIntent()
is deprecated. More importantly, it will
fail fast. This was used to request access to one of the Environment
public directories, as an alternative to needing READ_EXTERNAL_STORAGE
and therefore getting access to the entire external storage area. It would appear
that the scoped storage feature not only replaces this but is incompatible
with this. So, if you are using createAccessIntent()
, you will need to add
code to take a new approach on Android Q and higher devices.
Where Things Go From Here
There are six beta releases on the docket. Beta 4, due in early June, is supposed to have final APIs, so I’ll have a few more “random musings” posts to write in the upcoming weeks.
Plus, I’ll be giving some of this new stuff a workout, and I’ll have new material for subscribers covering Android Q soon.