LinkSheet [1] can do that. It's a small app that you set as the default browser and shows a prompt when you open a link to allow you to choose what to do (eg. open in browser, open in app, share link, remove tracking URL parameters, etc.).
If you don't care about any of the extra functionality, you can configure it to always open your preferred browser and convert Custom Tabs intents to regular ones. No root access required.
Per [1], I've also enabled MTE for user applications via the `persist.arm64.memtag.app_default` property. So far, the only crashes I've seen have been in apps that use cgo (eg. syncthing and rclone).
With root access, things can be persistently whitelisted on a per-app basis [2]:
su -c 'setprop persist.arm64.memtag.app.<package name> off'
or based on basename(argv[0]) [3]:
su -c 'setprop persist.device_config.memory_safety_native.mode_override.process.<basename> off'
Wonderful tool! I started using it since 0.6 because sbsigntools and pesign both choked on some EFI executables I had, but sbctl's go-uefi parser did not. It also seems to handle enrolling PK/KEK/db/dbx a lot more reliably than sbkeysync (which used to ignore errors and exit(0)) and efivar.
Yep, what you're referring to (the "Powered by <browser>" screen) is done with the Custom Tabs API. Some folks might also refer to it as the in-app browser. Any browser can implement a CustomTabsService and the whole feature respects the default browser setting.
The Fastmail app is actually a good example of something that uses the WebView APIs though. Fastmail's UI is entirely web-based and their whole app is rendered inside of a WebView, provided by the Chromium-based "Android System WebView" app. If I remember correctly, the list of allowed signatures for a WebView provider is baked into the OS, so no third party can provide an implementation without root access.
What I don't understand is the use case for data descriptors. If the entire file is available, then the central directory is sufficient. If the file is being streamed, then there's no way to know with certainty where the data descriptor is, especially for a scenario like an uncompressed zip stored within a zip.
I suppose a parser could try to compare the CRC and uncompressed size fields every time it encounters the data descriptor magic bytes until it finds one that matches, but the magic bytes aren't even mandatory. The data descriptor can just be CRC + compressed size + uncompressed size with no marker.
From basic testing, `unzip`, libarchive/bsdtar, and the Python zipfile module all choke on files like this when read from a stream (as expected).
Why were data descriptors ever included in the spec?
Looking at AOSP, the logic that allows something like Play Protect to work is at [1]. It looks for system apps that can handle the ACTION_PACKAGE_NEEDS_VERIFICATION intent, which is the Play Store app in this case. Looking at the Play Store's AndroidManifest.xml, the PackageVerificationReceiver component is what listens for that intent.
With root access, it should be possible to disable just that component without breaking other functionality by running:
EDIT: For folks with rooted devices, all alerts can be disabled with:
adb shell su -c 'pm disable com.google.android.cellbroadcastreceiver'
and reenabled with:
adb shell su -c 'pm enable com.google.android.cellbroadcastreceiver'
For folks on custom Android builds (or older stock Android builds without APEX module support), the package name is `com.android.cellbroadcastreceiver` (without the `.google`).
I don't know the details of what happened between the two projects, but according to Wikipedia [1], libav was abandoned a bit over 5 years ago. Looks like their website (and main git repo) no longer exist.
If you don't care about any of the extra functionality, you can configure it to always open your preferred browser and convert Custom Tabs intents to regular ones. No root access required.
[1] https://github.com/1fexd/LinkSheet