diff --git a/apkGen.pl b/apkGen.pl index 4abab0d2..2c15f882 100644 --- a/apkGen.pl +++ b/apkGen.pl @@ -15,8 +15,10 @@ sub cmd($){ } } +cmd "./gradlew --stop"; cmd "./gradlew clean"; cmd "./gradlew assembleNoFcmRelease"; cmd "./gradlew assembleFcmRelease"; +cmd "./gradlew --stop"; cmd "mv app/build/outputs/apk/SubwayTooter*.apk app/"; cmd " ls -1t app/SubwayTooter*.apk |head -n 5"; diff --git a/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppDataExporter.kt b/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppDataExporter.kt index 285b877a..a26c6271 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppDataExporter.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppDataExporter.kt @@ -182,6 +182,7 @@ object AppDataExporter { cv.clear() reader.beginObject() + val keys = ArrayList() while (reader.hasNext()) { val name = reader.nextName() if (name == null) { @@ -205,6 +206,7 @@ object AppDataExporter { "last_notification_error", "last_subscription_error", "last_push_endpoint", + "sound_uri", -> { reader.skipValue() continue @@ -217,20 +219,35 @@ object AppDataExporter { JsonToken.NULL -> { reader.skipValue() cv.putNull(name) + keys.add(name) } - JsonToken.BOOLEAN -> cv.put(name, if (reader.nextBoolean()) 1 else 0) + JsonToken.BOOLEAN -> { + cv.put(name, if (reader.nextBoolean()) 1 else 0) + keys.add(name) + } - JsonToken.NUMBER -> cv.put(name, reader.nextLong()) + JsonToken.NUMBER -> { + cv.put(name, reader.nextLong()) + keys.add(name) + } - JsonToken.STRING -> cv.put(name, reader.nextString()) + JsonToken.STRING -> { + cv.put(name, reader.nextString()) + keys.add(name) + } - else -> reader.skipValue() + else -> { + reader.skipValue() + log.w("skip $table.$name") + } } } reader.endObject() val new_id = db.replace(table, null, cv) - if (new_id == -1L) error("importTable: invalid row_id") + if (new_id == -1L) { + error("importTable: replace failed. table=$table, names=${keys.joinToString(",")}") + } idMap?.put(old_id, new_id) } reader.endArray() diff --git a/app/src/main/java/jp/juggler/subwaytooter/push/PushMastodon.kt b/app/src/main/java/jp/juggler/subwaytooter/push/PushMastodon.kt index def8ed12..910cb4e2 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/push/PushMastodon.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/push/PushMastodon.kt @@ -18,6 +18,7 @@ import jp.juggler.util.data.* import jp.juggler.util.log.LogCategory import jp.juggler.util.time.parseTimeIso8601 import kotlinx.coroutines.isActive +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import java.security.Provider import java.security.SecureRandom import java.security.interfaces.ECPublicKey @@ -88,11 +89,16 @@ class PushMastodon( } } } - if (params["dh"] != deviceHash) { + if (params["dh"] != deviceHash && !isOldSubscription(account, oldEndpointUrl)) { + // この端末で作成した購読ではない。 // TODO: 古い形式のURLを移行できないか? log.w("deviceHash not match. keep it for other devices. ${account.acct} $oldEndpointUrl") subLog.e(R.string.push_subscription_exists_but_not_created_by_this_device) + daoAccountNotificationStatus.updateSubscriptionError( + account.acct, + context.getString(R.string.push_subscription_exists_but_not_created_by_this_device) + ) return } } @@ -175,6 +181,22 @@ class PushMastodon( } } + private fun isOldSubscription(account: SavedAccount, url: String): Boolean { + // https://mastodon-msg.juggler.jp + // /webpushcallback + // /{ deviceId(FCM token) } + // /{ acct } + // /{flags } + // /{ client identifier} + + val clientIdentifierOld = url.toHttpUrlOrNull()?.pathSegments?.elementAtOrNull(4) + ?: return false + val installId = prefDevice.installIdV1?.notEmpty() ?: return false + val accessToken = account.bearerAccessToken?.notEmpty() ?: return false + val clientIdentifier = "$accessToken$installId".digestSHA256Base64Url() + return clientIdentifier == clientIdentifierOld + } + private suspend fun isSameAlerts( subLog: SubscriptionLogger, account: SavedAccount, @@ -362,7 +384,7 @@ class PushMastodon( // - notification.user のfull acct がないのでふぁぼ魔ミュートは行えない // - テキスト本文のミュートは…部分的には可能 - if(pm.textExpand?.let{TootStatus.muted_word?.matchShort(it)}==true){ + if (pm.textExpand?.let { TootStatus.muted_word?.matchShort(it) } == true) { error("muted by text word.") } diff --git a/app/src/main/java/jp/juggler/subwaytooter/push/PushMisskey.kt b/app/src/main/java/jp/juggler/subwaytooter/push/PushMisskey.kt index d7b24b03..8f4db2d0 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/push/PushMisskey.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/push/PushMisskey.kt @@ -18,6 +18,7 @@ import jp.juggler.subwaytooter.pref.prefDevice import jp.juggler.subwaytooter.table.* import jp.juggler.util.data.* import jp.juggler.util.log.LogCategory +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import java.security.Provider import java.security.SecureRandom import java.security.interfaces.ECPublicKey @@ -99,6 +100,10 @@ class PushMisskey( subLog.i(R.string.push_subscription_app_server_hash_missing_but_ok) } else { subLog.e(R.string.push_subscription_app_server_hash_missing_error) + daoAccountNotificationStatus.updateSubscriptionError( + account.acct, + context.getString(R.string.push_subscription_app_server_hash_missing_error) + ) } return } else if (willRemoveSubscription) { @@ -160,6 +165,22 @@ class PushMisskey( subLog.i(R.string.push_subscription_completed) } + private fun isOldSubscription(account: SavedAccount, url: String): Boolean { + // https://mastodon-msg.juggler.jp + // /webpushcallback + // /{ deviceId(FCM token) } + // /{ acct } + // /{flags } + // /{ client identifier} + + val clientIdentifierOld = url.toHttpUrlOrNull()?.pathSegments?.elementAtOrNull(4) + ?: return false + val installId = prefDevice.installIdV1?.notEmpty() ?: return false + val accessToken = account.misskeyApiToken?.notEmpty() ?: return false + val clientIdentifier = "$accessToken$installId".digestSHA256Base64Url() + return clientIdentifier == clientIdentifierOld + } + /* https://github.com/syuilo/misskey/blob/master/src/services/create-notification.ts#L46 Misskeyは通知に既読の概念があり、イベント発生後2秒たっても未読の時だけプッシュ通知が発生する。 diff --git a/app/src/main/java/jp/juggler/subwaytooter/push/PushRepo.kt b/app/src/main/java/jp/juggler/subwaytooter/push/PushRepo.kt index b695f3c8..b143470c 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/push/PushRepo.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/push/PushRepo.kt @@ -357,6 +357,10 @@ class PushRepo( ) } catch (ex: Throwable) { subLog.e(ex, "updateSubscription failed.") + daoAccountNotificationStatus.updateSubscriptionError( + account.acct, + ex.withCaption() + ) } } prefDevice.timeLastEndpointRegister = System.currentTimeMillis()