Something went wrong on our end
-
Aleksandras Kostarevas authoredAleksandras Kostarevas authored
UpdateChecking.kt 4.50 KiB
package org.futo.inputmethod.updates
import android.app.job.JobInfo
import android.app.job.JobScheduler
import android.content.ComponentName
import android.content.Context
import android.os.Build
import android.util.Log
import androidx.datastore.preferences.core.edit
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
//import okhttp3.OkHttpClient
//import okhttp3.Request
//import okhttp3.internal.closeQuietly
import org.futo.inputmethod.latin.uix.dataStore
import org.futo.inputmethod.latin.uix.getSetting
import org.futo.inputmethod.latin.BuildConfig
import java.lang.Exception
const val UPDATE_URL = "https://keyboard.futo.org/keyboard_version"
suspend fun checkForUpdate(): UpdateResult? {
if(!BuildConfig.UPDATE_CHECKING || !BuildConfig.UPDATE_CHECKING_NETWORK) return null
else return null
// TODO: Move this code to a different source directory so we can enable or disable
// it per build flavor (e.g. so nightly can have update checking)
/*
return withContext(Dispatchers.IO) {
val httpClient = OkHttpClient()
val request = Request.Builder().method("GET", null).url(UPDATE_URL).build()
try {
val response = httpClient.newCall(request).execute()
val body = response.body
val result = if (body != null) {
val data = body.string().lines()
body.closeQuietly()
val latestVersion = data[0].toInt()
val latestVersionUrl = data[1]
val latestVersionString = data[2]
if(latestVersionUrl.startsWith("https://voiceinput.futo.org/") || latestVersionUrl.startsWith("https://keyboard.futo.org/")){
Log.d("UpdateChecking", "Retrieved update for version ${latestVersionString}")
UpdateResult(
nextVersion = latestVersion,
apkUrl = latestVersionUrl,
nextVersionString = latestVersionString
)
} else {
Log.e("UpdateChecking", "Update URL contains unknown prefix: ${latestVersionUrl}")
null
}
} else {
Log.e("UpdateChecking", "Body of result is null")
null
}
response.closeQuietly()
result
} catch (e: Exception) {
Log.e("UpdateChecking", "Checking update failed with exception")
e.printStackTrace()
null
}
}*/
}
suspend fun checkForUpdateAndSaveToPreferences(context: Context): Boolean {
val updateResult = checkForUpdate()
if(updateResult != null) {
withContext(Dispatchers.IO) {
context.dataStore.edit {
it[LAST_UPDATE_CHECK_RESULT] = Json.encodeToString(updateResult)
it[LAST_UPDATE_CHECK_FAILED] = false
it[DEFER_MANUAL_UPDATE_UNTIL] = System.currentTimeMillis() + MANUAL_UPDATE_PERIOD_MS
}
}
return true
} else {
context.dataStore.edit {
it[LAST_UPDATE_CHECK_FAILED] = true
if(it[DEFER_MANUAL_UPDATE_UNTIL] == null) {
it[DEFER_MANUAL_UPDATE_UNTIL] = System.currentTimeMillis() + MANUAL_UPDATE_PERIOD_MS
}
}
return false
}
}
suspend fun retrieveSavedLastUpdateCheckResult(context: Context): UpdateResult? {
if(!BuildConfig.UPDATE_CHECKING) return null
return UpdateResult.fromString(context.getSetting(LAST_UPDATE_CHECK_RESULT, ""))
}
const val JOB_ID: Int = 15782788
fun scheduleUpdateCheckingJob(context: Context) {
if(!BuildConfig.UPDATE_CHECKING) return
val jobScheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
if(jobScheduler.getPendingJob(JOB_ID) != null) {
Log.i("UpdateChecking", "Job already scheduled, no need to do anything")
return
}
var jobInfoBuilder = JobInfo.Builder(JOB_ID, ComponentName(context, UpdateCheckingService::class.java))
.setPeriodic(1000L * 60L * 60L * 12L) // every 12 hours
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // on unmetered Wi-Fi
.setPersisted(true) // persist after reboots
// Update checking has minimum priority
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
jobInfoBuilder = jobInfoBuilder.setPriority(JobInfo.PRIORITY_MIN)
}
jobScheduler.schedule(jobInfoBuilder.build())
}