Skip to content

fix: persist ignored-version lock so updates are suppressed#1351

Open
Phoenix1808 wants to merge 1 commit into
Droid-ify:mainfrom
Phoenix1808:fix/ignored-version-lock
Open

fix: persist ignored-version lock so updates are suppressed#1351
Phoenix1808 wants to merge 1 commit into
Droid-ify:mainfrom
Phoenix1808:fix/ignored-version-lock

Conversation

@Phoenix1808

Copy link
Copy Markdown

Fix: "Ignore this version" does not take effect until app restart

Fixes #1309

Problem

Toggling "Ignore this version" correctly changed the action button to Launch, but the app continued to:

  • Appear in the Updates tab

  • Trigger update available notifications

The ignore action only took effect after a full application restart.


Root Cause

ProductPreferences performs two separate operations when an ignored version is toggled:

  1. Stores the preference in SharedPreferences

  2. Signals the database layer to write a corresponding entry into the lock table

The lock table is the source of truth used by:

  • Update queries

  • Update notifications

  • Updatable version detection

The signal is sent through a MutableSharedFlow configured with no replay and no buffer:

private val mutableSubject = MutableSharedFlow<Pair<String, Long?>>()
// replay = 0, extraBufferCapacity = 0

The preference update uses:

tryEmit(...)

Because the flow has:

replay = 0
extraBufferCapacity = 0

tryEmit() silently drops emissions whenever no collector is actively ready to receive the value at that exact moment.

As a result:

  • The SharedPreferences value was saved successfully.

  • The corresponding lock table entry was never written.

  • The Updates screen continued treating the version as updatable.

  • Update notifications continued to appear.

The bug appeared intermittent because the application rebuilt the entire lock table during startup:

init()

During initialization, ignored versions were reconstructed from SharedPreferences, causing the issue to seemingly fix itself after restarting the app.


Fix

Configure the flow with buffering so tryEmit() cannot lose events.

private val mutableSubject = MutableSharedFlow<Pair<String, Long?>>(
    extraBufferCapacity = Int.MAX_VALUE,
)

This preserves the existing architecture:

  • Database writes remain off the main thread.

  • Background collectors continue handling persistence.

  • Ignore events are guaranteed to be delivered.

Additionally, the lock write now invokes:

notifyChanged(...)

This immediately refreshes the Updates UI, causing ignored versions to disappear without requiring:

  • Manual sync

  • App restart

  • Process recreation


Before / After

Before After
image image
Ignored version still shows in Updates Toggled ignore → gone instantly (no sync/restart)

Testing

Device Testing

Built and installed the debug variant on a physical Android device.

Test Steps

  1. Installed an older version of an application so an update was available.

  2. Opened the update screen.

  3. Toggled Ignore this version.

  4. Verified the application disappeared from the Updates tab immediately.

  5. Verified no update notification was generated.

  6. Toggled ignore off again.

  7. Verified the update reappeared as expected.

Result

✅ Ignored versions disappear instantly from Updates.

✅ No restart required.

✅ No manual synchronization required.

✅ Un-ignore restores update visibility correctly.


Impact

This change ensures that:

  • Ignore-version actions are applied immediately.

  • Update notifications remain consistent with user preferences.

  • Lost flow emissions no longer create stale lock-table state.

  • UI and database state remain synchronized without requiring an application restart.

ProductPreferences emitted lock changes through a MutableSharedFlow with no
buffer (replay = 0, extraBufferCapacity = 0), so tryEmit() silently dropped
the event when the collector was not ready. The SharedPreferences entry was
saved, but the matching row in the lock table was never written, so the
Updates tab and update notifications kept treating the ignored version as
updatable until the next app restart rebuilt the lock table.

Give the flow an unbounded buffer so tryEmit() never drops the event and the
lock is written reliably.

Fixes Droid-ify#1309
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] "Ignore this version" toggle does not work correctly

1 participant