https://bugs.kde.org/show_bug.cgi?id=523424
Sébastien Beausoleil <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] Ever confirmed|0 |1 Status|REPORTED |CONFIRMED --- Comment #1 from Sébastien Beausoleil <[email protected]> --- Root cause for this symptom, with a reproducer and a workaround. I can't confirm it is the original reporter's cause (their Android version isn't stated), but it produces exactly this behaviour and the fix is on our side either way. **Environment:** GrapheneOS (Android 17, build 2026081301) on a Pixel 8, KDE Connect Android 1.35.13 (`targetSdk=37`), desktop KDE Connect 25.12.3 on Kubuntu 26.04. **Cause.** Android 17 stamps a `restricted` column on rows in the SMS provider. A row written by an app that does not hold `android.app.role.SMS` gets `restricted=1`, and `SmsProvider` then filters those rows out of that app's own reads unless it holds the `READ_RESTRICTED_MESSAGES` appop, which defaults to `ignore`. The consequence is circular: **KDE Connect cannot read back the message it just wrote itself.** Since the desktop displays only what it can re-read from the provider, the reply is invisible there while being genuinely sent and plainly present in the phone's own messaging app. **Reproducer.** Send yourself an SMS from the desktop. The message lands twice in the provider, once as `type=2` (sent, written by KDE Connect) and once as `type=1` (received, written by the default SMS app). Only the received copy reaches the desktop, seconds later — proving the link is healthy and that exactly one row is being withheld: id: 438 type: 2 sent creator: org.kde.kdeconnect_tp restricted: 1 reaches destop: no id: 439 type: 1 received creator: com.android.messaging restricted: 2 reaches destop: yes Both rows share the same `thread_id` and address. In this database every `restricted=1` row — 18 of them — had `creator=org.kde.kdeconnect_tp` and `type=2`; no other row was marked. `logcat` while the desktop requests the thread: ``` V/SmsProvider: checkQueryForForbiddenColumns checking sel: date <= ? AND thread_id = ? V/SmsProvider: canReadRestrictedMessages=false V/MmsProvider: accessRestricted=true ``` **Confirmation.** Granting the appop flips that to `canReadRestrictedMessages=true`, and every previously hidden message reappears, including two weeks of history: ``` adb shell appops set --uid org.kde.kdeconnect_tp READ_RESTRICTED_MESSAGES allow adb shell am force-stop org.kde.kdeconnect_tp ``` UID mode is required — package mode leaves the provider refusing. A restart is also required, as the app caches the decision. **Worth noting:** KDE Connect's `WRITE_SMS` appop is `ignore` (rejected), yet the row exists under its name — the platform wrote it on the app's behalf during the send. The system knows the message genuinely went out over its own telephony stack, and marks it untrusted regardless. The flag tracks *who wrote the row*, not direction: in this database 172 outgoing messages written by the Messaging app are unmarked, against 18 written by KDE Connect that are. **Suggested fix.** The appop is a local workaround, not a solution; it can't be granted from within the app. The durable fix is for the Android side to stop depending on a provider read-back it is not entitled to: when a send succeeds, emit that message to the desktop directly from what was just sent, rather than waiting to observe it reappear in the provider. That also removes a race that exists on every Android version, since the read-back is inherently asynchronous. If maintainers prefer, the platform behaviour could additionally be raised with AOSP/GrapheneOS — an app arguably ought to be able to read rows for which it is itself the `creator` — but that would not help existing installs. -- You are receiving this mail because: You are watching all bug changes.
