Allow install of nightlies with the same version code but newer upload dates.

This commit is contained in:
Greyson Parrelli 2023-11-07 12:51:09 -05:00
parent ed8953c430
commit ac1171d43b
3 changed files with 24 additions and 8 deletions

View file

@ -12,6 +12,7 @@ import android.content.pm.PackageInstaller
import org.signal.core.util.getParcelableExtraCompat
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.apkupdate.ApkUpdateNotifications.FailureReason
import org.thoughtcrime.securesms.keyvalue.SignalStore
/**
* This is the receiver that is triggered by the [PackageInstaller] to notify of various events. Package installation is initiated
@ -36,6 +37,7 @@ class ApkUpdatePackageInstallerReceiver : BroadcastReceiver() {
when (statusCode) {
PackageInstaller.STATUS_SUCCESS -> {
Log.i(TAG, "Update installed successfully!")
SignalStore.apkUpdate().lastApkUploadTime = SignalStore.apkUpdate().pendingApkUploadTime
ApkUpdateNotifications.showAutoUpdateSuccess(context)
}
PackageInstaller.STATUS_PENDING_USER_ACTION -> handlePendingUserAction(context, userInitiated, intent!!)

View file

@ -81,8 +81,9 @@ class ApkUpdateJob private constructor(parameters: Parameters) : BaseJob(paramet
Log.d(TAG, "Got descriptor: $updateDescriptor")
}
if (updateDescriptor.versionCode > getCurrentAppVersionCode()) {
Log.i(TAG, "Newer version code available. Current: ${getCurrentAppVersionCode()}, Update: ${updateDescriptor.versionCode}")
val currentVersionCode = getCurrentAppVersionCode()
if (updateDescriptor.versionCode > currentVersionCode || (updateDescriptor.versionCode == currentVersionCode && (updateDescriptor.uploadTimestamp ?: 0) > SignalStore.apkUpdate().lastApkUploadTime)) {
Log.i(TAG, "Newer version code available. Current: (versionCode: ${getCurrentAppVersionCode()}, uploadTime: ${SignalStore.apkUpdate().lastApkUploadTime}), Update: (versionCode: ${updateDescriptor.versionCode}, uploadTime: ${updateDescriptor.uploadTimestamp})")
val digest: ByteArray = Hex.fromStringCondensed(updateDescriptor.digest)
val downloadStatus: DownloadStatus = getDownloadStatus(updateDescriptor.url, digest)
@ -93,10 +94,10 @@ class ApkUpdateJob private constructor(parameters: Parameters) : BaseJob(paramet
handleDownloadComplete(downloadStatus.downloadId)
} else if (downloadStatus.status == DownloadStatus.Status.MISSING) {
Log.i(TAG, "Download status missing, starting download...")
handleDownloadStart(updateDescriptor.url, updateDescriptor.versionName, digest)
handleDownloadStart(updateDescriptor.url, updateDescriptor.versionName, digest, updateDescriptor.uploadTimestamp ?: 0)
}
} else {
Log.d(TAG, "Version code is the same or older than our own. Current: ${getCurrentAppVersionCode()}, Update: ${updateDescriptor.versionCode}")
Log.d(TAG, "Version code is the same or older than our own. Current: (versionCode: ${getCurrentAppVersionCode()}, uploadTime: ${SignalStore.apkUpdate().lastApkUploadTime}), Update: (versionCode: ${updateDescriptor.versionCode}, uploadTime: ${updateDescriptor.uploadTimestamp})")
}
SignalStore.apkUpdate().lastSuccessfulCheck = System.currentTimeMillis()
@ -155,7 +156,7 @@ class ApkUpdateJob private constructor(parameters: Parameters) : BaseJob(paramet
return DownloadStatus(DownloadStatus.Status.MISSING, -1)
}
private fun handleDownloadStart(uri: String?, versionName: String?, digest: ByteArray) {
private fun handleDownloadStart(uri: String?, versionName: String?, digest: ByteArray, uploadTimestamp: Long) {
deleteExistingDownloadedApks(context)
val downloadRequest = DownloadManager.Request(Uri.parse(uri)).apply {
@ -169,7 +170,7 @@ class ApkUpdateJob private constructor(parameters: Parameters) : BaseJob(paramet
val downloadId = context.getDownloadManager().enqueue(downloadRequest)
// DownloadManager will trigger [UpdateApkReadyListener] when finished via a broadcast
SignalStore.apkUpdate().setDownloadAttributes(downloadId, digest)
SignalStore.apkUpdate().setDownloadAttributes(downloadId, digest, uploadTimestamp)
}
private fun handleDownloadComplete(downloadId: Long) {
@ -216,7 +217,10 @@ class ApkUpdateJob private constructor(parameters: Parameters) : BaseJob(paramet
val url: String? = null,
@JsonProperty("sha256sum")
val digest: String? = null
val digest: String? = null,
@JsonProperty
val uploadTimestamp: Long? = null
)
private class DownloadStatus(val status: Status, val downloadId: Long) {

View file

@ -11,6 +11,8 @@ internal class ApkUpdateValues(store: KeyValueStore) : SignalStoreValues(store)
private const val DIGEST = "apk_update.digest"
private const val AUTO_UPDATE = "apk_update.auto_update"
private const val LAST_SUCCESSFUL_CHECK = "apk_update.last_successful_check"
private const val LAST_APK_UPLOAD_TIME = "apk_update.last_apk_upload_time"
private const val PENDING_APK_UPLOAD_TIME = "apk_update.pending_apk_upload_time"
}
override fun onFirstEverAppLaunch() = Unit
@ -21,11 +23,18 @@ internal class ApkUpdateValues(store: KeyValueStore) : SignalStoreValues(store)
var autoUpdate: Boolean by booleanValue(AUTO_UPDATE, true)
var lastSuccessfulCheck: Long by longValue(LAST_SUCCESSFUL_CHECK, 0)
fun setDownloadAttributes(id: Long, digest: ByteArray?) {
/** The upload of the last APK we installed */
var lastApkUploadTime: Long by longValue(LAST_APK_UPLOAD_TIME, 0)
/** The upload time of the APK we're trying to install */
val pendingApkUploadTime: Long by longValue(PENDING_APK_UPLOAD_TIME, 0)
fun setDownloadAttributes(id: Long, digest: ByteArray?, apkUploadTime: Long) {
store
.beginWrite()
.putLong(DOWNLOAD_ID, id)
.putBlob(DIGEST, digest)
.putLong(PENDING_APK_UPLOAD_TIME, apkUploadTime)
.commit()
}
@ -34,6 +43,7 @@ internal class ApkUpdateValues(store: KeyValueStore) : SignalStoreValues(store)
.beginWrite()
.putLong(DOWNLOAD_ID, -1)
.putBlob(DIGEST, null)
.putLong(PENDING_APK_UPLOAD_TIME, 0)
.commit()
}
}