diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3ce270cab4..424e970ced 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -78,7 +78,7 @@ wire { } ktlint { - version.set("1.2.1") + version.set("1.5.0") } android { diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt index b88e44e316..1b78accc12 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt @@ -162,7 +162,9 @@ class DatabaseAttachment : Attachment { override fun equals(other: Any?): Boolean { return other != null && - other is DatabaseAttachment && other.attachmentId == attachmentId && other.uri == uri + other is DatabaseAttachment && + other.attachmentId == attachmentId && + other.uri == uri } override fun hashCode(): Int { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/SystemEmojiDrawable.kt b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/SystemEmojiDrawable.kt index d4a5b43116..3186562d4b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/emoji/SystemEmojiDrawable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/emoji/SystemEmojiDrawable.kt @@ -48,22 +48,19 @@ class SystemEmojiDrawable(emoji: CharSequence) : Drawable() { companion object { private val textPaint: TextPaint = TextPaint() - private fun getStaticLayout(emoji: CharSequence): StaticLayout = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - StaticLayout.Builder.obtain(emoji, 0, emoji.length, textPaint, Int.MAX_VALUE).build() - } else { - @Suppress("DEPRECATION") - StaticLayout(emoji, textPaint, Int.MAX_VALUE, Layout.Alignment.ALIGN_NORMAL, 0f, 0f, true) - } + private fun getStaticLayout(emoji: CharSequence): StaticLayout = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + StaticLayout.Builder.obtain(emoji, 0, emoji.length, textPaint, Int.MAX_VALUE).build() + } else { + @Suppress("DEPRECATION") + StaticLayout(emoji, textPaint, Int.MAX_VALUE, Layout.Alignment.ALIGN_NORMAL, 0f, 0f, true) + } - private fun getProcessedEmoji(emoji: CharSequence): CharSequence = - try { - EmojiCompat.get().process(emoji) ?: emoji - } catch (e: IllegalStateException) { - emoji - } + private fun getProcessedEmoji(emoji: CharSequence): CharSequence = try { + EmojiCompat.get().process(emoji) ?: emoji + } catch (e: IllegalStateException) { + emoji + } - private fun StaticLayout.getBounds(): RectF = - RectF(getLineLeft(0), 0f, getLineRight(0), getLineDescent(0) - getLineAscent(0).toFloat()) + private fun StaticLayout.getBounds(): RectF = RectF(getLineLeft(0), 0f, getLineRight(0), getLineDescent(0) - getLineAscent(0).toFloat()) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsText.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsText.kt index b986d62592..80dacb102c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsText.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsText.kt @@ -36,14 +36,11 @@ sealed class DSLSettingsText { } companion object { - fun from(@StringRes stringId: Int, @ColorInt textColor: Int): DSLSettingsText = - FromResource(stringId, listOf(ColorModifier(textColor))) + fun from(@StringRes stringId: Int, @ColorInt textColor: Int): DSLSettingsText = FromResource(stringId, listOf(ColorModifier(textColor))) - fun from(@StringRes stringId: Int, vararg modifiers: Modifier): DSLSettingsText = - FromResource(stringId, modifiers.toList()) + fun from(@StringRes stringId: Int, vararg modifiers: Modifier): DSLSettingsText = FromResource(stringId, modifiers.toList()) - fun from(charSequence: CharSequence, vararg modifiers: Modifier): DSLSettingsText = - FromCharSequence(charSequence, modifiers.toList()) + fun from(charSequence: CharSequence, vararg modifiers: Modifier): DSLSettingsText = FromCharSequence(charSequence, modifiers.toList()) } interface Modifier { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/BackupStateObserver.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/BackupStateObserver.kt index b38bdfa241..aa33a77faf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/BackupStateObserver.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/backups/BackupStateObserver.kt @@ -267,7 +267,8 @@ class BackupStateObserver( Log.d(TAG, "[getNetworkBackupState][subscriptionStateMismatchDetected] No purchase found in Google Play Billing: $purchaseResult") false } - } || SignalStore.backup.backupTierInternalOverride == MessageBackupTier.PAID + } || + SignalStore.backup.backupTierInternalOverride == MessageBackupTier.PAID Log.d(TAG, "[getNetworkBackupState][subscriptionStateMismatchDetected] googlePlayBillingSubscriptionIsActiveAndWillRenew: $googlePlayBillingSubscriptionIsActiveAndWillRenew") diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt index d6efb24309..df410cc6fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt @@ -75,32 +75,31 @@ class ChangeNumberRepository( return accountManager.whoAmI } - suspend fun ensureDecryptionsDrained(timeout: Duration = 15.seconds) = - withTimeoutOrNull(timeout) { - suspendCancellableCoroutine { - val drainedListener = object : Runnable { - override fun run() { - AppDependencies - .incomingMessageObserver - .removeDecryptionDrainedListener(this) - Log.d(TAG, "Decryptions drained.") - it.resume(true) - } - } - - it.invokeOnCancellation { cancellationCause -> + suspend fun ensureDecryptionsDrained(timeout: Duration = 15.seconds) = withTimeoutOrNull(timeout) { + suspendCancellableCoroutine { + val drainedListener = object : Runnable { + override fun run() { AppDependencies .incomingMessageObserver - .removeDecryptionDrainedListener(drainedListener) - Log.d(TAG, "Decryptions draining canceled.", cancellationCause) + .removeDecryptionDrainedListener(this) + Log.d(TAG, "Decryptions drained.") + it.resume(true) } + } + it.invokeOnCancellation { cancellationCause -> AppDependencies .incomingMessageObserver - .addDecryptionDrainedListener(drainedListener) - Log.d(TAG, "Waiting for decryption drain.") + .removeDecryptionDrainedListener(drainedListener) + Log.d(TAG, "Decryptions draining canceled.", cancellationCause) } + + AppDependencies + .incomingMessageObserver + .addDecryptionDrainedListener(drainedListener) + Log.d(TAG, "Waiting for decryption drain.") } + } @WorkerThread fun changeLocalNumber(e164: String, pni: ServiceId.PNI) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt index 4574db37fe..de58b874fc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt @@ -140,11 +140,12 @@ class NotificationsSettingsViewModel(private val sharedPreferences: SharedPrefer ) private fun canEnableNotifications(): Boolean { - val areNotificationsDisabledBySystem = Build.VERSION.SDK_INT >= 26 && ( - !NotificationChannels.getInstance().isMessageChannelEnabled || - !NotificationChannels.getInstance().isMessagesChannelGroupEnabled || - !NotificationChannels.getInstance().areNotificationsEnabled() - ) + val areNotificationsDisabledBySystem = Build.VERSION.SDK_INT >= 26 && + ( + !NotificationChannels.getInstance().isMessageChannelEnabled || + !NotificationChannels.getInstance().isMessagesChannelGroupEnabled || + !NotificationChannels.getInstance().areNotificationsEnabled() + ) return !areNotificationsDisabledBySystem } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/InAppDonations.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/InAppDonations.kt index 41ae8c65eb..87edb83e79 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/InAppDonations.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/InAppDonations.kt @@ -50,7 +50,8 @@ object InAppDonations { InAppPaymentType.ONE_TIME_GIFT -> true InAppPaymentType.RECURRING_DONATION -> true InAppPaymentType.RECURRING_BACKUP -> false - } && !LocaleRemoteConfig.isPayPalDisabled() + } && + !LocaleRemoteConfig.isPayPalDisabled() } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ChatColors.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ChatColors.kt index cf674dc17d..8ecccc51b1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ChatColors.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ChatColors.kt @@ -178,12 +178,10 @@ class ChatColors( } @JvmStatic - fun forGradient(id: Id, linearGradient: LinearGradient): ChatColors = - ChatColors(id, linearGradient, null) + fun forGradient(id: Id, linearGradient: LinearGradient): ChatColors = ChatColors(id, linearGradient, null) @JvmStatic - fun forColor(id: Id, @ColorInt color: Int): ChatColors = - ChatColors(id, null, color) + fun forColor(id: Id, @ColorInt color: Int): ChatColors = ChatColors(id, null, color) } sealed class Id(val longValue: Long) : Parcelable { diff --git a/app/src/main/java/org/thoughtcrime/securesms/pin/SvrRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/pin/SvrRepository.kt index d47131b1e1..821abbaf30 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/pin/SvrRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/pin/SvrRepository.kt @@ -423,12 +423,13 @@ object SvrRepository { false } - newToken = newToken || if (Svr3Migration.shouldWriteToSvr2) { - val credentials: AuthCredentials = svr2.authorization() - SignalStore.svr.appendSvr2AuthTokenToList(credentials.asBasic()) - } else { - false - } + newToken = newToken || + if (Svr3Migration.shouldWriteToSvr2) { + val credentials: AuthCredentials = svr2.authorization() + SignalStore.svr.appendSvr2AuthTokenToList(credentials.asBasic()) + } else { + false + } if (newToken && SignalStore.svr.hasPin()) { BackupManager(AppDependencies.application).dataChanged() diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/data/RegistrationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/data/RegistrationRepository.kt index 71c5d88da9..2d89e7e8ae 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/data/RegistrationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/data/RegistrationRepository.kt @@ -110,10 +110,9 @@ object RegistrationRepository { /** * Retrieve the FCM token from the Firebase service. */ - suspend fun getFcmToken(context: Context): String? = - withContext(Dispatchers.Default) { - FcmUtil.getToken(context).orElse(null) - } + suspend fun getFcmToken(context: Context): String? = withContext(Dispatchers.Default) { + FcmUtil.getToken(context).orElse(null) + } /** * Queries, and creates if needed, the local registration ID. @@ -147,122 +146,120 @@ object RegistrationRepository { * Queries, and creates if needed, the local profile key. */ @JvmStatic - suspend fun getProfileKey(e164: String): ProfileKey = - withContext(Dispatchers.IO) { - // TODO [regv2]: make creation more explicit instead of hiding it in this getter - val recipientTable = SignalDatabase.recipients - val recipient = recipientTable.getByE164(e164) - var profileKey = if (recipient.isPresent) { - ProfileKeyUtil.profileKeyOrNull(Recipient.resolved(recipient.get()).profileKey) - } else { - null - } - if (profileKey == null) { - profileKey = ProfileKeyUtil.createNew() - Log.i(TAG, "No profile key found, created a new one") - } - profileKey + suspend fun getProfileKey(e164: String): ProfileKey = withContext(Dispatchers.IO) { + // TODO [regv2]: make creation more explicit instead of hiding it in this getter + val recipientTable = SignalDatabase.recipients + val recipient = recipientTable.getByE164(e164) + var profileKey = if (recipient.isPresent) { + ProfileKeyUtil.profileKeyOrNull(Recipient.resolved(recipient.get()).profileKey) + } else { + null } + if (profileKey == null) { + profileKey = ProfileKeyUtil.createNew() + Log.i(TAG, "No profile key found, created a new one") + } + profileKey + } /** * Takes a server response from a successful registration and persists the relevant data. */ @JvmStatic - suspend fun registerAccountLocally(context: Context, data: LocalRegistrationMetadata) = - withContext(Dispatchers.IO) { - Log.v(TAG, "registerAccountLocally()") - if (data.linkedDeviceInfo != null) { - SignalStore.account.deviceId = data.linkedDeviceInfo.deviceId - SignalStore.account.deviceName = data.linkedDeviceInfo.deviceName + suspend fun registerAccountLocally(context: Context, data: LocalRegistrationMetadata) = withContext(Dispatchers.IO) { + Log.v(TAG, "registerAccountLocally()") + if (data.linkedDeviceInfo != null) { + SignalStore.account.deviceId = data.linkedDeviceInfo.deviceId + SignalStore.account.deviceName = data.linkedDeviceInfo.deviceName + } + + val aciIdentityKeyPair = data.getAciIdentityKeyPair() + val pniIdentityKeyPair = data.getPniIdentityKeyPair() + SignalStore.account.restoreAciIdentityKeyFromBackup(aciIdentityKeyPair.publicKey.serialize(), aciIdentityKeyPair.privateKey.serialize()) + SignalStore.account.restorePniIdentityKeyFromBackup(pniIdentityKeyPair.publicKey.serialize(), pniIdentityKeyPair.privateKey.serialize()) + + val aciPreKeyCollection = data.getAciPreKeyCollection() + val pniPreKeyCollection = data.getPniPreKeyCollection() + val aci: ACI = ACI.parseOrThrow(data.aci) + val pni: PNI = PNI.parseOrThrow(data.pni) + val hasPin: Boolean = data.hasPin + + SignalStore.account.setAci(aci) + SignalStore.account.setPni(pni) + + AppDependencies.resetProtocolStores() + + AppDependencies.protocolStore.aci().sessions().archiveAllSessions() + AppDependencies.protocolStore.pni().sessions().archiveAllSessions() + SenderKeyUtil.clearAllState() + + val aciProtocolStore = AppDependencies.protocolStore.aci() + val aciMetadataStore = SignalStore.account.aciPreKeys + + val pniProtocolStore = AppDependencies.protocolStore.pni() + val pniMetadataStore = SignalStore.account.pniPreKeys + + storeSignedAndLastResortPreKeys(aciProtocolStore, aciMetadataStore, aciPreKeyCollection) + storeSignedAndLastResortPreKeys(pniProtocolStore, pniMetadataStore, pniPreKeyCollection) + + val recipientTable = SignalDatabase.recipients + val selfId = Recipient.trustedPush(aci, pni, data.e164).id + + recipientTable.setProfileSharing(selfId, true) + recipientTable.markRegisteredOrThrow(selfId, aci) + recipientTable.linkIdsForSelf(aci, pni, data.e164) + recipientTable.setProfileKey(selfId, ProfileKey(data.profileKey.toByteArray())) + + AppDependencies.recipientCache.clearSelf() + + SignalStore.account.setE164(data.e164) + SignalStore.account.fcmToken = data.fcmToken + SignalStore.account.fcmEnabled = data.fcmEnabled + + val now = System.currentTimeMillis() + saveOwnIdentityKey(selfId, aci, aciProtocolStore, now) + saveOwnIdentityKey(selfId, pni, pniProtocolStore, now) + + if (data.linkedDeviceInfo != null) { + if (data.linkedDeviceInfo.accountEntropyPool != null) { + SignalStore.account.setAccountEntropyPoolFromPrimaryDevice(AccountEntropyPool(data.linkedDeviceInfo.accountEntropyPool)) } - val aciIdentityKeyPair = data.getAciIdentityKeyPair() - val pniIdentityKeyPair = data.getPniIdentityKeyPair() - SignalStore.account.restoreAciIdentityKeyFromBackup(aciIdentityKeyPair.publicKey.serialize(), aciIdentityKeyPair.privateKey.serialize()) - SignalStore.account.restorePniIdentityKeyFromBackup(pniIdentityKeyPair.publicKey.serialize(), pniIdentityKeyPair.privateKey.serialize()) - - val aciPreKeyCollection = data.getAciPreKeyCollection() - val pniPreKeyCollection = data.getPniPreKeyCollection() - val aci: ACI = ACI.parseOrThrow(data.aci) - val pni: PNI = PNI.parseOrThrow(data.pni) - val hasPin: Boolean = data.hasPin - - SignalStore.account.setAci(aci) - SignalStore.account.setPni(pni) - - AppDependencies.resetProtocolStores() - - AppDependencies.protocolStore.aci().sessions().archiveAllSessions() - AppDependencies.protocolStore.pni().sessions().archiveAllSessions() - SenderKeyUtil.clearAllState() - - val aciProtocolStore = AppDependencies.protocolStore.aci() - val aciMetadataStore = SignalStore.account.aciPreKeys - - val pniProtocolStore = AppDependencies.protocolStore.pni() - val pniMetadataStore = SignalStore.account.pniPreKeys - - storeSignedAndLastResortPreKeys(aciProtocolStore, aciMetadataStore, aciPreKeyCollection) - storeSignedAndLastResortPreKeys(pniProtocolStore, pniMetadataStore, pniPreKeyCollection) - - val recipientTable = SignalDatabase.recipients - val selfId = Recipient.trustedPush(aci, pni, data.e164).id - - recipientTable.setProfileSharing(selfId, true) - recipientTable.markRegisteredOrThrow(selfId, aci) - recipientTable.linkIdsForSelf(aci, pni, data.e164) - recipientTable.setProfileKey(selfId, ProfileKey(data.profileKey.toByteArray())) - - AppDependencies.recipientCache.clearSelf() - - SignalStore.account.setE164(data.e164) - SignalStore.account.fcmToken = data.fcmToken - SignalStore.account.fcmEnabled = data.fcmEnabled - - val now = System.currentTimeMillis() - saveOwnIdentityKey(selfId, aci, aciProtocolStore, now) - saveOwnIdentityKey(selfId, pni, pniProtocolStore, now) - - if (data.linkedDeviceInfo != null) { - if (data.linkedDeviceInfo.accountEntropyPool != null) { - SignalStore.account.setAccountEntropyPoolFromPrimaryDevice(AccountEntropyPool(data.linkedDeviceInfo.accountEntropyPool)) - } - - if (data.linkedDeviceInfo.mediaRootBackupKey != null) { - SignalStore.backup.mediaRootBackupKey = MediaRootBackupKey(data.linkedDeviceInfo.mediaRootBackupKey.toByteArray()) - } - } - - SignalStore.account.setServicePassword(data.servicePassword) - SignalStore.account.setRegistered(true) - TextSecurePreferences.setPromptedPushRegistration(context, true) - TextSecurePreferences.setUnauthorizedReceived(context, false) - NotificationManagerCompat.from(context).cancel(NotificationIds.UNREGISTERED_NOTIFICATION_ID) - - val masterKey = if (data.masterKey != null) MasterKey(data.masterKey.toByteArray()) else null - SvrRepository.onRegistrationComplete(masterKey, data.pin, hasPin, data.reglockEnabled, SignalStore.account.restoredAccountEntropyPool) - - AppDependencies.resetNetwork() - AppDependencies.startNetwork() - PreKeysSyncJob.enqueue() - - val jobManager = AppDependencies.jobManager - - if (data.linkedDeviceInfo == null) { - jobManager.add(DirectoryRefreshJob(false)) - jobManager.add(RotateCertificateJob()) - - DirectoryRefreshListener.schedule(context) - RotateSignedPreKeyListener.schedule(context) - } else { - SignalStore.account.isMultiDevice = true - jobManager.runJobBlocking(RefreshOwnProfileJob(), 30.seconds) - - jobManager.add(RotateCertificateJob()) - RotateSignedPreKeyListener.schedule(context) + if (data.linkedDeviceInfo.mediaRootBackupKey != null) { + SignalStore.backup.mediaRootBackupKey = MediaRootBackupKey(data.linkedDeviceInfo.mediaRootBackupKey.toByteArray()) } } + SignalStore.account.setServicePassword(data.servicePassword) + SignalStore.account.setRegistered(true) + TextSecurePreferences.setPromptedPushRegistration(context, true) + TextSecurePreferences.setUnauthorizedReceived(context, false) + NotificationManagerCompat.from(context).cancel(NotificationIds.UNREGISTERED_NOTIFICATION_ID) + + val masterKey = if (data.masterKey != null) MasterKey(data.masterKey.toByteArray()) else null + SvrRepository.onRegistrationComplete(masterKey, data.pin, hasPin, data.reglockEnabled, SignalStore.account.restoredAccountEntropyPool) + + AppDependencies.resetNetwork() + AppDependencies.startNetwork() + PreKeysSyncJob.enqueue() + + val jobManager = AppDependencies.jobManager + + if (data.linkedDeviceInfo == null) { + jobManager.add(DirectoryRefreshJob(false)) + jobManager.add(RotateCertificateJob()) + + DirectoryRefreshListener.schedule(context) + RotateSignedPreKeyListener.schedule(context) + } else { + SignalStore.account.isMultiDevice = true + jobManager.runJobBlocking(RefreshOwnProfileJob(), 30.seconds) + + jobManager.add(RotateCertificateJob()) + RotateSignedPreKeyListener.schedule(context) + } + } + @JvmStatic private fun saveOwnIdentityKey(selfId: RecipientId, serviceId: ServiceId, protocolStore: SignalServiceAccountDataStoreImpl, now: Long) { protocolStore.identities().saveIdentityWithoutSideEffects( @@ -299,49 +296,46 @@ object RegistrationRepository { return PinHashUtil.verifyLocalPinHash(pinHash, pin) } - suspend fun fetchMasterKeyFromSvrRemote(pin: String, svr2Credentials: AuthCredentials?, svr3Credentials: Svr3Credentials?): MasterKey = - withContext(Dispatchers.IO) { - val credentialSet = SvrAuthCredentialSet(svr2Credentials = svr2Credentials, svr3Credentials = svr3Credentials) - val masterKey = SvrRepository.restoreMasterKeyPreRegistration(credentialSet, pin) - return@withContext masterKey - } + suspend fun fetchMasterKeyFromSvrRemote(pin: String, svr2Credentials: AuthCredentials?, svr3Credentials: Svr3Credentials?): MasterKey = withContext(Dispatchers.IO) { + val credentialSet = SvrAuthCredentialSet(svr2Credentials = svr2Credentials, svr3Credentials = svr3Credentials) + val masterKey = SvrRepository.restoreMasterKeyPreRegistration(credentialSet, pin) + return@withContext masterKey + } /** * Validates a session ID. */ - private suspend fun validateSession(context: Context, sessionId: String, e164: String, password: String): RegistrationSessionCheckResult = - withContext(Dispatchers.IO) { - val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi - Log.d(TAG, "Validating registration session with service.") - val registrationSessionResult = api.getRegistrationSessionStatus(sessionId) - return@withContext RegistrationSessionCheckResult.from(registrationSessionResult) - } + private suspend fun validateSession(context: Context, sessionId: String, e164: String, password: String): RegistrationSessionCheckResult = withContext(Dispatchers.IO) { + val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi + Log.d(TAG, "Validating registration session with service.") + val registrationSessionResult = api.getRegistrationSessionStatus(sessionId) + return@withContext RegistrationSessionCheckResult.from(registrationSessionResult) + } /** * Initiates a new registration session on the service. */ - suspend fun createSession(context: Context, e164: String, password: String, mcc: String?, mnc: String?): RegistrationSessionCreationResult = - withContext(Dispatchers.IO) { - Log.d(TAG, "About to create a registration session…") - val fcmToken: String? = FcmUtil.getToken(context).orElse(null) - val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi + suspend fun createSession(context: Context, e164: String, password: String, mcc: String?, mnc: String?): RegistrationSessionCreationResult = withContext(Dispatchers.IO) { + Log.d(TAG, "About to create a registration session…") + val fcmToken: String? = FcmUtil.getToken(context).orElse(null) + val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi - val registrationSessionResult = if (fcmToken == null) { - Log.d(TAG, "Creating registration session without FCM token.") - api.createRegistrationSession(null, mcc, mnc) - } else { - Log.d(TAG, "Creating registration session with FCM token.") - createSessionAndBlockForPushChallenge(api, fcmToken, mcc, mnc) - } - val result = RegistrationSessionCreationResult.from(registrationSessionResult) - if (result is RegistrationSessionCreationResult.Success) { - Log.d(TAG, "Updating registration session and E164 in value store.") - SignalStore.registration.sessionId = result.sessionId - SignalStore.registration.sessionE164 = e164 - } - - return@withContext result + val registrationSessionResult = if (fcmToken == null) { + Log.d(TAG, "Creating registration session without FCM token.") + api.createRegistrationSession(null, mcc, mnc) + } else { + Log.d(TAG, "Creating registration session with FCM token.") + createSessionAndBlockForPushChallenge(api, fcmToken, mcc, mnc) } + val result = RegistrationSessionCreationResult.from(registrationSessionResult) + if (result is RegistrationSessionCreationResult.Success) { + Log.d(TAG, "Updating registration session and E164 in value store.") + SignalStore.registration.sessionId = result.sessionId + SignalStore.registration.sessionE164 = e164 + } + + return@withContext result + } /** * Validates an existing session, if its ID is provided. If the session is expired/invalid, or none is provided, it will attempt to initiate a new session. @@ -379,108 +373,103 @@ object RegistrationRepository { /** * Asks the service to send a verification code through one of our supported channels (SMS, phone call). */ - suspend fun requestSmsCode(context: Context, sessionId: String, e164: String, password: String, mode: E164VerificationMode): VerificationCodeRequestResult = - withContext(Dispatchers.IO) { - val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi + suspend fun requestSmsCode(context: Context, sessionId: String, e164: String, password: String, mode: E164VerificationMode): VerificationCodeRequestResult = withContext(Dispatchers.IO) { + val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi - val codeRequestResult = api.requestSmsVerificationCode(sessionId, Locale.getDefault(), mode.isSmsRetrieverSupported, mode.transport) + val codeRequestResult = api.requestSmsVerificationCode(sessionId, Locale.getDefault(), mode.isSmsRetrieverSupported, mode.transport) - return@withContext VerificationCodeRequestResult.from(codeRequestResult) - } + return@withContext VerificationCodeRequestResult.from(codeRequestResult) + } /** * Submits the user-entered verification code to the service. */ - suspend fun submitVerificationCode(context: Context, sessionId: String, registrationData: RegistrationData): VerificationCodeRequestResult = - withContext(Dispatchers.IO) { - val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, registrationData.e164, SignalServiceAddress.DEFAULT_DEVICE_ID, registrationData.password).registrationApi - val result = api.verifyAccount(sessionId = sessionId, verificationCode = registrationData.code) - return@withContext VerificationCodeRequestResult.from(result) - } + suspend fun submitVerificationCode(context: Context, sessionId: String, registrationData: RegistrationData): VerificationCodeRequestResult = withContext(Dispatchers.IO) { + val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, registrationData.e164, SignalServiceAddress.DEFAULT_DEVICE_ID, registrationData.password).registrationApi + val result = api.verifyAccount(sessionId = sessionId, verificationCode = registrationData.code) + return@withContext VerificationCodeRequestResult.from(result) + } /** * Submits the solved captcha token to the service. */ - suspend fun submitCaptchaToken(context: Context, e164: String, password: String, sessionId: String, captchaToken: String): VerificationCodeRequestResult = - withContext(Dispatchers.IO) { - val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi - val captchaSubmissionResult = api.submitCaptchaToken(sessionId = sessionId, captchaToken = captchaToken) - return@withContext VerificationCodeRequestResult.from(captchaSubmissionResult) - } + suspend fun submitCaptchaToken(context: Context, e164: String, password: String, sessionId: String, captchaToken: String): VerificationCodeRequestResult = withContext(Dispatchers.IO) { + val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi + val captchaSubmissionResult = api.submitCaptchaToken(sessionId = sessionId, captchaToken = captchaToken) + return@withContext VerificationCodeRequestResult.from(captchaSubmissionResult) + } - suspend fun requestAndVerifyPushToken(context: Context, sessionId: String, e164: String, password: String) = - withContext(Dispatchers.IO) { - val fcmToken = getFcmToken(context) - val accountManager = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password) - val pushChallenge = PushChallengeRequest.getPushChallengeBlocking(accountManager, sessionId, Optional.ofNullable(fcmToken), PUSH_REQUEST_TIMEOUT).orElse(null) - val pushSubmissionResult = accountManager.registrationApi.submitPushChallengeToken(sessionId = sessionId, pushChallengeToken = pushChallenge) - return@withContext VerificationCodeRequestResult.from(pushSubmissionResult) - } + suspend fun requestAndVerifyPushToken(context: Context, sessionId: String, e164: String, password: String) = withContext(Dispatchers.IO) { + val fcmToken = getFcmToken(context) + val accountManager = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password) + val pushChallenge = PushChallengeRequest.getPushChallengeBlocking(accountManager, sessionId, Optional.ofNullable(fcmToken), PUSH_REQUEST_TIMEOUT).orElse(null) + val pushSubmissionResult = accountManager.registrationApi.submitPushChallengeToken(sessionId = sessionId, pushChallengeToken = pushChallenge) + return@withContext VerificationCodeRequestResult.from(pushSubmissionResult) + } /** * Submit the necessary assets as a verified account so that the user can actually use the service. */ - suspend fun registerAccount(context: Context, sessionId: String?, registrationData: RegistrationData, pin: String? = null, masterKeyProducer: MasterKeyProducer? = null): RegisterAccountResult = - withContext(Dispatchers.IO) { - Log.v(TAG, "registerAccount()") - val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, registrationData.e164, SignalServiceAddress.DEFAULT_DEVICE_ID, registrationData.password).registrationApi + suspend fun registerAccount(context: Context, sessionId: String?, registrationData: RegistrationData, pin: String? = null, masterKeyProducer: MasterKeyProducer? = null): RegisterAccountResult = withContext(Dispatchers.IO) { + Log.v(TAG, "registerAccount()") + val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, registrationData.e164, SignalServiceAddress.DEFAULT_DEVICE_ID, registrationData.password).registrationApi - val universalUnidentifiedAccess: Boolean = TextSecurePreferences.isUniversalUnidentifiedAccess(context) - val unidentifiedAccessKey: ByteArray = UnidentifiedAccess.deriveAccessKeyFrom(registrationData.profileKey) + val universalUnidentifiedAccess: Boolean = TextSecurePreferences.isUniversalUnidentifiedAccess(context) + val unidentifiedAccessKey: ByteArray = UnidentifiedAccess.deriveAccessKeyFrom(registrationData.profileKey) - val masterKey: MasterKey? - try { - masterKey = masterKeyProducer?.produceMasterKey() - } catch (e: SvrNoDataException) { - return@withContext RegisterAccountResult.SvrNoData(e) - } catch (e: SvrWrongPinException) { - return@withContext RegisterAccountResult.SvrWrongPin(e) - } catch (e: IOException) { - return@withContext RegisterAccountResult.UnknownError(e) + val masterKey: MasterKey? + try { + masterKey = masterKeyProducer?.produceMasterKey() + } catch (e: SvrNoDataException) { + return@withContext RegisterAccountResult.SvrNoData(e) + } catch (e: SvrWrongPinException) { + return@withContext RegisterAccountResult.SvrWrongPin(e) + } catch (e: IOException) { + return@withContext RegisterAccountResult.UnknownError(e) + } + + val registrationLock: String? = masterKey?.deriveRegistrationLock() + + val accountAttributes = AccountAttributes( + signalingKey = null, + registrationId = registrationData.registrationId, + fetchesMessages = registrationData.isNotFcm, + registrationLock = registrationLock, + unidentifiedAccessKey = unidentifiedAccessKey, + unrestrictedUnidentifiedAccess = universalUnidentifiedAccess, + capabilities = AppCapabilities.getCapabilities(true), + discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy.phoneNumberDiscoverabilityMode == PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.DISCOVERABLE, + name = null, + pniRegistrationId = registrationData.pniRegistrationId, + recoveryPassword = registrationData.recoveryPassword + ) + + SignalStore.account.generateAciIdentityKeyIfNecessary() + val aciIdentity: IdentityKeyPair = SignalStore.account.aciIdentityKey + + SignalStore.account.generatePniIdentityKeyIfNecessary() + val pniIdentity: IdentityKeyPair = SignalStore.account.pniIdentityKey + + val aciPreKeyCollection = generateSignedAndLastResortPreKeys(aciIdentity, SignalStore.account.aciPreKeys) + val pniPreKeyCollection = generateSignedAndLastResortPreKeys(pniIdentity, SignalStore.account.pniPreKeys) + + val result: NetworkResult = api.registerAccount(sessionId, registrationData.recoveryPassword, accountAttributes, aciPreKeyCollection, pniPreKeyCollection, registrationData.fcmToken, true) + .map { accountRegistrationResponse: VerifyAccountResponse -> + AccountRegistrationResult( + uuid = accountRegistrationResponse.uuid, + pni = accountRegistrationResponse.pni, + storageCapable = accountRegistrationResponse.storageCapable, + number = accountRegistrationResponse.number, + masterKey = masterKey, + pin = pin, + aciPreKeyCollection = aciPreKeyCollection, + pniPreKeyCollection = pniPreKeyCollection, + reRegistration = accountRegistrationResponse.reregistration + ) } - val registrationLock: String? = masterKey?.deriveRegistrationLock() - - val accountAttributes = AccountAttributes( - signalingKey = null, - registrationId = registrationData.registrationId, - fetchesMessages = registrationData.isNotFcm, - registrationLock = registrationLock, - unidentifiedAccessKey = unidentifiedAccessKey, - unrestrictedUnidentifiedAccess = universalUnidentifiedAccess, - capabilities = AppCapabilities.getCapabilities(true), - discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy.phoneNumberDiscoverabilityMode == PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.DISCOVERABLE, - name = null, - pniRegistrationId = registrationData.pniRegistrationId, - recoveryPassword = registrationData.recoveryPassword - ) - - SignalStore.account.generateAciIdentityKeyIfNecessary() - val aciIdentity: IdentityKeyPair = SignalStore.account.aciIdentityKey - - SignalStore.account.generatePniIdentityKeyIfNecessary() - val pniIdentity: IdentityKeyPair = SignalStore.account.pniIdentityKey - - val aciPreKeyCollection = generateSignedAndLastResortPreKeys(aciIdentity, SignalStore.account.aciPreKeys) - val pniPreKeyCollection = generateSignedAndLastResortPreKeys(pniIdentity, SignalStore.account.pniPreKeys) - - val result: NetworkResult = api.registerAccount(sessionId, registrationData.recoveryPassword, accountAttributes, aciPreKeyCollection, pniPreKeyCollection, registrationData.fcmToken, true) - .map { accountRegistrationResponse: VerifyAccountResponse -> - AccountRegistrationResult( - uuid = accountRegistrationResponse.uuid, - pni = accountRegistrationResponse.pni, - storageCapable = accountRegistrationResponse.storageCapable, - number = accountRegistrationResponse.number, - masterKey = masterKey, - pin = pin, - aciPreKeyCollection = aciPreKeyCollection, - pniPreKeyCollection = pniPreKeyCollection, - reRegistration = accountRegistrationResponse.reregistration - ) - } - - return@withContext RegisterAccountResult.from(result) - } + return@withContext RegisterAccountResult.from(result) + } @WorkerThread fun registerAsLinkedDevice( @@ -539,85 +528,83 @@ object RegistrationRepository { } } - private suspend fun createSessionAndBlockForPushChallenge(accountManager: RegistrationApi, fcmToken: String, mcc: String?, mnc: String?): NetworkResult = - withContext(Dispatchers.IO) { - // TODO [regv2]: do not use event bus nor latch - val subscriber = PushTokenChallengeSubscriber() - val eventBus = EventBus.getDefault() - eventBus.register(subscriber) + private suspend fun createSessionAndBlockForPushChallenge(accountManager: RegistrationApi, fcmToken: String, mcc: String?, mnc: String?): NetworkResult = withContext(Dispatchers.IO) { + // TODO [regv2]: do not use event bus nor latch + val subscriber = PushTokenChallengeSubscriber() + val eventBus = EventBus.getDefault() + eventBus.register(subscriber) - try { - Log.d(TAG, "Requesting a registration session with FCM token…") - val sessionCreationResponse = accountManager.createRegistrationSession(fcmToken, mcc, mnc) - if (sessionCreationResponse !is NetworkResult.Success) { - return@withContext sessionCreationResponse - } - - val receivedPush = subscriber.latch.await(PUSH_REQUEST_TIMEOUT, TimeUnit.MILLISECONDS) - eventBus.unregister(subscriber) - - if (receivedPush) { - val challenge = subscriber.challenge - if (challenge != null) { - Log.i(TAG, "Push challenge token received.") - return@withContext accountManager.submitPushChallengeToken(sessionCreationResponse.result.metadata.id, challenge) - } else { - Log.w(TAG, "Push received but challenge token was null.") - } - } else { - Log.i(TAG, "Push challenge timed out.") - } - Log.i(TAG, "Push challenge unsuccessful. Continuing with session created without one.") + try { + Log.d(TAG, "Requesting a registration session with FCM token…") + val sessionCreationResponse = accountManager.createRegistrationSession(fcmToken, mcc, mnc) + if (sessionCreationResponse !is NetworkResult.Success) { return@withContext sessionCreationResponse - } catch (ex: Exception) { - Log.w(TAG, "Exception caught, but the earlier try block should have caught it?", ex) - return@withContext NetworkResult.ApplicationError(ex) } - } - suspend fun hasValidSvrAuthCredentials(context: Context, e164: String, password: String): BackupAuthCheckResult = - withContext(Dispatchers.IO) { - val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi + val receivedPush = subscriber.latch.await(PUSH_REQUEST_TIMEOUT, TimeUnit.MILLISECONDS) + eventBus.unregister(subscriber) - val svr3Result = SignalStore.svr.svr3AuthTokens - ?.takeIf { Svr3Migration.shouldReadFromSvr3 } - ?.takeIf { it.isNotEmpty() } - ?.toSvrCredentials() - ?.let { authTokens -> - api - .validateSvr3AuthCredential(e164, authTokens) - .runIfSuccessful { - val removedInvalidTokens = SignalStore.svr.removeSvr3AuthTokens(it.invalid) - if (removedInvalidTokens) { - BackupManager(context).dataChanged() - } - } - .let { BackupAuthCheckResult.fromV3(it) } + if (receivedPush) { + val challenge = subscriber.challenge + if (challenge != null) { + Log.i(TAG, "Push challenge token received.") + return@withContext accountManager.submitPushChallengeToken(sessionCreationResponse.result.metadata.id, challenge) + } else { + Log.w(TAG, "Push received but challenge token was null.") } + } else { + Log.i(TAG, "Push challenge timed out.") + } + Log.i(TAG, "Push challenge unsuccessful. Continuing with session created without one.") + return@withContext sessionCreationResponse + } catch (ex: Exception) { + Log.w(TAG, "Exception caught, but the earlier try block should have caught it?", ex) + return@withContext NetworkResult.ApplicationError(ex) + } + } - if (svr3Result is BackupAuthCheckResult.SuccessWithCredentials) { - Log.d(TAG, "Found valid SVR3 credentials.") - return@withContext svr3Result + suspend fun hasValidSvrAuthCredentials(context: Context, e164: String, password: String): BackupAuthCheckResult = withContext(Dispatchers.IO) { + val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi + + val svr3Result = SignalStore.svr.svr3AuthTokens + ?.takeIf { Svr3Migration.shouldReadFromSvr3 } + ?.takeIf { it.isNotEmpty() } + ?.toSvrCredentials() + ?.let { authTokens -> + api + .validateSvr3AuthCredential(e164, authTokens) + .runIfSuccessful { + val removedInvalidTokens = SignalStore.svr.removeSvr3AuthTokens(it.invalid) + if (removedInvalidTokens) { + BackupManager(context).dataChanged() + } + } + .let { BackupAuthCheckResult.fromV3(it) } } - Log.d(TAG, "No valid SVR3 credentials, looking for SVR2.") - - return@withContext SignalStore.svr.svr2AuthTokens - ?.takeIf { it.isNotEmpty() } - ?.toSvrCredentials() - ?.let { authTokens -> - api - .validateSvr2AuthCredential(e164, authTokens) - .runIfSuccessful { - val removedInvalidTokens = SignalStore.svr.removeSvr2AuthTokens(it.invalid) - if (removedInvalidTokens) { - BackupManager(context).dataChanged() - } - } - .let { BackupAuthCheckResult.fromV2(it) } - } ?: BackupAuthCheckResult.SuccessWithoutCredentials() + if (svr3Result is BackupAuthCheckResult.SuccessWithCredentials) { + Log.d(TAG, "Found valid SVR3 credentials.") + return@withContext svr3Result } + Log.d(TAG, "No valid SVR3 credentials, looking for SVR2.") + + return@withContext SignalStore.svr.svr2AuthTokens + ?.takeIf { it.isNotEmpty() } + ?.toSvrCredentials() + ?.let { authTokens -> + api + .validateSvr2AuthCredential(e164, authTokens) + .runIfSuccessful { + val removedInvalidTokens = SignalStore.svr.removeSvr2AuthTokens(it.invalid) + if (removedInvalidTokens) { + BackupManager(context).dataChanged() + } + } + .let { BackupAuthCheckResult.fromV2(it) } + } ?: BackupAuthCheckResult.SuccessWithoutCredentials() + } + /** Converts the basic-auth creds we have locally into username:password pairs that are suitable for handing off to the service. */ private fun List.toSvrCredentials(): List { return this diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.kt index 93f91cc074..9adda3aed3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.kt @@ -102,7 +102,9 @@ class ContactRecordProcessor( if (!hasAci && !hasPni) { Log.w(TAG, "Found a ContactRecord with neither an ACI nor a PNI -- marking as invalid.") return true - } else if (selfAci != null && selfAci == remote.proto.signalAci || + } else if ( + selfAci != null && + selfAci == remote.proto.signalAci || (selfPni != null && selfPni == remote.proto.signalPni) || (selfE164 != null && remote.proto.e164.isNotBlank() && remote.proto.e164 == selfE164) ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt index 0900585b24..74e98c84dd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt @@ -309,7 +309,8 @@ class FullSignalAudioManager(context: Context, eventListener: EventListener?) : } val needBluetoothAudioStart = signalBluetoothManager.state == SignalBluetoothManager.State.AVAILABLE && - (userSelectedAudioDevice == AudioDevice.NONE || userSelectedAudioDevice == AudioDevice.BLUETOOTH || autoSwitchToBluetooth) && !androidAudioManager.isBluetoothScoOn + (userSelectedAudioDevice == AudioDevice.NONE || userSelectedAudioDevice == AudioDevice.BLUETOOTH || autoSwitchToBluetooth) && + !androidAudioManager.isBluetoothScoOn val needBluetoothAudioStop = (signalBluetoothManager.state == SignalBluetoothManager.State.CONNECTED || signalBluetoothManager.state == SignalBluetoothManager.State.CONNECTING) && (userSelectedAudioDevice != AudioDevice.NONE && userSelectedAudioDevice != AudioDevice.BLUETOOTH) diff --git a/app/src/test/java/org/thoughtcrime/securesms/emoji/EmojiJsonParserTest.kt b/app/src/test/java/org/thoughtcrime/securesms/emoji/EmojiJsonParserTest.kt index bc2816fb42..3c02c61555 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/emoji/EmojiJsonParserTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/emoji/EmojiJsonParserTest.kt @@ -171,9 +171,8 @@ class EmojiJsonParserTest { private fun uriFactory(sprite: String, format: String) = Uri.parse("file:///$sprite") - private fun EmojiPageModel.isSameAs(other: EmojiPageModel) = - this.javaClass == other.javaClass && - this.emoji == other.emoji && - this.iconAttr == other.iconAttr && - this.spriteUri == other.spriteUri + private fun EmojiPageModel.isSameAs(other: EmojiPageModel) = this.javaClass == other.javaClass && + this.emoji == other.emoji && + this.iconAttr == other.iconAttr && + this.spriteUri == other.spriteUri } diff --git a/app/src/test/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackControllerRangeComparatorTest.kt b/app/src/test/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackControllerRangeComparatorTest.kt index 2f898471c5..c8f1f8e900 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackControllerRangeComparatorTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/giph/mp4/GiphyMp4PlaybackControllerRangeComparatorTest.kt @@ -14,6 +14,5 @@ class GiphyMp4PlaybackControllerRangeComparatorTest { Assert.assertArrayEquals(expected, sorted) } - private fun createComparator(start: Int, end: Int): GiphyMp4PlaybackController.RangeComparator = - GiphyMp4PlaybackController.RangeComparator(start, end) + private fun createComparator(start: Int, end: Int): GiphyMp4PlaybackController.RangeComparator = GiphyMp4PlaybackController.RangeComparator(start, end) } diff --git a/build-logic/plugins/src/main/java/ktlint.gradle.kts b/build-logic/plugins/src/main/java/ktlint.gradle.kts index a0d7ee7757..fee113b5a0 100644 --- a/build-logic/plugins/src/main/java/ktlint.gradle.kts +++ b/build-logic/plugins/src/main/java/ktlint.gradle.kts @@ -3,5 +3,5 @@ plugins { } ktlint { - version.set("1.2.1") + version.set("1.5.0") } diff --git a/build-logic/tools/build.gradle.kts b/build-logic/tools/build.gradle.kts index 825f937ed9..9a63555e79 100644 --- a/build-logic/tools/build.gradle.kts +++ b/build-logic/tools/build.gradle.kts @@ -21,7 +21,7 @@ kotlin { // NOTE: For now, in order to run ktlint on this project, you have to manually run ./gradlew :build-logic:tools:ktlintFormat // Gotta figure out how to get it auto-included in the normal ./gradlew ktlintFormat ktlint { - version.set("1.2.1") + version.set("1.5.0") } dependencies { diff --git a/core-ui/src/main/java/org/signal/core/ui/compose/IconButtons.kt b/core-ui/src/main/java/org/signal/core/ui/compose/IconButtons.kt index bbb7de86f6..cc54f2e45a 100644 --- a/core-ui/src/main/java/org/signal/core/ui/compose/IconButtons.kt +++ b/core-ui/src/main/java/org/signal/core/ui/compose/IconButtons.kt @@ -39,13 +39,12 @@ object IconButtons { disabledContainerColor: Color = Color.Transparent, disabledContentColor: Color = contentColor.copy(alpha = 0.38f) - ): IconButtonColors = - IconButtonColors( - containerColor = containerColor, - contentColor = contentColor, - disabledContainerColor = disabledContainerColor, - disabledContentColor = disabledContentColor - ) + ): IconButtonColors = IconButtonColors( + containerColor = containerColor, + contentColor = contentColor, + disabledContainerColor = disabledContainerColor, + disabledContentColor = disabledContentColor + ) @Composable fun iconToggleButtonColors( @@ -56,15 +55,14 @@ object IconButtons { contentColor.copy(alpha = 0.38f), checkedContainerColor: Color = Color.Transparent, checkedContentColor: Color = MaterialTheme.colorScheme.primary - ): IconToggleButtonColors = - IconToggleButtonColors( - containerColor = containerColor, - contentColor = contentColor, - disabledContainerColor = disabledContainerColor, - disabledContentColor = disabledContentColor, - checkedContainerColor = checkedContainerColor, - checkedContentColor = checkedContentColor - ) + ): IconToggleButtonColors = IconToggleButtonColors( + containerColor = containerColor, + contentColor = contentColor, + disabledContainerColor = disabledContainerColor, + disabledContentColor = disabledContentColor, + checkedContainerColor = checkedContainerColor, + checkedContentColor = checkedContentColor + ) @Composable fun IconButton( diff --git a/core-ui/src/main/java/org/signal/core/ui/compose/copied/androidx/compose/DragGestureDetector.kt b/core-ui/src/main/java/org/signal/core/ui/compose/copied/androidx/compose/DragGestureDetector.kt index fc02c742cc..8a37c8c8d5 100644 --- a/core-ui/src/main/java/org/signal/core/ui/compose/copied/androidx/compose/DragGestureDetector.kt +++ b/core-ui/src/main/java/org/signal/core/ui/compose/copied/androidx/compose/DragGestureDetector.kt @@ -127,5 +127,4 @@ suspend fun AwaitPointerEventScope.awaitLongPressOrCancellation( } } -private fun PointerEvent.isPointerUp(pointerId: PointerId): Boolean = - changes.fastFirstOrNull { it.id == pointerId }?.pressed != true +private fun PointerEvent.isPointerUp(pointerId: PointerId): Boolean = changes.fastFirstOrNull { it.id == pointerId }?.pressed != true diff --git a/core-ui/src/main/java/org/signal/core/ui/navigation/ResultEventBus.kt b/core-ui/src/main/java/org/signal/core/ui/navigation/ResultEventBus.kt index c9bceb2403..f57e503af2 100644 --- a/core-ui/src/main/java/org/signal/core/ui/navigation/ResultEventBus.kt +++ b/core-ui/src/main/java/org/signal/core/ui/navigation/ResultEventBus.kt @@ -62,8 +62,7 @@ class ResultEventBus { /** * Provides a flow for the given resultKey. */ - inline fun getResultFlow(resultKey: String = T::class.toString()) = - channelMap[resultKey]?.receiveAsFlow() + inline fun getResultFlow(resultKey: String = T::class.toString()) = channelMap[resultKey]?.receiveAsFlow() /** * Sends a result into the channel associated with the given resultKey. diff --git a/debuglogs-viewer/app/src/main/java/org/signal/debuglogsviewer/app/webview/WebView.kt b/debuglogs-viewer/app/src/main/java/org/signal/debuglogsviewer/app/webview/WebView.kt index d0f1dcafa5..cba3b61cc4 100644 --- a/debuglogs-viewer/app/src/main/java/org/signal/debuglogsviewer/app/webview/WebView.kt +++ b/debuglogs-viewer/app/src/main/java/org/signal/debuglogsviewer/app/webview/WebView.kt @@ -72,7 +72,8 @@ fun setupWebView( webview.evaluateJavascript("editor.setValue($originalContent, -1);", null) } - copyButton.setOnClickListener { // In Signal app, use Util.writeTextToClipboard(context, value) instead + copyButton.setOnClickListener { + // In Signal app, use Util.writeTextToClipboard(context, value) instead webview.evaluateJavascript("editor.getValue();") { value -> val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip = ClipData.newPlainText(context.getString(R.string.app_name), value) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 31eb55bae3..fbb8a82c22 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ accompanist = "0.28.0" nanohttpd = "2.3.1" navigation-safe-args-gradle-plugin = "2.8.5" protobuf-gradle-plugin = "0.9.0" -ktlint = "12.1.1" +ktlint = "14.0.1" ui-test-junit4 = "1.9.4" [plugins] diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index dccc0f852e..b778118ed9 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -40,9 +40,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -121,9 +125,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -179,9 +187,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -269,9 +281,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -362,9 +378,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -852,9 +872,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -888,9 +912,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -933,9 +961,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -969,9 +1001,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -997,9 +1033,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1025,9 +1065,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1065,9 +1109,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1101,9 +1149,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1129,9 +1181,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1174,9 +1230,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1210,9 +1270,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1238,9 +1302,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1258,6 +1326,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -1283,9 +1353,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1311,9 +1385,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1339,9 +1417,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1367,9 +1449,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1447,9 +1533,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1467,9 +1557,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1487,9 +1581,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1507,9 +1605,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1527,9 +1629,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1547,9 +1653,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1567,9 +1677,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1587,9 +1701,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1607,9 +1725,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1627,6 +1749,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -1668,9 +1792,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1704,9 +1832,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1740,9 +1872,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1776,9 +1912,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1804,9 +1944,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1832,9 +1976,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1868,9 +2016,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1904,9 +2056,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1919,6 +2075,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -1960,9 +2118,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -1996,9 +2158,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2016,9 +2182,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2084,9 +2254,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2120,9 +2294,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2168,9 +2346,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2204,9 +2386,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2232,9 +2418,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2280,9 +2470,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2316,9 +2510,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2344,9 +2542,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2372,9 +2574,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2400,6 +2606,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -2408,9 +2616,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2444,9 +2656,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2472,6 +2688,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -2480,9 +2698,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2508,6 +2730,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -2516,9 +2740,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2547,14 +2775,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -2600,9 +2834,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2636,9 +2874,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2664,9 +2906,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2697,9 +2943,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2733,9 +2983,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2766,9 +3020,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2802,9 +3060,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2830,9 +3092,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2858,9 +3124,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2886,6 +3156,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -2894,9 +3166,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2930,9 +3206,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -2958,9 +3238,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3006,9 +3290,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3042,9 +3330,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3070,9 +3362,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3118,9 +3414,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3154,9 +3454,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3182,9 +3486,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3286,9 +3594,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3357,9 +3669,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3802,9 +4118,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -3890,14 +4210,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -3968,9 +4294,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -4022,9 +4352,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -4112,9 +4446,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -4195,9 +4533,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -4320,9 +4662,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -4496,9 +4842,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -4594,14 +4944,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -4657,9 +5013,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -4705,14 +5065,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -4804,9 +5170,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -4893,14 +5263,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -5000,6 +5376,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -5049,12 +5427,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -5167,14 +5551,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -5228,9 +5618,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -5288,14 +5682,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -5416,9 +5816,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -5510,25 +5914,37 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -5613,14 +6029,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -5966,81 +6388,121 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6267,9 +6729,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -6295,9 +6761,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -6325,9 +6795,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -6355,9 +6829,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -6437,9 +6915,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -6584,6 +7066,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -6659,6 +7143,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -6854,9 +7340,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -6874,9 +7364,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -6894,9 +7388,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -6926,9 +7424,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -8526,6 +9028,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + @@ -8533,6 +9042,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + @@ -8883,6 +9399,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -9071,6 +9589,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -9125,6 +9645,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -9242,6 +9764,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -9290,12 +9814,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + @@ -9453,6 +9983,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -9500,6 +10032,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -9575,6 +10109,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9599,6 +10145,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9623,6 +10181,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9647,6 +10217,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9671,6 +10253,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9695,6 +10289,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9719,6 +10325,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9743,6 +10361,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9767,6 +10397,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9791,6 +10433,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9815,6 +10469,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9851,6 +10517,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9875,6 +10553,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9899,6 +10589,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -9923,6 +10625,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -10550,6 +11264,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + @@ -10574,6 +11295,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -10626,6 +11359,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + @@ -10638,6 +11378,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -10688,6 +11440,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -11278,6 +12042,30 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + + + + + + + + + + + + + @@ -11728,6 +12516,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + @@ -11978,6 +12773,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -12076,6 +12873,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -12498,6 +13297,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -12631,6 +13432,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -12721,6 +13524,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -12853,6 +13658,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -12910,6 +13717,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -13815,6 +14624,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -14048,6 +14869,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -14103,6 +14926,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -14134,6 +14959,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -14182,9 +15009,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14202,9 +15033,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14222,9 +15057,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14237,6 +15076,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -14254,9 +15095,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14269,6 +15114,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -14286,9 +15133,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14306,9 +15157,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14326,9 +15181,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14346,9 +15205,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14366,9 +15229,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14381,6 +15248,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + @@ -14398,9 +15267,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + @@ -14413,25 +15286,37 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + + + + + @@ -14503,6 +15388,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + diff --git a/libsignal-service/build.gradle.kts b/libsignal-service/build.gradle.kts index 5f234d29cb..1c95447482 100644 --- a/libsignal-service/build.gradle.kts +++ b/libsignal-service/build.gradle.kts @@ -69,7 +69,7 @@ afterEvaluate { } ktlint { - version.set("1.2.1") + version.set("1.5.0") filter { exclude { entry ->