Problem
#4699 discards oversized remote non-file pastes at receive time instead of storing them. The pull cursor in PastePullService is only advanced in memory: after a restart, init() rebuilds each device's cursor from the max createTime of stored pastes, which by definition never includes a discarded paste.
So when the newest paste from a peer device is one that was discarded for being oversized, every restart re-pulls that same paste, re-discards it, and shows the warning notification again — repeatedly transferring tens of MB for nothing until the peer produces a newer paste that gets stored.
Fix
Persist a durable per-device pull cursor:
- New
PastePullCursorEntity(appInstanceId PK, maxCreateTime) table + SQLDelight migration 3.sqm (idempotent CREATE TABLE IF NOT EXISTS, consistent with the migration-replay behavior of DesktopDriverFactory).
- When a remote oversized paste is discarded, upsert the cursor with its
createTime; the SQL upsert takes MAX(existing, new) so the cursor is monotonic.
PastePullService.init() restores each device's cursor as the max of the stored-paste max createTime and the durable cursor.
- Device removal (local unpair and remote
NOTIFY_REMOVE, both converging on SyncDeviceManager.removeDevice) deletes the device's cursor row along with the other local state.
Problem
#4699 discards oversized remote non-file pastes at receive time instead of storing them. The pull cursor in
PastePullServiceis only advanced in memory: after a restart,init()rebuilds each device's cursor from the maxcreateTimeof stored pastes, which by definition never includes a discarded paste.So when the newest paste from a peer device is one that was discarded for being oversized, every restart re-pulls that same paste, re-discards it, and shows the warning notification again — repeatedly transferring tens of MB for nothing until the peer produces a newer paste that gets stored.
Fix
Persist a durable per-device pull cursor:
PastePullCursorEntity(appInstanceId PK, maxCreateTime)table + SQLDelight migration3.sqm(idempotentCREATE TABLE IF NOT EXISTS, consistent with the migration-replay behavior ofDesktopDriverFactory).createTime; the SQL upsert takesMAX(existing, new)so the cursor is monotonic.PastePullService.init()restores each device's cursor as the max of the stored-paste maxcreateTimeand the durable cursor.NOTIFY_REMOVE, both converging onSyncDeviceManager.removeDevice) deletes the device's cursor row along with the other local state.