AppDetailsFragment: Download apps using DownloadWorker
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -129,4 +129,8 @@ class ActionButton : RelativeLayout {
|
||||
fun addOnClickListener(onClickListener: OnClickListener?) {
|
||||
B.btn.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
fun addOnLongClickListener(onLongClickListener: OnLongClickListener?) {
|
||||
B.btn.setOnLongClickListener(onLongClickListener)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,15 +22,12 @@ package com.aurora.store.view.ui.details
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.os.IBinder
|
||||
import android.provider.Settings
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
@@ -44,6 +41,8 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import coil.load
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import com.airbnb.epoxy.EpoxyRecyclerView
|
||||
@@ -65,15 +64,13 @@ import com.aurora.gplayapi.data.models.StreamCluster
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.State
|
||||
import com.aurora.store.data.ViewState
|
||||
import com.aurora.store.data.downloader.DownloadManager
|
||||
import com.aurora.store.data.downloader.getGroupId
|
||||
import com.aurora.store.data.event.BusEvent
|
||||
import com.aurora.store.data.event.InstallerEvent
|
||||
import com.aurora.store.data.installer.AppInstaller
|
||||
import com.aurora.store.data.installer.RootInstaller
|
||||
import com.aurora.store.data.model.DownloadStatus
|
||||
import com.aurora.store.data.providers.AuthProvider
|
||||
import com.aurora.store.data.service.AppMetadataStatusListener
|
||||
import com.aurora.store.data.service.UpdateService
|
||||
import com.aurora.store.data.work.DownloadWorker
|
||||
import com.aurora.store.databinding.FragmentDetailsBinding
|
||||
import com.aurora.store.databinding.LayoutDetailsBetaBinding
|
||||
import com.aurora.store.databinding.LayoutDetailsDescriptionBinding
|
||||
@@ -81,7 +78,6 @@ import com.aurora.store.databinding.LayoutDetailsDevBinding
|
||||
import com.aurora.store.databinding.LayoutDetailsPermissionsBinding
|
||||
import com.aurora.store.databinding.LayoutDetailsReviewBinding
|
||||
import com.aurora.store.util.CommonUtil
|
||||
import com.aurora.store.util.Log
|
||||
import com.aurora.store.util.PackageUtil
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
@@ -98,14 +94,6 @@ import com.aurora.store.viewmodel.details.DetailsClusterViewModel
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.tonyodev.fetch2.AbstractFetchGroupListener
|
||||
import com.tonyodev.fetch2.Download
|
||||
import com.tonyodev.fetch2.Error
|
||||
import com.tonyodev.fetch2.Fetch
|
||||
import com.tonyodev.fetch2.FetchGroup
|
||||
import com.tonyodev.fetch2.FetchGroupListener
|
||||
import com.tonyodev.fetch2.Status
|
||||
import com.tonyodev.fetch2core.DownloadBlock
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
@@ -113,6 +101,7 @@ import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
@@ -130,64 +119,29 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
private val startForStorageManagerResult =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (isRAndAbove() && Environment.isExternalStorageManager()) {
|
||||
updateApp(app)
|
||||
DownloadWorker.enqueueApp(requireContext(), app)
|
||||
} else {
|
||||
toast(R.string.permissions_denied)
|
||||
}
|
||||
}
|
||||
private val startForPermissions =
|
||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
|
||||
if (it) updateApp(app) else toast(R.string.permissions_denied)
|
||||
if (it) {
|
||||
DownloadWorker.enqueueApp(requireContext(), app)
|
||||
} else {
|
||||
toast(R.string.permissions_denied)
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var authData: AuthData
|
||||
private lateinit var app: App
|
||||
private var fetch: Fetch? = null
|
||||
private var downloadManager: DownloadManager? = null
|
||||
|
||||
private var attachToServiceCalled = false
|
||||
private var updateService: UpdateService? = null
|
||||
private var pendingAddListeners = true
|
||||
private var serviceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(name: ComponentName, binder: IBinder) {
|
||||
updateService = (binder as UpdateService.UpdateServiceBinder).getUpdateService()
|
||||
if (::fetchGroupListener.isInitialized && ::appMetadataListener.isInitialized && pendingAddListeners) {
|
||||
updateService!!.registerFetchListener(fetchGroupListener)
|
||||
// appMetadataListener needs to be initialized after the fetchGroupListener
|
||||
updateService!!.registerAppMetadataListener(appMetadataListener)
|
||||
pendingAddListeners = false
|
||||
}
|
||||
if (listOfActionsWhenServiceAttaches.isNotEmpty()) {
|
||||
val iterator = listOfActionsWhenServiceAttaches.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val next = iterator.next()
|
||||
next.run()
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName) {
|
||||
updateService = null
|
||||
attachToServiceCalled = false
|
||||
pendingAddListeners = true
|
||||
}
|
||||
}
|
||||
private lateinit var fetchGroupListener: FetchGroupListener
|
||||
private lateinit var appMetadataListener: AppMetadataStatusListener
|
||||
private lateinit var completionMarker: File
|
||||
private lateinit var inProgressMarker: File
|
||||
|
||||
private var isExternal = false
|
||||
private var isNone = false
|
||||
private var status = Status.NONE
|
||||
private var downloadStatus = DownloadStatus.UNAVAILABLE
|
||||
private var isUpdatable: Boolean = false
|
||||
private var autoDownload: Boolean = false
|
||||
private var downloadOnly: Boolean = false
|
||||
private var uninstallActionEnabled = false
|
||||
|
||||
val listOfActionsWhenServiceAttaches = ArrayList<Runnable>()
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
EventBus.getDefault().register(this)
|
||||
@@ -283,6 +237,38 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
}
|
||||
}
|
||||
|
||||
// Downloads
|
||||
binding.layoutDetailsInstall.imgCancel.setOnClickListener {
|
||||
DownloadWorker.cancelDownload(it.context, app)
|
||||
if (downloadStatus != DownloadStatus.DOWNLOADING) flip(0)
|
||||
}
|
||||
|
||||
val uniqueWorkName = "${DownloadWorker.DOWNLOAD_WORKER}/${app.packageName}"
|
||||
WorkManager.getInstance(view.context)
|
||||
.getWorkInfosForUniqueWorkLiveData(uniqueWorkName)
|
||||
.observe(viewLifecycleOwner) { workList ->
|
||||
workList.getOrNull(0)?.let {
|
||||
if (it.state.isFinished) flip(0) else flip(1)
|
||||
when (it.state) {
|
||||
WorkInfo.State.ENQUEUED,
|
||||
WorkInfo.State.RUNNING -> {
|
||||
downloadStatus = DownloadStatus.DOWNLOADING
|
||||
updateProgress(
|
||||
it.progress.getInt(DownloadWorker.DOWNLOAD_PROGRESS, 0),
|
||||
it.progress.getLong(DownloadWorker.DOWNLOAD_SPEED, -1),
|
||||
it.progress.getLong(DownloadWorker.DOWNLOAD_TIME, -1)
|
||||
)
|
||||
}
|
||||
|
||||
WorkInfo.State.FAILED -> downloadStatus = DownloadStatus.FAILED
|
||||
WorkInfo.State.CANCELLED -> downloadStatus = DownloadStatus.CANCELLED
|
||||
WorkInfo.State.SUCCEEDED -> downloadStatus = DownloadStatus.COMPLETED
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reviews
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
viewModel.reviews.collect {
|
||||
@@ -434,7 +420,6 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
getUpdateServiceInstance()
|
||||
checkAndSetupInstall()
|
||||
super.onResume()
|
||||
}
|
||||
@@ -459,34 +444,24 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun verifyAndInstall(files: List<Download>) {
|
||||
if (downloadOnly)
|
||||
return
|
||||
|
||||
var filesExist = true
|
||||
|
||||
files.forEach { download ->
|
||||
filesExist = filesExist && File(download.file).exists()
|
||||
}
|
||||
|
||||
if (filesExist)
|
||||
install(files)
|
||||
else
|
||||
purchase()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun install(files: List<Download>) {
|
||||
updateActionState(State.IDLE)
|
||||
private fun install() {
|
||||
val files = File(
|
||||
PathUtil.getAppDownloadDir(
|
||||
requireContext(),
|
||||
app.packageName,
|
||||
app.versionCode
|
||||
).pathString
|
||||
).listFiles() ?: return
|
||||
|
||||
val apkFiles = files.filter { it.file.endsWith(".apk") }
|
||||
val apkFiles = files.filter { it.path.endsWith(".apk") }
|
||||
val preferredInstaller =
|
||||
Preferences.getInteger(requireContext(), Preferences.PREFERENCE_INSTALLER_ID)
|
||||
|
||||
if (apkFiles.size > 1 && preferredInstaller == 1) {
|
||||
showDialog(R.string.title_installer, R.string.dialog_desc_native_split)
|
||||
} else {
|
||||
viewModel.install(requireContext(), app.packageName, apkFiles.map { it.file })
|
||||
viewModel.install(requireContext(), app.packageName, apkFiles)
|
||||
|
||||
runOnUiThread {
|
||||
binding.layoutDetailsInstall.btnDownload.setText(getString(R.string.action_installing))
|
||||
@@ -515,16 +490,10 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun attachWhiteListStatus() {
|
||||
|
||||
}
|
||||
|
||||
private fun inflatePartialApp() {
|
||||
if (::app.isInitialized) {
|
||||
attachWhiteListStatus()
|
||||
attachHeader()
|
||||
attachBottomSheet()
|
||||
attachFetch()
|
||||
attachActions()
|
||||
|
||||
if (autoDownload) {
|
||||
@@ -592,21 +561,29 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun startDownload() {
|
||||
when (status) {
|
||||
Status.PAUSED -> {
|
||||
fetch?.resumeGroup(app.getGroupId(requireContext()))
|
||||
}
|
||||
|
||||
Status.DOWNLOADING -> {
|
||||
private fun startDownload(forceDownload: Boolean = false) {
|
||||
when (downloadStatus) {
|
||||
DownloadStatus.DOWNLOADING -> {
|
||||
flip(1)
|
||||
toast("Already downloading")
|
||||
}
|
||||
|
||||
Status.COMPLETED -> {
|
||||
fetch?.getFetchGroup(app.getGroupId(requireContext())) {
|
||||
verifyAndInstall(it.downloads)
|
||||
DownloadStatus.COMPLETED -> {
|
||||
if (forceDownload) {
|
||||
purchase()
|
||||
return
|
||||
}
|
||||
|
||||
// Check if files are still present, else proceed to re-download the app
|
||||
val files = File(
|
||||
PathUtil.getAppDownloadDir(
|
||||
requireContext(),
|
||||
app.packageName,
|
||||
app.versionCode
|
||||
).pathString
|
||||
).listFiles()
|
||||
|
||||
if (files?.isNotEmpty() == true) install() else purchase()
|
||||
}
|
||||
|
||||
else -> {
|
||||
@@ -627,7 +604,7 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
|
||||
)
|
||||
} else {
|
||||
updateApp(app)
|
||||
DownloadWorker.enqueueApp(requireContext(), app)
|
||||
}
|
||||
} else {
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
@@ -635,42 +612,23 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
updateApp(app)
|
||||
DownloadWorker.enqueueApp(requireContext(), app)
|
||||
} else {
|
||||
startForPermissions.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
updateApp(app)
|
||||
DownloadWorker.enqueueApp(requireContext(), app)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateApp(app: App) {
|
||||
if (updateService == null) {
|
||||
listOfActionsWhenServiceAttaches.add {
|
||||
updateService?.updateApp(app, true)
|
||||
}
|
||||
getUpdateServiceInstance()
|
||||
} else {
|
||||
updateService?.updateApp(app, true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateProgress(
|
||||
fetchGroup: FetchGroup,
|
||||
etaInMilliSeconds: Long,
|
||||
downloadedBytesPerSecond: Long
|
||||
) {
|
||||
private fun updateProgress(progress: Int, speed: Long = -1, timeRemaining: Long = -1) {
|
||||
runOnUiThread {
|
||||
val progress = if (fetchGroup.groupDownloadProgress > 0)
|
||||
fetchGroup.groupDownloadProgress
|
||||
else
|
||||
0
|
||||
|
||||
if (progress == 100) {
|
||||
binding.layoutDetailsInstall.btnDownload.setText(getString(R.string.action_installing))
|
||||
return@runOnUiThread
|
||||
}
|
||||
|
||||
binding.layoutDetailsInstall.apply {
|
||||
txtProgressPercent.text = ("${progress}%")
|
||||
|
||||
@@ -680,31 +638,8 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
progressDownload.progress = progress
|
||||
}
|
||||
|
||||
txtEta.text = CommonUtil.getETAString(
|
||||
requireContext(),
|
||||
etaInMilliSeconds
|
||||
)
|
||||
txtSpeed.text =
|
||||
CommonUtil.getDownloadSpeedString(
|
||||
requireContext(),
|
||||
downloadedBytesPerSecond
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun expandBottomSheet(message: String?) {
|
||||
runOnUiThread {
|
||||
bottomSheetBehavior.isHideable = false
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
|
||||
with(binding.layoutDetailsInstall) {
|
||||
txtPurchaseError.text = message
|
||||
btnDownload.updateState(State.IDLE)
|
||||
if (app.isFree)
|
||||
btnDownload.setText(R.string.action_install)
|
||||
else
|
||||
btnDownload.setText(app.price)
|
||||
txtEta.text = CommonUtil.getETAString(requireContext(), timeRemaining)
|
||||
txtSpeed.text = CommonUtil.getDownloadSpeedString(requireContext(), speed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -713,6 +648,8 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
app.isInstalled = PackageUtil.isInstalled(requireContext(), app.packageName)
|
||||
|
||||
runOnUiThread {
|
||||
app.isInstalled = PackageUtil.isInstalled(requireContext(), app.packageName)
|
||||
|
||||
binding.layoutDetailsInstall.btnDownload.let { btn ->
|
||||
if (app.isInstalled) {
|
||||
isUpdatable = PackageUtil.isUpdatable(
|
||||
@@ -729,6 +666,10 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
("$installedVersion ➔ ${app.versionName} (${app.versionCode})")
|
||||
btn.setText(R.string.action_update)
|
||||
btn.addOnClickListener { startDownload() }
|
||||
btn.addOnLongClickListener {
|
||||
startDownload(true)
|
||||
true
|
||||
}
|
||||
} else {
|
||||
binding.layoutDetailsApp.txtLine3.text = installedVersion
|
||||
btn.setText(R.string.action_open)
|
||||
@@ -738,7 +679,10 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
binding.layoutDetailsToolbar.toolbar.invalidateMenu()
|
||||
}
|
||||
} else {
|
||||
if (app.isFree) {
|
||||
val downloading = downloadStatus == DownloadStatus.DOWNLOADING
|
||||
if (DownloadWorker.isEnqueued(app.packageName) && !downloading) {
|
||||
flip(1)
|
||||
} else if (app.isFree) {
|
||||
btn.setText(R.string.action_install)
|
||||
} else {
|
||||
btn.setText(app.price)
|
||||
@@ -752,6 +696,15 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
startDownload()
|
||||
}
|
||||
}
|
||||
btn.addOnLongClickListener {
|
||||
if (authData.isAnonymous && !app.isFree) {
|
||||
toast(R.string.toast_purchase_blocked)
|
||||
} else {
|
||||
btn.setText(R.string.download_metadata)
|
||||
startDownload(true)
|
||||
}
|
||||
true
|
||||
}
|
||||
if (uninstallActionEnabled) {
|
||||
binding.layoutDetailsToolbar.toolbar.invalidateMenu()
|
||||
}
|
||||
@@ -771,186 +724,6 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun attachFetch() {
|
||||
if (fetch == null) {
|
||||
downloadManager = DownloadManager.with(requireContext())
|
||||
fetch = downloadManager!!.fetch
|
||||
}
|
||||
fetch?.getFetchGroup(app.getGroupId(requireContext())) { fetchGroup: FetchGroup ->
|
||||
if (fetchGroup.groupDownloadProgress == 100 && fetchGroup.completedDownloads.isNotEmpty()) {
|
||||
status = Status.COMPLETED
|
||||
} else if (downloadManager?.isDownloading(fetchGroup) == true) {
|
||||
status = Status.DOWNLOADING
|
||||
flip(1)
|
||||
} else if (downloadManager?.isCanceled(fetchGroup) == true) {
|
||||
status = Status.CANCELLED
|
||||
} else if (fetchGroup.pausedDownloads.isNotEmpty()) {
|
||||
status = Status.PAUSED
|
||||
} else {
|
||||
status = Status.NONE
|
||||
}
|
||||
}
|
||||
|
||||
fetchGroupListener = object : AbstractFetchGroupListener() {
|
||||
|
||||
override fun onAdded(groupId: Int, download: Download, fetchGroup: FetchGroup) {
|
||||
if (groupId == app.getGroupId(requireContext())) {
|
||||
status = download.status
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStarted(
|
||||
groupId: Int,
|
||||
download: Download,
|
||||
downloadBlocks: List<DownloadBlock>,
|
||||
totalBlocks: Int,
|
||||
fetchGroup: FetchGroup
|
||||
) {
|
||||
if (groupId == app.getGroupId(requireContext())) {
|
||||
status = download.status
|
||||
flip(1)
|
||||
|
||||
val pkgDir = PathUtil.getPackageDirectory(requireContext(), app.packageName)
|
||||
completionMarker =
|
||||
File("$pkgDir/.${app.versionCode}.download-complete")
|
||||
inProgressMarker =
|
||||
File("$pkgDir/.${app.versionCode}.download-in-progress")
|
||||
|
||||
if (completionMarker.exists())
|
||||
completionMarker.delete()
|
||||
|
||||
inProgressMarker.createNewFile()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResumed(groupId: Int, download: Download, fetchGroup: FetchGroup) {
|
||||
if (groupId == app.getGroupId(requireContext())) {
|
||||
status = download.status
|
||||
flip(1)
|
||||
inProgressMarker.parentFile?.mkdirs()
|
||||
inProgressMarker.createNewFile()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPaused(groupId: Int, download: Download, fetchGroup: FetchGroup) {
|
||||
if (groupId == app.getGroupId(requireContext())) {
|
||||
status = download.status
|
||||
flip(0)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onProgress(
|
||||
groupId: Int,
|
||||
download: Download,
|
||||
etaInMilliSeconds: Long,
|
||||
downloadedBytesPerSecond: Long,
|
||||
fetchGroup: FetchGroup
|
||||
) {
|
||||
if (groupId == app.getGroupId(requireContext())) {
|
||||
updateProgress(fetchGroup, etaInMilliSeconds, downloadedBytesPerSecond)
|
||||
Log.i(
|
||||
"${app.displayName} : ${download.file} -> Progress : %d",
|
||||
fetchGroup.groupDownloadProgress
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCompleted(groupId: Int, download: Download, fetchGroup: FetchGroup) {
|
||||
if (groupId == app.getGroupId(requireContext()) && fetchGroup.groupDownloadProgress == 100) {
|
||||
status = download.status
|
||||
flip(0)
|
||||
updateProgress(fetchGroup, -1, -1)
|
||||
try {
|
||||
inProgressMarker.delete()
|
||||
completionMarker.createNewFile()
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCancelled(groupId: Int, download: Download, fetchGroup: FetchGroup) {
|
||||
if (groupId == app.getGroupId(requireContext())) {
|
||||
status = download.status
|
||||
flip(0)
|
||||
inProgressMarker.delete()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(
|
||||
groupId: Int,
|
||||
download: Download,
|
||||
error: Error,
|
||||
throwable: Throwable?,
|
||||
fetchGroup: FetchGroup
|
||||
) {
|
||||
if (groupId == app.getGroupId(requireContext())) {
|
||||
status = download.status
|
||||
flip(0)
|
||||
inProgressMarker.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appMetadataListener = object : AppMetadataStatusListener {
|
||||
override fun onAppMetadataStatusError(reason: String, app: App) {
|
||||
if (app.packageName == this@AppDetailsFragment.app.packageName) {
|
||||
updateActionState(State.IDLE)
|
||||
expandBottomSheet(reason)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getUpdateServiceInstance()
|
||||
|
||||
binding.layoutDetailsInstall.imgCancel.setOnClickListener {
|
||||
fetch?.cancelGroup(
|
||||
app.getGroupId(requireContext())
|
||||
)
|
||||
}
|
||||
if (updateService != null) {
|
||||
pendingAddListeners = false
|
||||
updateService!!.registerFetchListener(fetchGroupListener)
|
||||
// appMetadataListener needs to be initialized after the fetchGroupListener
|
||||
updateService!!.registerAppMetadataListener(appMetadataListener)
|
||||
} else {
|
||||
pendingAddListeners = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUpdateServiceInstance() {
|
||||
if (updateService == null && !attachToServiceCalled) {
|
||||
attachToServiceCalled = true
|
||||
val intent = Intent(requireContext(), UpdateService::class.java)
|
||||
activity?.startService(intent)
|
||||
activity?.bindService(
|
||||
intent,
|
||||
serviceConnection,
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
if (updateService != null) {
|
||||
updateService = null
|
||||
attachToServiceCalled = false
|
||||
pendingAddListeners = true
|
||||
activity?.unbindService(serviceConnection)
|
||||
}
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (updateService != null) {
|
||||
updateService = null
|
||||
attachToServiceCalled = false
|
||||
pendingAddListeners = true
|
||||
activity?.unbindService(serviceConnection)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
|
||||
Reference in New Issue
Block a user