UpdateService: Drop dependency upon kovenant

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2023-07-21 13:02:19 +05:30
parent e491992f06
commit bf554853ec

View File

@@ -30,9 +30,11 @@ import com.tonyodev.fetch2.*
import com.tonyodev.fetch2core.DownloadBlock import com.tonyodev.fetch2core.DownloadBlock
import com.tonyodev.fetch2core.FetchObserver import com.tonyodev.fetch2core.FetchObserver
import com.tonyodev.fetch2core.Reason import com.tonyodev.fetch2core.Reason
import nl.komponents.kovenant.task import kotlinx.coroutines.CoroutineScope
import nl.komponents.kovenant.ui.failUi import kotlinx.coroutines.Dispatchers
import nl.komponents.kovenant.ui.successUi import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
@@ -81,6 +83,10 @@ class UpdateService: LifecycleService() {
private var installing = HashSet<String>() private var installing = HashSet<String>()
private var lock = ReentrantLock() private var lock = ReentrantLock()
// Coroutine
private val job = SupervisorJob()
private val serviceScope = CoroutineScope(Dispatchers.IO + job)
fun putInInstalling(packageName: String?) { fun putInInstalling(packageName: String?) {
if (packageName == null) { if (packageName == null) {
return return
@@ -476,84 +482,102 @@ class UpdateService: LifecycleService() {
fun updateApp(app: App, removeExisiting: Boolean = false) { fun updateApp(app: App, removeExisiting: Boolean = false) {
putInInstalling(app.packageName) putInInstalling(app.packageName)
task { serviceScope.launch {
val files = purchaseHelper.purchase( try {
app.packageName, val files = purchaseHelper.purchase(
app.versionCode, app.packageName,
app.offerType app.versionCode,
) app.offerType
)
if (app.dependencies.dependentLibraries.isNotEmpty() && isOAndAbove()) { if (app.dependencies.dependentLibraries.isNotEmpty() && isOAndAbove()) {
app.dependencies.dependentLibraries.forEach { app.dependencies.dependentLibraries.forEach {
if (!isSharedLibraryInstalled(this, it.packageName, it.versionCode)) { if (!isSharedLibraryInstalled(
it.displayName = getString(R.string.downloading_dep, app.displayName) this@UpdateService,
it.iconArtwork = app.iconArtwork it.packageName,
it.versionCode
updateApp(it, removeExisiting) )
while (containsInInstalling(it.packageName) ||
!isSharedLibraryInstalled(this, it.packageName, it.versionCode)
) { ) {
Thread.sleep(1000) it.displayName = getString(R.string.downloading_dep, app.displayName)
it.iconArtwork = app.iconArtwork
updateApp(it, removeExisiting)
while (containsInInstalling(it.packageName) ||
!isSharedLibraryInstalled(
this@UpdateService,
it.packageName,
it.versionCode
)
) {
delay(1000)
}
} }
} }
} }
}
files.filter { it.url.isNotEmpty() } val requests = files.filter { it.url.isNotEmpty() }
.map { RequestBuilder.buildRequest(this, app, it) } .map { RequestBuilder.buildRequest(this@UpdateService, app, it) }
.toList() .toList()
} successUi { requests ->
if (requests.isNotEmpty()) { if (requests.isNotEmpty()) {
if (removeExisiting) { if (removeExisiting) {
/*Remove old fetch group if downloaded earlier, mostly in case of updates*/ /*Remove old fetch group if downloaded earlier, mostly in case of updates*/
fetch.deleteGroup(app.getGroupId(this)) fetch.deleteGroup(app.getGroupId(this@UpdateService))
}
fetch.enqueue(requests) {
Log.i("Updating ${app.displayName}")
}
} else {
removeFromInstalling(app.packageName)
Log.e("Failed to download : ${app.displayName}")
appMetadataListeners.forEach {
it.onAppMetadataStatusError(
getString(R.string.purchase_session_expired),
app
)
}
if (appMetadataListeners.isEmpty()) {
appMetadataPendingEvents.add(
AppMetadataStatus(
getString(R.string.purchase_session_expired),
app
)
)
}
} }
fetch.enqueue(requests) { } catch (exception: Exception) {
Log.i("Updating ${app.displayName}")
}
} else {
removeFromInstalling(app.packageName) removeFromInstalling(app.packageName)
Log.e("Failed to download : ${app.displayName}") var reason = "Unknown"
when (exception) {
is ApiException.AppNotPurchased -> {
reason = getString(R.string.purchase_invalid)
}
is ApiException.AppNotFound -> {
reason = getString(R.string.purchase_not_found)
}
is ApiException.AppNotSupported -> {
reason = getString(R.string.purchase_unsupported)
}
is ApiException.EmptyDownloads -> {
reason = getString(R.string.purchase_no_file)
}
}
appMetadataListeners.forEach { appMetadataListeners.forEach {
it.onAppMetadataStatusError(getString(R.string.purchase_session_expired), app) it.onAppMetadataStatusError(reason, app)
} }
if (appMetadataListeners.isEmpty()) { if (appMetadataListeners.isEmpty()) {
appMetadataPendingEvents.add(AppMetadataStatus(getString(R.string.purchase_session_expired), app)) appMetadataPendingEvents.add(AppMetadataStatus(reason, app))
} }
Log.e("Failed to purchase ${app.displayName} : $reason")
} }
} failUi { failException ->
removeFromInstalling(app.packageName)
var reason = "Unknown"
when (failException) {
is ApiException.AppNotPurchased -> {
reason = getString(R.string.purchase_invalid)
}
is ApiException.AppNotFound -> {
reason = getString(R.string.purchase_not_found)
}
is ApiException.AppNotSupported -> {
reason = getString(R.string.purchase_unsupported)
}
is ApiException.EmptyDownloads -> {
reason = getString(R.string.purchase_no_file)
}
}
appMetadataListeners.forEach {
it.onAppMetadataStatusError(reason, app)
}
if (appMetadataListeners.isEmpty()) {
appMetadataPendingEvents.add(AppMetadataStatus(reason, app))
}
Log.e("Failed to purchase ${app.displayName} : $reason")
} }
} }
@@ -580,30 +604,18 @@ class UpdateService: LifecycleService() {
} }
putInInstalling(packageName) putInInstalling(packageName)
files?.let { downloads -> files?.let { downloads ->
var filesExist = true if (downloads.all { File(it.file).exists() }) {
serviceScope.launch {
downloads.forEach { download ->
filesExist = filesExist && File(download.file).exists()
}
if (filesExist) {
task {
try { try {
val installer = AppInstaller.getInstance(this) AppInstaller.getInstance(this@UpdateService).getPreferredInstaller()
.getPreferredInstaller() .install(
installer.install( packageName,
packageName, files.filter { it.file.endsWith(".apk") }.map { it.file }.toList()
files )
.filter { it.file.endsWith(".apk") } } catch (exception: Exception) {
.map { it.file }.toList()
)
} catch (th: Throwable) {
removeFromInstalling(packageName) removeFromInstalling(packageName)
th.printStackTrace() Log.e(exception.stackTraceToString())
} }
}.fail {
removeFromInstalling(packageName)
Log.e(it.stackTraceToString())
} }
} else { } else {
removeFromInstalling(packageName) removeFromInstalling(packageName)