apsun / NekoSMS

A pattern-based text message blocker for Android.
GNU General Public License v3.0
417 stars 44 forks source link

Fix SMS restoration on android 14 #100

Closed NekoGirlSAIKOU closed 2 months ago

NekoGirlSAIKOU commented 2 months ago

Fix #99

apsun commented 2 months ago

Thanks for the PR! Do you have a reference (code link, etc) for why this causes restoring to fail? I'd like to link to that for posterity

Based on my reading of the code, 0 should be a valid subscription ID as far as I can tell https://android.googlesource.com/platform/frameworks/base/+/HEAD/telephony/java/android/telephony/SubscriptionManager.java#151

NekoGirlSAIKOU commented 2 months ago

According to #89, the subId stored in NekoSMS database is all 0 since Android 11. According to his screenshot, the SMS App don't recognize related SIM card for restored SMS with subId 0. So 0 may be an invalid subId. While debugging this bug, because of E TelephonyPermissions: Subscription[Subscription ID:0] has no records on device in logs, I tried not to restore the subId and found the problem solved.

不太擅长英语写作,表达不太清楚。还是用中文重新写一遍好了。。。根据 #89 这个PR在Android 11之后NekoSMS记录的拦截的短信的subId全部都是0。而且根据他的截图,subId为0的短信还原后,在短信App中还是无法正确的识别出对应的SIM卡,所以我觉着0可能是无效的subId。而且我在我的手机上调试时,尝试还原短信的时候系统报了E TelephonyPermissions: Subscription[Subscription ID:0] has no records on device 这个错误,所以我就只管试着在subId为0时不还原subId试试,结果就可以正常还原短信了。我猜为0的subId可能本身是合法的,但是因为我的手机上的SIM卡的subId都不为0,所以还原短信时系统找不到对应的SIM卡,Android 14之前可能找不到的话就忽略了,Android 14可能更严格改为报错了(虽然大致看了下Android 14的行为变更也没找到相关的变更...)。当时没想那么多(我当时以为0是完全无效的subId...),也许更正确的修复方式是检查下是否有与subId对应为的SIM卡来决定是否还原这一项?最根本的解决方式应该是合并 #89,不过对于subId为0的旧记录应该还是要额外处理下。

NekoGirlSAIKOU commented 2 months ago

According to 1f2ea35267441816042e63ae0bbe5aa73cfa3f78, it seems that Android no longer allow subId without records. Since no subId of SIM card on my phone (and maybe many others) is 0, Android don't allow restoring such SMS.

翻了下LineageOS 21.0(Android 14)的代码(不知道怎么在android.googlesource.com上进行搜索...而且我用的ROM是基于LineageOS的所以先看了这个)这个报错是TelephonyPermissions中的checkSubscriptionAssociatedWithUser这个方法输出的,并且在LineageOS 20.0(Android 13)的TelephonyPermissions.java中没有这个方法。最后可能是因为在LineageOS 21.0的SmsProvider.java中的insertInner方法里调用了checkSubscriptionAssociatedWithUser方法进行检查,然后因为检查没通过于是没有把短信写入数据库。

在AOSP的android14-release分支的TelephonyPermissions.java中的checkSubscriptionAssociatedWithUser这个方法的注释是false if user is not associated with the subscription.但是在main分支中注释变成了false if user is not associated with the subscription, or no record found of this subscription. 这个改动是在1f2ea35267441816042e63ae0bbe5aa73cfa3f78这个commit加入的。总之看起来和我前面猜的差不多,对于手机上没有记录的subId直接报错了。

apsun commented 2 months ago

Ok, I think I understand now. Any subId which is invalid will fail (not just 0), but SmsMessageUtils#getSubId was broken and always returning 0, and so now messages in our database have an invalid subId value

Although I guess that's not the only source of subId == 0; https://github.com/apsun/NekoSMS/blob/master/app/src/main/java/com/crossbowffs/nekosms/provider/DatabaseHelper.java#L132 also initializes it to 0 if upgrading from an older app version without multi-SIM support

I missed #89 (sorry!), will take a look at that. As a workaround for the bad values in our database though, I think this PR is a fair mitigation (other option would be to retry rejected insert without the subId value). Thank you!

apsun commented 2 months ago

Figured it out, getSubId is useless as of https://android-review.googlesource.com/c/platform/frameworks/base/+/1196441, the field is never initialized so we always get 0

apsun commented 2 months ago

Could you give this build a try and report back if restore still works? It changes the default value from 0 to -1 and updates the existing values in the db. Unfortunately it's not possible to tell whether 0 was an actual value so it throws away the subId information for existing messages.

NekoSMS-0.23.0-dev.zip

NekoGirlSAIKOU commented 2 months ago

It works for old messages. But new messages still can't be restored. Their subId is still 0.

NekoGirlSAIKOU commented 2 months ago

It works for old messages. But new messages still can't be restored. Their subId is still 0.

It works well. I forgot to reboot my phone...

apsun commented 2 months ago

It works for old messages. But new messages still can't be restored. Their subId is still 0.

It works well. I forgot to reboot my phone...

Ah, yeah... I should bump the module version too. It's been a while since I touched it :sweat_smile: