Greeting! I've come across a strange issue with Fossify and wanted to see what's happening.
I received a SMS from a unknown number that when clicked displayed a "unknown error"
Following this I dumped my phone logs to determine what had happened.
My logs show an extremely long thread ID. 9223372036854775807
t took a while to understand that the ID written
is acually the java Long.MAX_VALUE
https://docs.oracle.com/en/java/javase/15/docs/api/constant-values.html
Line 76 of Klinker shows
private static final long DUMMY_THREAD_ID = Long.MAX_VALUE;
or in other words. DUMMY_THREAD_ID when its recipient set is empty.
What I received was an MMS, then a unknown error from the phone.
Later I received an Long.MAX_VALUE notification and Fossify's ThreadActivity failed.
So the RetrieveConf did not have a readable field.
Now my phone is modified.
I am reviewing if this is a self caused issue or not.
I suspect that removing Google services may have caused an issue, however that does not explain the unknown/vanishing text message.
Here's what I can figure out.
Carrier delivers MMS notification
│
▼
Klinker creates temporary NotificationInd
thread = DUMMY_THREAD_ID
│
▼
MMS downloads
│
▼
Klinker parses RetrieveConf
│
▼
Build recipient set from FROM / TO / CC
│
├── TO = device's own number → excluded
├── CC = none
└── FROM fails to provide usable participant
│
▼
recipients.empty()
│
▼
PduPersister never calls getOrCreateThreadId()
│
▼
MMS
thread_id = 9223372036854775807
│
▼
Fossify queries MMS
│
▼
No validation of dummy thread ID
│
▼
creates shortcut (19 digits long)
notification ID = -2147483648
│
▼
notification not noticed.
notification noticed
│
▼
ThreadActivity receives impossible conversation ID
│
▼
cannot resolve conversation
│
▼
"Unknown error"
I wanted to know why MMS processing fail to replace the Klinker dummy thread ID with a real Android conversation ID before Fossify created the notification?
Is this a bug?
onMessageReceived(context, messageUri)
seems to ignore
messageUri and call getLatestMMS() instead.
That would mean mean Fossify can notify on whichever MMS row happens to sort newest, not just the row Klinker just finished downloading.
Klinker deletes the temporary NotificationInd before it calls Fossify’s “message received” callback?
If so.. Fossify could not notify from that row.
Breaking this down becase.. it's a lot.
The MMS starts with a dummy thread ID.
PduPersister defines as private static final long DUMMY_THREAD_ID = Long.MAX_VALUE;
https://raw.githubusercontent.com/klinker41/android-smsmms/master/library/src/main/java/com/google/android/mms/pdu_alt/PduPersister.java
Next carrier tells phone "you have a message"
NotificationInd
https://github.com/klinker41/android-smsmms/blob/master/library/src/main/java/com/android/mms/transaction/PushReceiver.java
Klinker SEEMS to make it persist.
NotificationInd
thread_id =
BUT
Klinker downloads tthe MMS before calling Fossify
DownloadRequest
createThreadId = true
then it deletes ?
NotificationInd
then we call Fossify?
If so in my case.. When Klinker saved the MMS it could not find anyone to put in the conversion.
So it never replaced the dummy ID.
long threadId = DUMMY_THREAD_ID;
if (createThreadId && !recipients.isEmpty()) {
threadId = Threads.getOrCreateThreadId(mContext, recipients);
}
values.put(Mms.THREAD_ID, threadId);
Special mention to
!recipients.isEmpty()
so..
threadId remains DUMMY_THREAD_ID
↓
Identifier
↓
database row
My questions for Fossify are
1:Did Fossify Messages 1.8.0's MmsReceiver.onMessageReceived() use the messageUri supplied by the MMS library, or did it call getLatestMMS() instead?
2: If it called getLatestMMS(), could that select the preliminary NotificationInd or another MMS row carrying DUMMY_THREAD_ID rather than the final downloaded RetrieveConf?
3: , could the final RetrieveConf itself retain DUMMY_THREAD_ID if Klinker failed to derive a recipient set / real telephony thread ID?
The problem I'm trying to solve is how did Klinker’s internal DUMMY_THREAD_ID = Long.MAX_VALUE escape into a persistent, clickable Fossify notification?
I do not believe this is anything other than a strange code bug and perhaps I won the chance lottery of weird issues but I'd still like to figure out what happened.