Skip to content

Commit

Permalink
Optimize ArtifactJob
Browse files Browse the repository at this point in the history
  • Loading branch information
SanmerDev committed Aug 13, 2024
1 parent cea7a0d commit 63ff085
Showing 1 changed file with 27 additions and 19 deletions.
46 changes: 27 additions & 19 deletions app/src/main/kotlin/dev/sanmer/github/artifacts/job/ArtifactJob.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package dev.sanmer.github.artifacts.job

import android.Manifest
import android.annotation.SuppressLint
import android.app.Notification
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.net.Uri
import android.os.Environment
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
Expand Down Expand Up @@ -41,19 +42,19 @@ import java.io.File
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds

@OptIn(FlowPreview::class)
@AndroidEntryPoint
class ArtifactJob : LifecycleService() {
private val notificationManager by lazy { NotificationManagerCompat.from(this) }

init {
lifecycleScope.launch {
@OptIn(FlowPreview::class)
jobStateFlow.sample(500.milliseconds).collect {
when (it) {
JobState.Empty -> {}
is JobState.Pending -> notifyProgress(it.artifact, 0f)
is JobState.Running -> notifyProgress(it.artifact, it.progress)
is JobState.Success -> notifySuccess(it.artifact)
is JobState.Success -> notifySuccess(it.artifact, it.uri)
is JobState.Failure -> notifyFailure(it.artifact)
}
}
Expand All @@ -68,17 +69,15 @@ class ArtifactJob : LifecycleService() {
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val sticky = super.onStartCommand(intent, flags, startId)
if (intent == null) return sticky

val artifact = intent.artifact
val token = intent.token

lifecycleScope.launch {
intent ?: return@launch
val artifact = intent.artifact
val token = intent.token

runCatching {
download(artifact, token)
}.onSuccess {
jobStateFlow.update { JobState.Success(artifact) }
}.onSuccess { uri ->
jobStateFlow.update { JobState.Success(artifact, uri) }
}.onFailure { error ->
Timber.e(error)
jobStateFlow.update { JobState.Failure(artifact, error) }
Expand All @@ -87,7 +86,7 @@ class ArtifactJob : LifecycleService() {
pendingJobs.removeAt(0)
}

return sticky
return super.onStartCommand(intent, flags, startId)
}

override fun onCreate() {
Expand All @@ -97,15 +96,15 @@ class ArtifactJob : LifecycleService() {
}

override fun onDestroy() {
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_DETACH)
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
Timber.d("onDestroy")
super.onDestroy()
}

private suspend fun download(artifact: Artifact, token: String) = withContext(Dispatchers.IO) {
val uri = createMediaStoreUri(
file = File(Environment.DIRECTORY_DOWNLOADS, "${artifact.name}.zip"),
mimeType = "android/zip"
mimeType = "application/zip"
)

val request = Request.Builder()
Expand All @@ -125,6 +124,8 @@ class ArtifactJob : LifecycleService() {
}
}
}

uri
}

private fun setForeground() {
Expand Down Expand Up @@ -156,13 +157,21 @@ class ArtifactJob : LifecycleService() {
notify(artifact.id.toInt(), notification)
}

private fun notifySuccess(artifact: Artifact) {
private fun notifySuccess(artifact: Artifact, uri: Uri) {
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri, "application/zip")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
val flag = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
val pending = PendingIntent.getActivity(this, 0, intent, flag)

val notification = newNotificationBuilder()
.setContentTitle(artifact.name)
.setContentText(getText(R.string.download_success))
.setContentIntent(pending)
.setSilent(true)
.setOngoing(false)
.setGroup(GROUP_KEY)
.setAutoCancel(true)
.build()

notify(artifact.id.toInt(), notification)
Expand All @@ -174,7 +183,6 @@ class ArtifactJob : LifecycleService() {
.setContentText(getText(R.string.download_fail))
.setSilent(false)
.setOngoing(false)
.setGroup(GROUP_KEY)
.build()

notify(artifact.id.toInt(), notification)
Expand All @@ -184,7 +192,7 @@ class ArtifactJob : LifecycleService() {
NotificationCompat.Builder(this, Const.CHANNEL_ID_ARTIFACT_JOB)
.setSmallIcon(R.drawable.box)

@SuppressLint("MissingPermission")
@Throws(SecurityException::class)
private fun notify(id: Int, notification: Notification) {
notificationManager.notify(id, notification)
}
Expand All @@ -193,7 +201,7 @@ class ArtifactJob : LifecycleService() {
data object Empty : JobState(0)
class Pending(val artifact: Artifact) : JobState(artifact.id)
class Running(val artifact: Artifact, val progress: Float) : JobState(artifact.id)
class Success(val artifact: Artifact) : JobState(artifact.id)
class Success(val artifact: Artifact, val uri: Uri) : JobState(artifact.id)
class Failure(val artifact: Artifact, val error: Throwable) : JobState(artifact.id)
}

Expand Down

0 comments on commit 63ff085

Please sign in to comment.