mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-28 04:34:21 +01:00
Fix backup state observation and expand logging.
This commit is contained in:
@@ -95,19 +95,19 @@ class BackupStateObserver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val internalBackupState = MutableStateFlow(getNonIOBackupState())
|
private val internalBackupState = MutableStateFlow(getNonIOBackupState())
|
||||||
private val backupStateRefreshRequest = MutableSharedFlow<Unit>()
|
private val backupStateRefreshRequest = MutableSharedFlow<Unit>(replay = 1)
|
||||||
|
|
||||||
val backupState: StateFlow<BackupState> = internalBackupState
|
val backupState: StateFlow<BackupState> = internalBackupState
|
||||||
|
|
||||||
init {
|
init {
|
||||||
scope.launch(SignalDispatchers.IO) {
|
scope.launch(SignalDispatchers.IO) {
|
||||||
performDatabaseBackupStateRefresh()
|
performDatabaseBackupStateRefresh()
|
||||||
}
|
|
||||||
|
|
||||||
scope.launch(SignalDispatchers.IO) {
|
requestBackupStateRefresh()
|
||||||
backupStateRefreshRequest
|
backupStateRefreshRequest
|
||||||
.throttleLatest(100.milliseconds)
|
.throttleLatest(100.milliseconds)
|
||||||
.collect {
|
.collect {
|
||||||
|
Log.d(TAG, "Dispatching refresh")
|
||||||
performFullBackupStateRefresh()
|
performFullBackupStateRefresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,19 +160,20 @@ class BackupStateObserver(
|
|||||||
@WorkerThread
|
@WorkerThread
|
||||||
private fun getDatabaseBackupState(): BackupState {
|
private fun getDatabaseBackupState(): BackupState {
|
||||||
if (SignalStore.backup.backupTier != MessageBackupTier.PAID) {
|
if (SignalStore.backup.backupTier != MessageBackupTier.PAID) {
|
||||||
Log.d(TAG, "No additional information available without accessing the network.")
|
Log.d(TAG, "[getDatabaseBackupState] No additional information for non PAID backup available without accessing the network.")
|
||||||
return getNonIOBackupState()
|
return getNonIOBackupState()
|
||||||
}
|
}
|
||||||
|
|
||||||
val latestPayment = SignalDatabase.inAppPayments.getLatestInAppPaymentByType(InAppPaymentType.RECURRING_BACKUP)
|
val latestPayment = SignalDatabase.inAppPayments.getLatestInAppPaymentByType(InAppPaymentType.RECURRING_BACKUP)
|
||||||
if (latestPayment == null) {
|
if (latestPayment == null) {
|
||||||
Log.d(TAG, "No additional information is available in the local database.")
|
Log.d(TAG, "[getDatabaseBackupState] No additional information for PAID backup is available in the local database.")
|
||||||
return getNonIOBackupState()
|
return getNonIOBackupState()
|
||||||
}
|
}
|
||||||
|
|
||||||
val price = latestPayment.data.amount!!.toFiatMoney()
|
val price = latestPayment.data.amount!!.toFiatMoney()
|
||||||
val isPending = SignalDatabase.inAppPayments.hasPendingBackupRedemption()
|
val isPending = SignalDatabase.inAppPayments.hasPendingBackupRedemption()
|
||||||
if (isPending) {
|
if (isPending) {
|
||||||
|
Log.d(TAG, "[getDatabaseBackupState] We have a pending subscription.")
|
||||||
return BackupState.Pending(price = price)
|
return BackupState.Pending(price = price)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +185,7 @@ class BackupStateObserver(
|
|||||||
|
|
||||||
val isCanceled = latestPayment.data.cancellation != null
|
val isCanceled = latestPayment.data.cancellation != null
|
||||||
if (isCanceled) {
|
if (isCanceled) {
|
||||||
|
Log.d(TAG, "[getDatabaseBackupState] We have a canceled subscription.")
|
||||||
return BackupState.Canceled(
|
return BackupState.Canceled(
|
||||||
messageBackupsType = paidBackupType,
|
messageBackupsType = paidBackupType,
|
||||||
renewalTime = latestPayment.endOfPeriod
|
renewalTime = latestPayment.endOfPeriod
|
||||||
@@ -191,6 +193,7 @@ class BackupStateObserver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (SignalStore.backup.subscriptionStateMismatchDetected) {
|
if (SignalStore.backup.subscriptionStateMismatchDetected) {
|
||||||
|
Log.d(TAG, "[getDatabaseBackupState] We have a subscription state mismatch with Google Play.")
|
||||||
return BackupState.SubscriptionMismatchMissingGooglePlay(
|
return BackupState.SubscriptionMismatchMissingGooglePlay(
|
||||||
messageBackupsType = paidBackupType,
|
messageBackupsType = paidBackupType,
|
||||||
renewalTime = latestPayment.endOfPeriod
|
renewalTime = latestPayment.endOfPeriod
|
||||||
@@ -198,12 +201,14 @@ class BackupStateObserver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (latestPayment.endOfPeriod < System.currentTimeMillis().milliseconds) {
|
if (latestPayment.endOfPeriod < System.currentTimeMillis().milliseconds) {
|
||||||
|
Log.d(TAG, "[getDatabaseBackupState] We have an inactive subscription.")
|
||||||
return BackupState.Inactive(
|
return BackupState.Inactive(
|
||||||
messageBackupsType = paidBackupType,
|
messageBackupsType = paidBackupType,
|
||||||
renewalTime = latestPayment.endOfPeriod
|
renewalTime = latestPayment.endOfPeriod
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "[getDatabaseBackupState] We have an active subscription.")
|
||||||
return BackupState.ActivePaid(
|
return BackupState.ActivePaid(
|
||||||
messageBackupsType = paidBackupType,
|
messageBackupsType = paidBackupType,
|
||||||
price = price,
|
price = price,
|
||||||
@@ -213,16 +218,17 @@ class BackupStateObserver(
|
|||||||
|
|
||||||
private suspend fun performDatabaseBackupStateRefresh() {
|
private suspend fun performDatabaseBackupStateRefresh() {
|
||||||
if (!RemoteConfig.messageBackups) {
|
if (!RemoteConfig.messageBackups) {
|
||||||
|
Log.d(TAG, "[performDatabaseBackupStateRefresh] Dropping refresh for disabled feature.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SignalStore.account.isRegistered) {
|
if (!SignalStore.account.isRegistered) {
|
||||||
Log.d(TAG, "Dropping refresh for unregistered user.")
|
Log.d(TAG, "[performDatabaseBackupStateRefresh] Dropping refresh for unregistered user.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backupState.value !is BackupState.LocalStore) {
|
if (backupState.value !is BackupState.LocalStore) {
|
||||||
Log.d(TAG, "Dropping database refresh for non-local store state.")
|
Log.d(TAG, "[performDatabaseBackupStateRefresh] Dropping database refresh for non-local store state.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,15 +237,16 @@ class BackupStateObserver(
|
|||||||
|
|
||||||
private suspend fun performFullBackupStateRefresh() {
|
private suspend fun performFullBackupStateRefresh() {
|
||||||
if (!RemoteConfig.messageBackups) {
|
if (!RemoteConfig.messageBackups) {
|
||||||
|
Log.d(TAG, "[performFullBackupStateRefresh] Dropping refresh for disabled feature.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SignalStore.account.isRegistered) {
|
if (!SignalStore.account.isRegistered) {
|
||||||
Log.d(TAG, "Dropping refresh for unregistered user.")
|
Log.d(TAG, "[performFullBackupStateRefresh] Dropping refresh for unregistered user.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Performing refresh.")
|
Log.d(TAG, "[performFullBackupStateRefresh] Performing refresh.")
|
||||||
withContext(SignalDispatchers.IO) {
|
withContext(SignalDispatchers.IO) {
|
||||||
val latestInAppPayment = SignalDatabase.inAppPayments.getLatestInAppPaymentByType(InAppPaymentType.RECURRING_BACKUP)
|
val latestInAppPayment = SignalDatabase.inAppPayments.getLatestInAppPaymentByType(InAppPaymentType.RECURRING_BACKUP)
|
||||||
internalBackupState.emit(getNetworkBackupState(latestInAppPayment))
|
internalBackupState.emit(getNetworkBackupState(latestInAppPayment))
|
||||||
@@ -251,28 +258,28 @@ class BackupStateObserver(
|
|||||||
*/
|
*/
|
||||||
private suspend fun getNetworkBackupState(lastPurchase: InAppPaymentTable.InAppPayment?): BackupState {
|
private suspend fun getNetworkBackupState(lastPurchase: InAppPaymentTable.InAppPayment?): BackupState {
|
||||||
if (lastPurchase?.state == InAppPaymentTable.State.PENDING) {
|
if (lastPurchase?.state == InAppPaymentTable.State.PENDING) {
|
||||||
Log.d(TAG, "We have a pending subscription.")
|
Log.d(TAG, "[getNetworkBackupState] We have a pending subscription.")
|
||||||
return BackupState.Pending(
|
return BackupState.Pending(
|
||||||
price = lastPurchase.data.amount!!.toFiatMoney()
|
price = lastPurchase.data.amount!!.toFiatMoney()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SignalStore.backup.subscriptionStateMismatchDetected) {
|
if (SignalStore.backup.subscriptionStateMismatchDetected) {
|
||||||
Log.d(TAG, "[subscriptionStateMismatchDetected] A mismatch was detected.")
|
Log.d(TAG, "[getNetworkBackupState][subscriptionStateMismatchDetected] A mismatch was detected.")
|
||||||
|
|
||||||
val hasActiveGooglePlayBillingSubscription = when (val purchaseResult = AppDependencies.billingApi.queryPurchases()) {
|
val hasActiveGooglePlayBillingSubscription = when (val purchaseResult = AppDependencies.billingApi.queryPurchases()) {
|
||||||
is BillingPurchaseResult.Success -> {
|
is BillingPurchaseResult.Success -> {
|
||||||
Log.d(TAG, "[subscriptionStateMismatchDetected] Found a purchase: $purchaseResult")
|
Log.d(TAG, "[getNetworkBackupState][subscriptionStateMismatchDetected] Found a purchase: $purchaseResult")
|
||||||
purchaseResult.isAcknowledged && purchaseResult.isAutoRenewing
|
purchaseResult.isAcknowledged && purchaseResult.isAutoRenewing
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
Log.d(TAG, "[subscriptionStateMismatchDetected] No purchase found in Google Play Billing: $purchaseResult")
|
Log.d(TAG, "[getNetworkBackupState][subscriptionStateMismatchDetected] No purchase found in Google Play Billing: $purchaseResult")
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
} || SignalStore.backup.backupTierInternalOverride == MessageBackupTier.PAID
|
} || SignalStore.backup.backupTierInternalOverride == MessageBackupTier.PAID
|
||||||
|
|
||||||
Log.d(TAG, "[subscriptionStateMismatchDetected] hasActiveGooglePlayBillingSubscription: $hasActiveGooglePlayBillingSubscription")
|
Log.d(TAG, "[getNetworkBackupState][subscriptionStateMismatchDetected] hasActiveGooglePlayBillingSubscription: $hasActiveGooglePlayBillingSubscription")
|
||||||
|
|
||||||
val activeSubscription = withContext(Dispatchers.IO) {
|
val activeSubscription = withContext(Dispatchers.IO) {
|
||||||
RecurringInAppPaymentRepository.getActiveSubscriptionSync(InAppPaymentSubscriberRecord.Type.BACKUP).getOrNull()
|
RecurringInAppPaymentRepository.getActiveSubscriptionSync(InAppPaymentSubscriberRecord.Type.BACKUP).getOrNull()
|
||||||
@@ -280,17 +287,18 @@ class BackupStateObserver(
|
|||||||
|
|
||||||
val hasActiveSignalSubscription = activeSubscription?.isActive == true
|
val hasActiveSignalSubscription = activeSubscription?.isActive == true
|
||||||
|
|
||||||
Log.d(TAG, "[subscriptionStateMismatchDetected] hasActiveSignalSubscription: $hasActiveSignalSubscription")
|
Log.d(TAG, "[getNetworkBackupState][subscriptionStateMismatchDetected] hasActiveSignalSubscription: $hasActiveSignalSubscription")
|
||||||
|
|
||||||
when {
|
when {
|
||||||
hasActiveSignalSubscription && !hasActiveGooglePlayBillingSubscription -> {
|
hasActiveSignalSubscription && !hasActiveGooglePlayBillingSubscription -> {
|
||||||
val type = buildPaidTypeFromSubscription(activeSubscription.activeSubscription)
|
val type = buildPaidTypeFromSubscription(activeSubscription.activeSubscription)
|
||||||
|
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
Log.d(TAG, "[subscriptionMismatchDetected] failed to load backup configuration. Likely a network error.")
|
Log.d(TAG, "[getNetworkBackupState][subscriptionMismatchDetected] failed to load backup configuration. Likely a network error.")
|
||||||
return getStateOnError()
|
return getStateOnError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "[getNetworkBackupState][subscriptionMismatchDetected] found a subscription mismatch and successfully loaded configuration.")
|
||||||
return BackupState.SubscriptionMismatchMissingGooglePlay(
|
return BackupState.SubscriptionMismatchMissingGooglePlay(
|
||||||
messageBackupsType = type,
|
messageBackupsType = type,
|
||||||
renewalTime = activeSubscription.activeSubscription.endOfCurrentPeriod.seconds
|
renewalTime = activeSubscription.activeSubscription.endOfCurrentPeriod.seconds
|
||||||
@@ -298,17 +306,17 @@ class BackupStateObserver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
hasActiveSignalSubscription && hasActiveGooglePlayBillingSubscription -> {
|
hasActiveSignalSubscription && hasActiveGooglePlayBillingSubscription -> {
|
||||||
Log.d(TAG, "Found active signal subscription and active google play subscription. Clearing mismatch.")
|
Log.d(TAG, "[getNetworkBackupState][subscriptionMismatchDetected] Found active signal subscription and active google play subscription. Clearing mismatch.")
|
||||||
SignalStore.backup.subscriptionStateMismatchDetected = false
|
SignalStore.backup.subscriptionStateMismatchDetected = false
|
||||||
}
|
}
|
||||||
|
|
||||||
!hasActiveSignalSubscription && !hasActiveGooglePlayBillingSubscription -> {
|
!hasActiveSignalSubscription && !hasActiveGooglePlayBillingSubscription -> {
|
||||||
Log.d(TAG, "Found inactive signal subscription and inactive google play subscription. Clearing mismatch.")
|
Log.d(TAG, "[getNetworkBackupState][subscriptionMismatchDetected] Found inactive signal subscription and inactive google play subscription. Clearing mismatch.")
|
||||||
SignalStore.backup.subscriptionStateMismatchDetected = false
|
SignalStore.backup.subscriptionStateMismatchDetected = false
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
Log.w(TAG, "Hit unexpected subscription mismatch state: signal:false, google:true")
|
Log.w(TAG, "[getNetworkBackupState][subscriptionMismatchDetected] Hit unexpected subscription mismatch state: signal:false, google:true")
|
||||||
return BackupState.NotFound
|
return BackupState.NotFound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,7 +332,7 @@ class BackupStateObserver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
null -> {
|
null -> {
|
||||||
Log.d(TAG, "Updating UI state with NONE null tier.")
|
Log.d(TAG, "[getNetworkBackupState] Updating UI state with NONE null tier.")
|
||||||
return BackupState.None
|
return BackupState.None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,14 +343,16 @@ class BackupStateObserver(
|
|||||||
*/
|
*/
|
||||||
private fun getStateOnError(): BackupState {
|
private fun getStateOnError(): BackupState {
|
||||||
return if (useDatabaseFallbackOnNetworkError) {
|
return if (useDatabaseFallbackOnNetworkError) {
|
||||||
|
Log.d(TAG, "[getStateOnError] Getting fallback state from database.")
|
||||||
getDatabaseBackupState()
|
getDatabaseBackupState()
|
||||||
} else {
|
} else {
|
||||||
|
Log.d(TAG, "[getStateOnError] Displaying error without database.")
|
||||||
BackupState.Error
|
BackupState.Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getPaidBackupState(lastPurchase: InAppPaymentTable.InAppPayment?): BackupState {
|
private suspend fun getPaidBackupState(lastPurchase: InAppPaymentTable.InAppPayment?): BackupState {
|
||||||
Log.d(TAG, "Attempting to retrieve subscription details for active PAID backup.")
|
Log.d(TAG, "[getPaidBackupState] Attempting to retrieve subscription details for active PAID backup.")
|
||||||
|
|
||||||
val typeResult = withContext(Dispatchers.IO) {
|
val typeResult = withContext(Dispatchers.IO) {
|
||||||
BackupRepository.getPaidType()
|
BackupRepository.getPaidType()
|
||||||
@@ -350,52 +360,62 @@ class BackupStateObserver(
|
|||||||
|
|
||||||
val type = if (typeResult is NetworkResult.Success) typeResult.result else null
|
val type = if (typeResult is NetworkResult.Success) typeResult.result else null
|
||||||
|
|
||||||
Log.d(TAG, "Attempting to retrieve current subscription...")
|
Log.d(TAG, "[getPaidBackupState] Attempting to retrieve current subscription...")
|
||||||
val activeSubscription = withContext(Dispatchers.IO) {
|
val activeSubscription = withContext(Dispatchers.IO) {
|
||||||
RecurringInAppPaymentRepository.getActiveSubscriptionSync(InAppPaymentSubscriberRecord.Type.BACKUP)
|
RecurringInAppPaymentRepository.getActiveSubscriptionSync(InAppPaymentSubscriberRecord.Type.BACKUP)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (activeSubscription.isSuccess) {
|
return if (activeSubscription.isSuccess) {
|
||||||
Log.d(TAG, "Retrieved subscription details.")
|
Log.d(TAG, "[getPaidBackupState] Retrieved subscription details.")
|
||||||
|
|
||||||
val subscription = activeSubscription.getOrThrow().activeSubscription
|
val subscription = activeSubscription.getOrThrow().activeSubscription
|
||||||
if (subscription != null) {
|
if (subscription != null) {
|
||||||
Log.d(TAG, "Subscription found. Updating UI state with subscription details. Status: ${subscription.status}")
|
Log.d(TAG, "[getPaidBackupState] Subscription found. Updating UI state with subscription details. Status: ${subscription.status}")
|
||||||
|
|
||||||
val subscriberType = type ?: buildPaidTypeFromSubscription(subscription)
|
val subscriberType = type ?: buildPaidTypeFromSubscription(subscription)
|
||||||
if (subscriberType == null) {
|
if (subscriberType == null) {
|
||||||
Log.d(TAG, "Failed to create backup type. Possible network error.")
|
Log.d(TAG, "[getPaidBackupState] Failed to create backup type. Possible network error.")
|
||||||
|
|
||||||
getStateOnError()
|
getStateOnError()
|
||||||
} else {
|
} else {
|
||||||
when {
|
when {
|
||||||
subscription.isCanceled && subscription.isActive -> BackupState.Canceled(
|
subscription.isCanceled && subscription.isActive -> {
|
||||||
messageBackupsType = subscriberType,
|
Log.d(TAG, "[getPaidBackupState] Found a canceled subscription.")
|
||||||
renewalTime = subscription.endOfCurrentPeriod.seconds
|
BackupState.Canceled(
|
||||||
)
|
messageBackupsType = subscriberType,
|
||||||
|
renewalTime = subscription.endOfCurrentPeriod.seconds
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
subscription.isActive -> BackupState.ActivePaid(
|
subscription.isActive -> {
|
||||||
messageBackupsType = subscriberType,
|
Log.d(TAG, "[getPaidBackupState] Found an active subscription.")
|
||||||
price = FiatMoney.fromSignalNetworkAmount(subscription.amount, Currency.getInstance(subscription.currency)),
|
BackupState.ActivePaid(
|
||||||
renewalTime = subscription.endOfCurrentPeriod.seconds
|
messageBackupsType = subscriberType,
|
||||||
)
|
price = FiatMoney.fromSignalNetworkAmount(subscription.amount, Currency.getInstance(subscription.currency)),
|
||||||
|
renewalTime = subscription.endOfCurrentPeriod.seconds
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
else -> BackupState.Inactive(
|
else -> {
|
||||||
messageBackupsType = subscriberType,
|
Log.d(TAG, "[getPaidBackupState] Found an inactive subscription.")
|
||||||
renewalTime = subscription.endOfCurrentPeriod.seconds
|
BackupState.Inactive(
|
||||||
)
|
messageBackupsType = subscriberType,
|
||||||
|
renewalTime = subscription.endOfCurrentPeriod.seconds
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "ActiveSubscription had null subscription object.")
|
Log.d(TAG, "[getPaidBackupState] ActiveSubscription had null subscription object.")
|
||||||
if (SignalStore.backup.areBackupsEnabled) {
|
if (SignalStore.backup.areBackupsEnabled) {
|
||||||
BackupState.NotFound
|
BackupState.NotFound
|
||||||
} else if (lastPurchase != null && lastPurchase.endOfPeriod > System.currentTimeMillis().milliseconds) {
|
} else if (lastPurchase != null && lastPurchase.endOfPeriod > System.currentTimeMillis().milliseconds) {
|
||||||
val canceledType = type ?: buildPaidTypeFromInAppPayment(lastPurchase)
|
val canceledType = type ?: buildPaidTypeFromInAppPayment(lastPurchase)
|
||||||
if (canceledType == null) {
|
if (canceledType == null) {
|
||||||
Log.w(TAG, "Failed to load canceled type information. Possible network error.")
|
Log.w(TAG, "[getPaidBackupState] Failed to load canceled type information. Possible network error.")
|
||||||
getStateOnError()
|
getStateOnError()
|
||||||
} else {
|
} else {
|
||||||
|
Log.d(TAG, "[getPaidBackupState] Found a canceled subscription via the last purchase object.")
|
||||||
BackupState.Canceled(
|
BackupState.Canceled(
|
||||||
messageBackupsType = canceledType,
|
messageBackupsType = canceledType,
|
||||||
renewalTime = lastPurchase.endOfPeriod
|
renewalTime = lastPurchase.endOfPeriod
|
||||||
@@ -404,9 +424,10 @@ class BackupStateObserver(
|
|||||||
} else {
|
} else {
|
||||||
val inactiveType = type ?: buildPaidTypeWithoutPricing()
|
val inactiveType = type ?: buildPaidTypeWithoutPricing()
|
||||||
if (inactiveType == null) {
|
if (inactiveType == null) {
|
||||||
Log.w(TAG, "Failed to load inactive type information. Possible network error.")
|
Log.w(TAG, "[getPaidBackupState] Failed to load inactive type information. Possible network error.")
|
||||||
getStateOnError()
|
getStateOnError()
|
||||||
} else {
|
} else {
|
||||||
|
Log.d(TAG, "[getPaidBackupState] Found an inactive subscription via the last purchase object.")
|
||||||
BackupState.Inactive(
|
BackupState.Inactive(
|
||||||
messageBackupsType = inactiveType,
|
messageBackupsType = inactiveType,
|
||||||
renewalTime = lastPurchase?.endOfPeriod ?: 0.seconds
|
renewalTime = lastPurchase?.endOfPeriod ?: 0.seconds
|
||||||
@@ -415,28 +436,32 @@ class BackupStateObserver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Failed to load ActiveSubscription data. Updating UI state with error.")
|
Log.d(TAG, "[getPaidBackupState] Failed to load ActiveSubscription data. Updating UI state with error.")
|
||||||
getStateOnError()
|
getStateOnError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getFreeBackupState(): BackupState {
|
private suspend fun getFreeBackupState(): BackupState {
|
||||||
|
Log.d(TAG, "[getFreeBackupState] Attempting to retrieve details for active FREE backup.")
|
||||||
|
|
||||||
val type = withContext(Dispatchers.IO) {
|
val type = withContext(Dispatchers.IO) {
|
||||||
BackupRepository.getFreeType()
|
BackupRepository.getFreeType()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type !is NetworkResult.Success) {
|
if (type !is NetworkResult.Success) {
|
||||||
Log.w(TAG, "Failed to load FREE type.", type.getCause())
|
Log.w(TAG, "[getFreeBackupState] Failed to load FREE type.", type.getCause())
|
||||||
return getStateOnError()
|
return getStateOnError()
|
||||||
}
|
}
|
||||||
|
|
||||||
val backupState = if (SignalStore.backup.areBackupsEnabled) {
|
val backupState = if (SignalStore.backup.areBackupsEnabled) {
|
||||||
|
Log.d(TAG, "[getFreeBackupState] Found an active free backup.")
|
||||||
BackupState.ActiveFree(type.result)
|
BackupState.ActiveFree(type.result)
|
||||||
} else {
|
} else {
|
||||||
|
Log.d(TAG, "[getFreeBackupState] Found an inactive free backup.")
|
||||||
BackupState.Inactive(type.result)
|
BackupState.Inactive(type.result)
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Updating UI state with $backupState FREE tier.")
|
Log.d(TAG, "[getFreeBackupState] Updating UI state with $backupState FREE tier.")
|
||||||
return backupState
|
return backupState
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,7 +471,14 @@ class BackupStateObserver(
|
|||||||
* @return A paid type, or null if we were unable to get the backup level configuration.
|
* @return A paid type, or null if we were unable to get the backup level configuration.
|
||||||
*/
|
*/
|
||||||
private fun buildPaidTypeFromSubscription(subscription: ActiveSubscription.Subscription): MessageBackupsType.Paid? {
|
private fun buildPaidTypeFromSubscription(subscription: ActiveSubscription.Subscription): MessageBackupsType.Paid? {
|
||||||
val config = BackupRepository.getBackupLevelConfiguration().successOrThrow()
|
val configResult = BackupRepository.getBackupLevelConfiguration()
|
||||||
|
if (configResult.getCause() != null) {
|
||||||
|
Log.w(TAG, "[buildPaidTypeFromSubscription] failed to build paid type.", configResult.getCause())
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should never throw
|
||||||
|
val config = configResult.successOrThrow()
|
||||||
|
|
||||||
val price = FiatMoney.fromSignalNetworkAmount(subscription.amount, Currency.getInstance(subscription.currency))
|
val price = FiatMoney.fromSignalNetworkAmount(subscription.amount, Currency.getInstance(subscription.currency))
|
||||||
return MessageBackupsType.Paid(
|
return MessageBackupsType.Paid(
|
||||||
@@ -462,7 +494,14 @@ class BackupStateObserver(
|
|||||||
* @return A paid type, or null if we were unable to get the backup level configuration.
|
* @return A paid type, or null if we were unable to get the backup level configuration.
|
||||||
*/
|
*/
|
||||||
private fun buildPaidTypeFromInAppPayment(inAppPayment: InAppPaymentTable.InAppPayment): MessageBackupsType.Paid? {
|
private fun buildPaidTypeFromInAppPayment(inAppPayment: InAppPaymentTable.InAppPayment): MessageBackupsType.Paid? {
|
||||||
val config = BackupRepository.getBackupLevelConfiguration().successOrThrow()
|
val configResult = BackupRepository.getBackupLevelConfiguration()
|
||||||
|
if (configResult.getCause() != null) {
|
||||||
|
Log.w(TAG, "[buildPaidTypeFromInAppPayment] failed to build paid type.", configResult.getCause())
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should never throw
|
||||||
|
val config = configResult.successOrThrow()
|
||||||
|
|
||||||
val price = inAppPayment.data.amount!!.toFiatMoney()
|
val price = inAppPayment.data.amount!!.toFiatMoney()
|
||||||
return MessageBackupsType.Paid(
|
return MessageBackupsType.Paid(
|
||||||
@@ -479,7 +518,14 @@ class BackupStateObserver(
|
|||||||
* @return A paid type, or null if we were unable to get the backup level configuration.
|
* @return A paid type, or null if we were unable to get the backup level configuration.
|
||||||
*/
|
*/
|
||||||
private fun buildPaidTypeWithoutPricing(): MessageBackupsType? {
|
private fun buildPaidTypeWithoutPricing(): MessageBackupsType? {
|
||||||
val config = BackupRepository.getBackupLevelConfiguration().successOrThrow()
|
val configResult = BackupRepository.getBackupLevelConfiguration()
|
||||||
|
if (configResult.getCause() != null) {
|
||||||
|
Log.w(TAG, "[buildPaidTypeWithoutPricing] failed to build paid type.", configResult.getCause())
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should never throw
|
||||||
|
val config = configResult.successOrThrow()
|
||||||
|
|
||||||
return MessageBackupsType.Paid(
|
return MessageBackupsType.Paid(
|
||||||
pricePerMonth = FiatMoney(BigDecimal.ZERO, Currency.getInstance(Locale.getDefault())),
|
pricePerMonth = FiatMoney(BigDecimal.ZERO, Currency.getInstance(Locale.getDefault())),
|
||||||
|
|||||||
Reference in New Issue
Block a user