Update auto update priority policy (#1051)

This commit is contained in:
Mikołaj Pich 2021-01-31 21:46:24 +01:00 committed by GitHub
parent e2ba265048
commit 4984cb9b26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -17,6 +17,7 @@ import com.google.android.play.core.install.model.UpdateAvailability.DEVELOPER_T
import com.google.android.play.core.install.model.UpdateAvailability.UPDATE_AVAILABLE
import com.google.android.play.core.ktx.isFlexibleUpdateAllowed
import com.google.android.play.core.ktx.isImmediateUpdateAllowed
import com.google.android.play.core.ktx.updatePriority
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
import timber.log.Timber
@ -24,40 +25,57 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class UpdateHelper @Inject constructor(@ApplicationContext private val context: Context) {
class UpdateHelper @Inject constructor(
@ApplicationContext private val context: Context,
private val analyticsHelper: AnalyticsHelper,
) {
lateinit var messageContainer: View
companion object {
const val IN_APP_UPDATE_REQUEST_CODE = 1721
const val DAYS_FOR_FLEXIBLE_UPDATE = 7
const val HIGH_PRIORITY_UPDATE = 4
}
private val appUpdateManager by lazy { AppUpdateManagerFactory.create(context) }
private val flexibleUpdateListener = InstallStateUpdatedListener { state ->
when (state.installStatus()) {
PENDING -> Toast.makeText(context, R.string.update_download_started, Toast.LENGTH_SHORT).show()
PENDING -> Toast.makeText(context, R.string.update_download_started, Toast.LENGTH_SHORT)
.show()
DOWNLOADED -> popupSnackBarForCompleteUpdate()
else -> Timber.d("Update state: ${state.installStatus()}")
}
}
private inline val AppUpdateInfo.isImmediateUpdateAvailable: Boolean
get() = updateAvailability() == UPDATE_AVAILABLE && isImmediateUpdateAllowed &&
updatePriority() >= HIGH_PRIORITY_UPDATE
get() {
val days = clientVersionStalenessDays() ?: 0
val isUpdatePriorityAllowUpdate = when (updatePriority) {
5 -> true
4 -> days > 7
3 -> days > 30
else -> false
}
return updateAvailability() == UPDATE_AVAILABLE && isImmediateUpdateAllowed && isUpdatePriorityAllowUpdate
}
private inline val AppUpdateInfo.isFlexibleUpdateAvailable: Boolean
get() = updateAvailability() == UPDATE_AVAILABLE && isFlexibleUpdateAllowed &&
clientVersionStalenessDays() ?: 0 >= DAYS_FOR_FLEXIBLE_UPDATE
get() {
val days = clientVersionStalenessDays() ?: 0
val isUpdatePriorityAllowUpdate = when (updatePriority) {
4, 3, 2 -> true
1 -> days >= 7
0 -> false
else -> false
}
return updateAvailability() == UPDATE_AVAILABLE && isFlexibleUpdateAllowed && isUpdatePriorityAllowUpdate
}
fun checkAndInstallUpdates(activity: Activity) {
Timber.d("Checking for updates...")
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
when {
appUpdateInfo.isImmediateUpdateAvailable -> startUpdate(activity, appUpdateInfo, IMMEDIATE)
appUpdateInfo.isImmediateUpdateAvailable -> {
startUpdate(activity, appUpdateInfo, IMMEDIATE)
}
appUpdateInfo.isFlexibleUpdateAvailable -> {
appUpdateManager.registerListener(flexibleUpdateListener)
startUpdate(activity, appUpdateInfo, FLEXIBLE)
@ -68,15 +86,20 @@ class UpdateHelper @Inject constructor(@ApplicationContext private val context:
}
private fun startUpdate(activity: Activity, appUpdateInfo: AppUpdateInfo, updateType: Int) {
Timber.d("Start update ($updateType): $appUpdateInfo")
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo, updateType, activity, IN_APP_UPDATE_REQUEST_CODE
)
}
fun onActivityResult(requestCode: Int, resultCode: Int) {
if (requestCode == IN_APP_UPDATE_REQUEST_CODE && resultCode != RESULT_OK) {
Timber.e("Update failed! Result code: $resultCode")
Toast.makeText(context, R.string.update_failed, Toast.LENGTH_LONG).show()
if (requestCode == IN_APP_UPDATE_REQUEST_CODE) {
if (resultCode != RESULT_OK) {
Timber.i("Update failed! Result code: $resultCode")
Toast.makeText(context, R.string.update_failed, Toast.LENGTH_LONG).show()
}
analyticsHelper.logEvent("inapp_update", "code" to resultCode)
}
}
@ -87,14 +110,23 @@ class UpdateHelper @Inject constructor(@ApplicationContext private val context:
when {
DOWNLOADED == info.installStatus() -> popupSnackBarForCompleteUpdate()
DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS == info.updateAvailability() -> {
startUpdate(activity, info, if (info.isImmediateUpdateAvailable) IMMEDIATE else FLEXIBLE)
startUpdate(
activity = activity,
appUpdateInfo = info,
updateType = if (info.isImmediateUpdateAvailable) IMMEDIATE else FLEXIBLE
)
}
}
}
}
private fun popupSnackBarForCompleteUpdate() {
Snackbar.make(messageContainer, R.string.update_download_success, Snackbar.LENGTH_INDEFINITE).apply {
Timber.d("Show snackbar with update complete")
Snackbar.make(
messageContainer,
R.string.update_download_success,
Snackbar.LENGTH_INDEFINITE
).apply {
setAction(R.string.update_download_success_button) {
appUpdateManager.completeUpdate()
appUpdateManager.unregisterListener(flexibleUpdateListener)
@ -102,4 +134,9 @@ class UpdateHelper @Inject constructor(@ApplicationContext private val context:
show()
}
}
private companion object {
private const val IN_APP_UPDATE_REQUEST_CODE = 1721
}
}