handle androidx DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION hack
In fdroidserver!1336 (closed), @zx2c4 said:
context.registerReceiver()
has had various behaviors and flags over different API releases, and androidx'sContextCompat
attempts to unify its behavior to match that of API 33.Before API 33,
registerReceiver()
took the name of a signature-level permission to gate whether intents could be sent to dynamically registered broadcast intent receivers. If no permission was specified, it was exported to the world.In API 33,
registerReceiver()
's flag argument gained explicitRECEIVER_EXPORTED
andRECEIVER_NOT_EXPORTED
controls. The use ofRECEIVER_NOT_EXPORTED
with no specified signature-level permissions means that the application intends to only send intents to itself, and reject them from elsewhere.In order to emulate API 33's
RECEIVER_NOT_EXPORTED
flag on older APIs, androidx'sContextCompat
makes use of the fact that a signature-level permission that no other app uses amounts to the same thing as being not exported. So, AAPT merges into the manifest:
<permission android:name="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/>
And then, on the older APIs, passes
${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION
toregisterReceiver()
's permission argument whenRECEIVER_NOT_EXPORTED
is specified.This technique appears to work. But it has the downside that manifests built from androidx API 33 projects declare this additional arbitrary uses-permission, which looks a bit odd in F-Droid, since it's basically just an internal hack, rather than a real permission.
At this point, this also makes me think that fdroidclient should stop checking the permissions list. That code was added back when runtime permissions did not exist yet, and it was standard practice to compare the permissions of the installed APK to the new APK in order to prompt the user about new requests. Indeed, I believe the code we took from AOSP did that. We considered removing that permissions check when runtime permissions were added, but it was not clear yet how to handle that. Ideally, we would have info on what Google Play checks in terms of permissions when upgrading an app. Plus it would be great to isolate F-Droid things from these permissions hacks from AOSP and androidx as much as possible. They have been a source of pain on each new release for a while now.
@cde @grote this seems related to the whole basic targetSdkVersion
work. If it is possible to drop the permissions comparison, then that means there is one less thing that external (e.g AOSP) updates break that has to be tracked and maintained.