Status Update
Comments
al...@google.com <al...@google.com> #2
al...@google.com <al...@google.com> #3
Great! Thanks a lot, I'll look for the live updates soon!
al...@google.com <al...@google.com>
al...@google.com <al...@google.com> #4
(1) in public.txt
output from MergeResources
task, but I'm not confident that would map to "all resources are public by default".
+cc'ing Izabela who might know how to get at this information from within a Gradle plugin.
We could also skip (1) and implement (2) by forcing all libraries to include a resource XML with a single <public />
element.
im...@google.com <im...@google.com> #5
I agree that "no public tag means everything is public" is a nuisance, and gave us a lot of hassle when implementing the conversion of AARs to namespaced ones (which as you know are very strict with res visibility). While we can't change that behaviour for backwards compatibility, we could propose changing to always generating public.txt (filled with *all* local resources if no public tags were defined) - It would increase the AAR size, but it's probably negligible.
For now, you should be able to consume the public.txt from MergeResources (the "PACKAGE" one, since in libraries you will have two MergeResources tasks, the other one being "MERGE"), by extra gradle Task that sees if the file exists - if it doesn't then fail and say "you don't have a <public> tag defined, if you need all resources to be public you need to list them all" or whatever matches your case.
I think Chris has done a lot of work around the APIs recently, and added a public API for getting the public.txt in GenerateApiPublicTxtTask and the artifact ArtifactType.PUBLIC_ANDROID_RESOURCES_LIST. However, this one's behaviour is different, meaning that if there were no <public> tags, it will generate the public.txt will *all* symbols (instead of not writing it). The one matching the AAR's public.txt would be InternalArtifactType.PUBLIC_RES but that one is our internal artifact.
al...@google.com <al...@google.com> #6
if it doesn't then fail and say "you don't have a <public> tag defined, if you need all resources to be public you need to list them all" or whatever matches your case.
I was hoping to avoid this for libraries that don't have any resources defined.
However, this one's behaviour is different, meaning that if there were no <public> tags, it will generate the public.txt will all symbols (instead of not writing it).
I could correlate between the two -- if the AAR does not have a public.txt
but GenerateApiPublicTxtTask
has a non-empty public.txt
then the developer has added resources but no explicit <public />
.
Which feels hacky. I think we'll just force every library to have a single <public />
element by default. One less thing for developers to think about.
al...@google.com <al...@google.com> #7
Forcing every library to have a <public />
element ended up being a bit hacky as well since some libraries were already correct and the build will fail if you define <public />
twice. I ended up removing all the existing <public />
definitions in aosp/1546636.
ap...@google.com <ap...@google.com> #8
Branch: androidx-main
commit 721ee0257e22d51a901eab77d8ba07112b608d55
Author: Alan Viverette <alanv@google.com>
Date: Mon Jan 11 10:55:42 2021
Always define public resources
Relnote: "Resources in libraries with no explicily declared public resources
(ex. via public.xml) are now private by default."
Fixes: 170882230
Test: ./gradlew checkResourceApi
Change-Id: Ia1dcca1ad5c65c1ab90b97c22589e7392161fd62
A buildSrc/res/values/public.xml
M buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
M buildSrc/src/main/kotlin/androidx/build/resources/GenerateResourceApiTask.kt
A buildSrc/src/main/kotlin/androidx/build/resources/PublicResourcesStubHelper.kt
M camera/camera-camera2/src/main/res/values/public.xml
M camera/camera-core/src/main/res/values/public.xml
M compose/ui/ui/src/androidMain/res/values/public.xml
M fragment/fragment/src/main/res/values/public.xml
Description
Our resource API tracking inverts the behavior of AGP by treating the "no public element" case as "all resources are private" when in fact it indicates the legacy "all resources are public" behavior.
The correct way to declare "no public elements" is to define a single
<public />
element.Unclear how we're going to handle this for existing libraries where all resources are currently considered public but have never been tracked.