mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-08-05 04:45:14 +01:00
Migrate to libsignal setPushToken/clearPushToken.
Co-authored-by: Cody Henthorne <cody@signal.org> # Conflicts: # lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/account/AccountApi.kt
This commit is contained in:
committed by
Greyson Parrelli
parent
abf05293eb
commit
7e79dfa57f
+10
-13
@@ -25,7 +25,6 @@ import org.signal.core.ui.BottomSheetUtil
|
||||
import org.signal.core.ui.permissions.PermissionDeniedBottomSheet
|
||||
import org.signal.core.ui.permissions.RationaleDialog
|
||||
import org.signal.core.util.AppUtil
|
||||
import org.signal.core.util.ThreadUtil
|
||||
import org.signal.core.util.Util
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.concurrent.SimpleTask
|
||||
@@ -1055,19 +1054,17 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter
|
||||
.setTitle("Unregister?")
|
||||
.setMessage("Are you sure? You'll have to re-register to use Signal again -- no promises that the process will go smoothly.")
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
AdvancedPrivacySettingsRepository(requireContext()).disablePushMessages {
|
||||
ThreadUtil.runOnMain {
|
||||
when (it) {
|
||||
AdvancedPrivacySettingsRepository.DisablePushMessagesResult.SUCCESS -> {
|
||||
SignalStore.account.setRegistered(false)
|
||||
SignalStore.registration.clearRegistrationComplete()
|
||||
SignalStore.registration.hasUploadedProfile = false
|
||||
Toast.makeText(context, "Unregistered!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
when (AdvancedPrivacySettingsRepository(requireContext()).disablePushMessages()) {
|
||||
AdvancedPrivacySettingsRepository.DisablePushMessagesResult.SUCCESS -> {
|
||||
SignalStore.account.setRegistered(false)
|
||||
SignalStore.registration.clearRegistrationComplete()
|
||||
SignalStore.registration.hasUploadedProfile = false
|
||||
Toast.makeText(context, "Unregistered!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
AdvancedPrivacySettingsRepository.DisablePushMessagesResult.NETWORK_ERROR -> {
|
||||
Toast.makeText(context, "Network error!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
AdvancedPrivacySettingsRepository.DisablePushMessagesResult.NETWORK_ERROR -> {
|
||||
Toast.makeText(context, "Network error!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-25
@@ -3,8 +3,12 @@ package org.thoughtcrime.securesms.components.settings.app.privacy.advanced
|
||||
import android.content.Context
|
||||
import com.google.android.gms.tasks.Tasks
|
||||
import com.google.firebase.installations.FirebaseInstallations
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.libsignal.net.DeviceDeregisteredException
|
||||
import org.signal.libsignal.net.RequestResult
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob
|
||||
@@ -13,8 +17,6 @@ import org.thoughtcrime.securesms.net.SignalNetwork
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.api.NetworkResultUtil
|
||||
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.ExecutionException
|
||||
|
||||
@@ -22,30 +24,34 @@ private val TAG = Log.tag(AdvancedPrivacySettingsRepository::class.java)
|
||||
|
||||
class AdvancedPrivacySettingsRepository(private val context: Context) {
|
||||
|
||||
fun disablePushMessages(consumer: (DisablePushMessagesResult) -> Unit) {
|
||||
SignalExecutors.BOUNDED.execute {
|
||||
val result = try {
|
||||
try {
|
||||
NetworkResultUtil.toBasicLegacy(SignalNetwork.account.clearFcmToken())
|
||||
} catch (e: AuthorizationFailedException) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
if (SignalStore.account.fcmEnabled) {
|
||||
Tasks.await(FirebaseInstallations.getInstance().delete())
|
||||
}
|
||||
DisablePushMessagesResult.SUCCESS
|
||||
} catch (ioe: IOException) {
|
||||
Log.w(TAG, ioe)
|
||||
DisablePushMessagesResult.NETWORK_ERROR
|
||||
} catch (e: InterruptedException) {
|
||||
Log.w(TAG, "Interrupted while deleting", e)
|
||||
DisablePushMessagesResult.NETWORK_ERROR
|
||||
} catch (e: ExecutionException) {
|
||||
Log.w(TAG, "Error deleting", e.cause)
|
||||
DisablePushMessagesResult.NETWORK_ERROR
|
||||
}
|
||||
suspend fun disablePushMessages(): DisablePushMessagesResult = withContext(Dispatchers.IO) {
|
||||
val clearTokenError: Throwable? = when (val result = SignalNetwork.account.clearFcmToken()) {
|
||||
is RequestResult.Success, is RequestResult.NonSuccess -> null
|
||||
is RequestResult.RetryableNetworkError -> result.networkError
|
||||
is RequestResult.ApplicationError -> result.cause
|
||||
}
|
||||
|
||||
consumer(result)
|
||||
if (clearTokenError != null) {
|
||||
Log.w(TAG, clearTokenError)
|
||||
if (clearTokenError !is DeviceDeregisteredException) {
|
||||
return@withContext DisablePushMessagesResult.NETWORK_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (SignalStore.account.fcmEnabled) {
|
||||
Tasks.await(FirebaseInstallations.getInstance().delete())
|
||||
}
|
||||
DisablePushMessagesResult.SUCCESS
|
||||
} catch (ioe: IOException) {
|
||||
Log.w(TAG, ioe)
|
||||
DisablePushMessagesResult.NETWORK_ERROR
|
||||
} catch (e: InterruptedException) {
|
||||
Log.w(TAG, "Interrupted while deleting", e)
|
||||
DisablePushMessagesResult.NETWORK_ERROR
|
||||
} catch (e: ExecutionException) {
|
||||
Log.w(TAG, "Error deleting", e.cause)
|
||||
DisablePushMessagesResult.NETWORK_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.thoughtcrime.securesms.net.SignalNetwork;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.signal.core.util.PlayServicesUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.NetworkResultUtil;
|
||||
import org.whispersystems.signalservice.api.RequestResultUtil;
|
||||
import org.signal.network.exceptions.NonSuccessfulResponseCodeException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -101,7 +101,7 @@ public class FcmRefreshJob extends BaseJob {
|
||||
Log.i(TAG, "Token didn't change.");
|
||||
}
|
||||
|
||||
NetworkResultUtil.toBasicLegacy(SignalNetwork.account().setFcmToken(token.get()));
|
||||
RequestResultUtil.successOrThrowNoError(SignalNetwork.account().setFcmToken(token.get()));
|
||||
SignalStore.account().setFcmToken(token.get());
|
||||
|
||||
if (!SignalStore.account().isFcmEnabled()) {
|
||||
|
||||
+19
@@ -70,6 +70,25 @@ fun <T : Any> RequestResult<T, RestStatusCodeError>.successOrThrow(): T {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [successOrThrow] variant for an API that defines no business-logic errors, so there is no
|
||||
* [RequestResult.NonSuccess] case to handle. Exists as a separate overload because Java cannot
|
||||
* bind a [Nothing] error argument to the [RestStatusCodeError] receiver above.
|
||||
*/
|
||||
@JvmName("successOrThrowNoError")
|
||||
@Throws(IOException::class)
|
||||
fun <T : Any> RequestResult<T, Nothing>.successOrThrow(): T {
|
||||
return when (this) {
|
||||
is RequestResult.Success -> result
|
||||
is RequestResult.RetryableNetworkError -> throw networkError
|
||||
is RequestResult.NonSuccess -> error("Branch is unreachable")
|
||||
is RequestResult.ApplicationError -> throw when (val error = cause) {
|
||||
is IOException, is RuntimeException -> error
|
||||
else -> RuntimeException(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : Any> WebsocketResponse.toRequestResult(clazz: KClass<T>): RequestResult<T, RestStatusCodeError> {
|
||||
return if (status < 200 || status > 299) {
|
||||
RequestResult.NonSuccess(RestStatusCodeError(status, headers, body?.toByteArray()))
|
||||
|
||||
+15
-11
@@ -5,8 +5,10 @@
|
||||
|
||||
package org.whispersystems.signalservice.api.account
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.signal.core.util.Base64
|
||||
import org.signal.core.util.Base64.encodeUrlSafeWithoutPadding
|
||||
import org.signal.libsignal.net.AuthDevicesService
|
||||
import org.signal.libsignal.net.RequestResult
|
||||
import org.signal.libsignal.usernames.BaseUsernameException
|
||||
import org.signal.libsignal.usernames.Username
|
||||
@@ -21,7 +23,6 @@ import org.whispersystems.signalservice.api.push.UsernameLinkComponents
|
||||
import org.whispersystems.signalservice.api.websocket.SignalWebSocket
|
||||
import org.whispersystems.signalservice.internal.push.ConfirmUsernameRequest
|
||||
import org.whispersystems.signalservice.internal.push.ConfirmUsernameResponse
|
||||
import org.whispersystems.signalservice.internal.push.GcmRegistrationId
|
||||
import org.whispersystems.signalservice.internal.push.PhoneNumberDiscoverabilityRequest
|
||||
import org.whispersystems.signalservice.internal.push.PushServiceSocket
|
||||
import org.whispersystems.signalservice.internal.push.ReserveUsernameRequest
|
||||
@@ -52,21 +53,24 @@ class AccountApi(private val authWebSocket: SignalWebSocket.AuthenticatedWebSock
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT /v1/accounts/gcm
|
||||
* - 200: Success
|
||||
* Sets the FCM push token the server should use to notify this device of new messages.
|
||||
*/
|
||||
fun setFcmToken(fcmToken: String): NetworkResult<Unit> {
|
||||
val request = WebSocketRequestMessage.put("/v1/accounts/gcm", GcmRegistrationId(fcmToken, true))
|
||||
return NetworkResult.fromWebSocketRequest(authWebSocket, request)
|
||||
fun setFcmToken(fcmToken: String): RequestResult<Unit, Nothing> {
|
||||
return runBlocking {
|
||||
authWebSocket.runCatchingWithChatConnection { connection ->
|
||||
AuthDevicesService(connection).setPushToken(fcmToken)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /v1/account/gcm
|
||||
* - 204: Success
|
||||
* Removes any push tokens associated with this device. Afterwards, the server will assume this device
|
||||
* polls for new messages over an open websocket.
|
||||
*/
|
||||
fun clearFcmToken(): NetworkResult<Unit> {
|
||||
val request = WebSocketRequestMessage.delete("/v1/accounts/gcm")
|
||||
return NetworkResult.fromWebSocketRequest(authWebSocket, request)
|
||||
suspend fun clearFcmToken(): RequestResult<Unit, Nothing> {
|
||||
return authWebSocket.runCatchingWithChatConnection { connection ->
|
||||
AuthDevicesService(connection).clearPushToken()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user