Add an opt-in warning (Settings > Updates, off by default) shown when an
individual update's new version adds trackers, on both the Updates and Details
screens. Rework the Exodus privacy screen into a list of all analyzed versions
(newest tagged "Latest"); tapping a version opens a dialog listing its trackers
with categories rendered as chips.
Replace the bundled exodus_trackers.json asset with a Room-backed tracker
dictionary (exodus_tracker table) synced from the Exodus /api/trackers endpoint
every 3 days via a WorkManager job enqueued after session verification on the
splash screen. Per-app reports are still fetched live from the search API and
their tracker ids resolved to details from the local table (best-effort). Also
fixes Exodus report deserialization to read the snake_case version_code and
creation_date keys.
MainScreen is a top-level destination, but the shared TopAppBar defaults
to showing the navigation icon, so a stray back arrow appeared on the
Apps/Games/Updates bar. Opt out with showNavigationIcon = false.
The Compose migration routed every link through browse(), which uses
Custom Tabs and only handles http/https, so the UPI and crypto donation
entries did nothing. Open UPI via an ACTION_VIEW intent (new viewExternal
helper) and copy crypto addresses to the clipboard with a confirmation
toast, falling back to copy when no UPI app is installed.
Add a divider under the header in the add-account sheet, and give the
account actions sheet an avatar plus a divider so it's clear which
account an action applies to as more accounts are added.
Play endpoints identify the account through the Authorization header,
but several use a fixed URL and omit Vary: Authorization. With a shared
cache, one account's response (profile, app details, library, ...) could
be served to another. Tag authenticated responses with Vary: Authorization
so the cache keys by account, and move to a fresh cache directory to drop
any pre-fix entries.
Hide the anonymous account option when anonymous login is disabled
(e.g. Huawei), route Add Google through the microG account chooser
when microG is available, and reject picking an already-added account.
On Android 8 the search bar on SearchScreen and BlacklistScreen would
reopen by itself and never stay closed — after pressing back, after
submitting a query via the keyboard, and after returning from an app's
details page.
Root cause: the screens wrapped Material3's InputField in a custom focus
workaround (a shared FocusRequester + interactionSource re-requesting
focus), which fought the library. More fundamentally, the Material3
InputField expands the search bar whenever it regains focus, and on
Android 8 focus is restored to the collapsed field in many situations
(dismissing the focusable search popup/dialog, navigating back from
details), so it kept re-expanding.
Fix:
- Drop the redundant manual focus workaround and let the library manage
focus/expansion, matching the official Material3 sample. SearchScreen
keeps its open-on-entry behavior via
rememberSearchBarState(initialValue = Expanded).
- Gate the input field's focusability on the expanded state
(focusProperties { canFocus = targetValue == Expanded }). While
collapsed the field can't take focus, so nothing can auto-expand it;
tapping still expands via Material3's click detection and the expanded
popup/dialog focuses its own field for typing.
Verified on an Android 8 emulator for both screens: entry, keyboard
search, suggestion tap, details round-trip, re-tap, and back all behave.
fetchDataSafetyReport was the only fetch in AppDetailsViewModel whose
coroutine had no exception handling, so any failure inside
WebDataSafetyHelper.fetch crashed the whole app. This is easily
triggered: the helper currently throws a NullPointerException for apps
without data safety details (e.g. beta invites like
com.notacult.walkscape), and transient network errors have the same
effect.
Catch and log the exception like the sibling fetches do; the details
page already handles a null report by omitting the data safety section.
Fixes#1517, #1525
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>