This week is for Media3 and a bit of Test:
androidx.media3:media3-cast:1.5.0-rc01
androidx.media3:media3-cast:1.5.0-rc02
androidx.media3:media3-common:1.5.0-rc01
androidx.media3:media3-common:1.5.0-rc02
androidx.media3:media3-common-ktx:1.5.0-rc01
androidx.media3:media3-common-ktx:1.5.0-rc02
androidx.media3:media3-container:1.5.0-rc01
androidx.media3:media3-container:1.5.0-rc02
androidx.media3:media3-database:1.5.0-rc01
androidx.media3:media3-database:1.5.0-rc02
androidx.media3:media3-datasource:1.5.0-rc01
androidx.media3:media3-datasource:1.5.0-rc02
androidx.media3:media3-datasource-cronet:1.5.0-rc01
androidx.media3:media3-datasource-cronet:1.5.0-rc02
androidx.media3:media3-datasource-okhttp:1.5.0-rc01
androidx.media3:media3-datasource-okhttp:1.5.0-rc02
androidx.media3:media3-datasource-rtmp:1.5.0-rc01
androidx.media3:media3-datasource-rtmp:1.5.0-rc02
androidx.media3:media3-decoder:1.5.0-rc01
androidx.media3:media3-decoder:1.5.0-rc02
androidx.media3:media3-effect:1.5.0-rc01
androidx.media3:media3-effect:1.5.0-rc02
androidx.media3:media3-exoplayer:1.5.0-rc01
androidx.media3:media3-exoplayer:1.5.0-rc02
androidx.media3:media3-exoplayer-dash:1.5.0-rc01
androidx.media3:media3-exoplayer-dash:1.5.0-rc02
androidx.media3:media3-exoplayer-hls:1.5.0-rc01
androidx.media3:media3-exoplayer-hls:1.5.0-rc02
androidx.media3:media3-exoplayer-ima:1.5.0-rc01
androidx.media3:media3-exoplayer-ima:1.5.0-rc02
androidx.media3:media3-exoplayer-midi:1.5.0-rc01
androidx.media3:media3-exoplayer-midi:1.5.0-rc02
androidx.media3:media3-exoplayer-rtsp:1.5.0-rc01
androidx.media3:media3-exoplayer-rtsp:1.5.0-rc02
androidx.media3:media3-exoplayer-smoothstreaming:1.5.0-rc01
androidx.media3:media3-exoplayer-smoothstreaming:1.5.0-rc02
androidx.media3:media3-exoplayer-workmanager:1.5.0-rc01
androidx.media3:media3-exoplayer-workmanager:1.5.0-rc02
androidx.media3:media3-extractor:1.5.0-rc01
androidx.media3:media3-extractor:1.5.0-rc02
androidx.media3:media3-muxer:1.5.0-rc01
androidx.media3:media3-muxer:1.5.0-rc02
androidx.media3:media3-session:1.5.0-rc01
androidx.media3:media3-session:1.5.0-rc02
androidx.media3:media3-test-utils:1.5.0-rc01
androidx.media3:media3-test-utils:1.5.0-rc02
androidx.media3:media3-test-utils-robolectric:1.5.0-rc01
androidx.media3:media3-test-utils-robolectric:1.5.0-rc02
androidx.media3:media3-transformer:1.5.0-rc01
androidx.media3:media3-transformer:1.5.0-rc02
androidx.media3:media3-ui:1.5.0-rc01
androidx.media3:media3-ui:1.5.0-rc02
androidx.media3:media3-ui-leanback:1.5.0-rc01
androidx.media3:media3-ui-leanback:1.5.0-rc02
androidx.test:orchestrator:1.6.0-alpha01
androidx.test.services:storage:1.6.0-alpha01
androidx.test.services:test-services:1.6.0-alpha01
—Nov 20, 2024
The good news is: the API differences report that was broken when
I wrote about Android 16 DP1 yesterday
has been repaired! As a result, we get access to insights like this from
the docs for AppFunctionService
:
Abstract base class to provide app functions to the system
…and this in the docs for AppFunctionManager
:
Provides app functions related functionalities.
App function is a specific piece of functionality that an app offers to the system. These functionalities can be integrated into various system features.
🙄
While the rest of the documentation on “app functions” is sparse, some of my guesses were accurate.
App functions are tied into app search, as the object representing
a specific function request
points to a GenericDocument
from the app search area. And, developers should be able to create
subclasses of AppFunctionService
to handle app function requests. This is a bound service,
defended by BIND_APP_FUNCTION_SERVICE
so that only a system process can bind to it.
There is mention of an “App Functions SDK”:
In most cases this identifier should come from the ID automatically generated by the AppFunctions SDK
There is also mention of EXECUTE_APP_FUNCTIONS_TRUSTED
and EXECUTE_APP_FUNCTIONS
that are not
in the Android SDK yet. With luck, these point to future areas with more information about what
this is all about.
—Nov 20, 2024
Wow, it’s February again already?
*checks calendar*
No, Google is just changing the timeframe for major Android releases.
As is outlined in the Android 16 DP1 blog post,
Google is moving to having a major and a minor release each calendar year. The major release
has been moved earlier in the year to better align with device manufacturer timetables.
The minor release, planned for late 2025, “will include new developer APIs” but should not
“include planned behavior changes that could affect apps”.
So, What’s In the API Differences Report?
Fans of these “random musings” posts know that I pore through the API differences report to help
provide detail beyond what the release notes state and to identify other changes that Google
is not talking about yet.
That is not working out so well this time around.
Simply put, the API differences report
is largely broken. Links lead to 404s or call out API additions that do not show up in the actual
documentation. It could be that they changed the scope of DP1 and failed to regenerate the API
differences report. Or, it could be that the API differences report is correct and they failed
to publish the documentation updates. My guess is that it is the former, given the mix of what
is working and what is not.
I may publish a follow-on post with more if the API differences report starts behaving more normally.
OK, What Can You Tell Us?
The biggest area of change surrounds the photo picker. As is noted in the release notes:
The developer preview includes new APIs that enable apps to embed the photo picker into their view hierarchy. This allows it to feel like a more integrated part of the app while still leveraging the process isolation that allows users to select media without the app needing overly broad permissions.
What is interesting to me is that they are using SurfaceControlViewHost
for this.
The actual UI will be rendered by a separate process, but you can control where that UI gets
rendered on your screen, wrap it in your own UI, etc. Google debuted this system
four years ago,
and I have been waiting for it to get put to use — it might be applied elsewhere, but this
is the first that I recall seeing.
The other big area of possible change is something called “app functions”. This is a bit of a
“negative space” analysis, as this is the biggest area that is missing from the API differences
report. For example, there is a new android.app.appfunctions
package…
and there is no documentation for it,
despite a link to that page from the API differences report. But, what I can infer is:
Given those two, I’ll guess that the app search functionality will gain some sort of “quick actions”
UI, where developers can publish operations (“app functions”) that can be performed on search results for their
app. What would be even more interesting is if developers could offer actions on any search results.
UPDATE 2024-11-20: The docs are better now!
Is There Much Else of Note?
The release notes and
blog post
mention changes to Health Connect and Privacy Sandbox. If you use either of those, you may want
to investigate further.
Beyond that:
Little else seems like it has changed in areas that might be commonly used. Ad Services might
qualify, but I have never used it, so I cannot really cover it here.
That’s It?
Even if we assume that the broken documentation points to changes, this is a surprisingly small
major release. Since there is only one more developer preview, and API changes should start fading
out after a Beta 1 release, Android 16 might be a bit sparse in terms of developer-facing changes.
Since they had ~3 months chopped off the development schedule, this seems reasonable. It may be that
DP2 will turn out to be much larger.
For user-facing changes, as always, pay attention to Mishaal Rahman,
who does excellent work covering those!
—Nov 19, 2024
I have received inquiries as to how my former androidx.tech
site worked. It offered a catalog
of every Jetpack artifact version, including the source code. It was designed to be a workaround
for the fact that Google did not offer this sort of stuff back in the day. Nowadays,
maven.google.com
kinda has this, insofar as it offers “source”
links (and you need to inspect for yourself which is the actual artifact source and which is
sample code).
So, here is how androidx.tech
worked.
Step 1: Find the POMs
Google’s Maven publications have long had links to source JARs for their artifact versions
in their POM files. The POM files also had information about dependencies that I wanted to
display. So, I needed the POM files for all the artifacts and their versions. And, to save
me having to re-download them, I wanted to store each of those POMs locally.
The simplest solution, given this need plus the need for the source code, would be to mirror
maven.google.com
. I could not figure out how to do this five years ago, and I may also have
been concerned about how much disk space would be needed by all of this.
I created a Kotlin project, reporeader
, that would traverse the artifacts in a Maven
repository and pull their POMs. This involved:
-
Downloading https://dl.google.com/dl/android/maven2/master-index.xml
and parsing the XML
to get the list of artifact groups
-
Filtering that list to only worry about androidx.
groups, as Google’s Maven repository has
a lot of other stuff as well, such as Play Services
-
Generating the URL for the artifact group index, which involves replacing all the .
characters in the artifact group with /
and using that to get a group index XML URL,
such as https://dl.google.com/dl/android/maven2/androidx/activity/group-index.xml
for
androidx.activity
-
Downloading and parsing that XML to get the artifacts and versions that are in that
group
-
Generating the URL for the POM, which replaces group-index.xml
in the group index URL
with /$artifact/$version/$artifact-$version.pom
for a given artifact name and artifact
version, giving you something like
https://dl.google.com/dl/android/maven2/androidx/activity/activity-compose/1.10.0-alpha03/activity-compose-1.10.0-alpha03.pom
-
Downloading that POM
This tool also knew to emit a roster of what was new: new artifact groups, new artifact IDs
within a group, and new artifact versions. I still use this tool today, to generate the
list of changes that go into posts like this one.
Step 2: Download the Sources
A POM file is an XML file with lots of interesting info:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>
<groupId>androidx.activity</groupId>
<artifactId>activity-compose</artifactId>
<version>1.10.0-alpha03</version>
<packaging>aar</packaging>
<name>Activity Compose</name>
<description>Compose integration with Activity</description>
<url>https://developer.android.com/jetpack/androidx/releases/activity#1.10.0-alpha03</url>
<inceptionYear>2020</inceptionYear>
<organization>
<name>The Android Open Source Project</name>
</organization>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>The Android Open Source Project</name>
</developer>
</developers>
<scm>
<connection>scm:git:https://android.googlesource.com/platform/frameworks/support</connection>
<url>https://cs.android.com/androidx/platform/frameworks/support</url>
</scm>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>androidx.activity</groupId>
<artifactId>activity</artifactId>
<version>1.10.0-alpha03</version>
</dependency>
<dependency>
<groupId>androidx.activity</groupId>
<artifactId>activity-ktx</artifactId>
<version>1.10.0-alpha03</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>androidx.compose.runtime</groupId>
<artifactId>runtime-saveable</artifactId>
<version>1.7.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>androidx.activity</groupId>
<artifactId>activity-ktx</artifactId>
<version>[1.10.0-alpha03]</version>
<scope>compile</scope>
<type>aar</type>
</dependency>
<dependency>
<groupId>androidx.compose.runtime</groupId>
<artifactId>runtime</artifactId>
<version>1.7.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>androidx.compose.ui</groupId>
<artifactId>ui</artifactId>
<version>1.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>androidx.core</groupId>
<artifactId>core-ktx</artifactId>
<version>1.13.0</version>
<scope>compile</scope>
<type>aar</type>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.7.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>androidx.lifecycle</groupId>
<artifactId>lifecycle-runtime</artifactId>
<version>2.6.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>androidx.savedstate</groupId>
<artifactId>savedstate</artifactId>
<version>1.2.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>androidx.lifecycle</groupId>
<artifactId>lifecycle-viewmodel</artifactId>
<version>2.6.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.8.22</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>androidx.lifecycle</groupId>
<artifactId>lifecycle-common</artifactId>
<version>2.6.1</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
However, it does not contain a link to the sources JAR for the artifact. Fortunately, Google
tended to use a consistent naming convention of $artifact-$version-sources.jar
. So, if I did not
already have the sources for that artifact version, I generated the URL for it
(e.g., https://dl.google.com/dl/android/maven2/androidx/activity/activity-compose/1.10.0-alpha03/activity-compose-1.10.0-alpha03-sources.jar
)
and downloaded it. Since JAR files are ZIP files, I could then use ordinary unZIP code to convert
the JAR into a directory tree of source code.
Step 3: Generate the Site
androidx.tech
was a static site, generated by Jekyll. Jekyll is Ruby code and is not designed
for a site of this size, with hundreds of thousands of pages. Still, given a big enough Amazon EC2 instance,
I could plow through it.
I had a separate Kotlin project, gen2
, that would generate the Markdown source for the site, given
the POM files and source trees. My publish
script would then set Jekyll loose to generate the
site, and from there it was a matter of rsync
to push the changes up to the actual host.
—Nov 10, 2024