Skip to content

Commit 00fc597

Browse files
committed
upload virustotal
1 parent b47a0c7 commit 00fc597

10 files changed

Lines changed: 714 additions & 88 deletions

File tree

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ dependencies {
9292

9393
implementation(libs.ktor.client.core)
9494
implementation(libs.ktor.client.cio)
95+
implementation(libs.ktor.client.logging)
9596

9697
implementation(libs.shizuku.api)
9798
implementation(libs.shizuku.provider)
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package app.pwhs.universalinstaller.data.remote
2+
3+
import android.Manifest
4+
import android.app.Notification
5+
import android.app.NotificationChannel
6+
import android.app.NotificationManager
7+
import android.content.Context
8+
import android.content.pm.PackageManager
9+
import android.os.Build
10+
import androidx.core.app.NotificationCompat
11+
import androidx.core.app.NotificationManagerCompat
12+
import androidx.core.content.ContextCompat
13+
import app.pwhs.universalinstaller.R
14+
15+
class VirusTotalNotifier(private val context: Context) {
16+
17+
private val manager = NotificationManagerCompat.from(context)
18+
19+
init {
20+
ensureChannel()
21+
}
22+
23+
fun notifyHashing(fileName: String): Int {
24+
if (!canPost()) return -1
25+
val id = nextId()
26+
val n = baseBuilder()
27+
.setContentTitle(context.getString(R.string.vt_notif_hashing))
28+
.setContentText(fileName)
29+
.setProgress(0, 0, true)
30+
.setOngoing(true)
31+
.build()
32+
post(id, n)
33+
return id
34+
}
35+
36+
fun notifyUploading(id: Int, fileName: String, percent: Int) {
37+
if (!canPost() || id < 0) return
38+
val n = baseBuilder()
39+
.setContentTitle(context.getString(R.string.vt_notif_uploading, percent))
40+
.setContentText(fileName)
41+
.setProgress(100, percent, false)
42+
.setOngoing(true)
43+
.setOnlyAlertOnce(true)
44+
.build()
45+
post(id, n)
46+
}
47+
48+
fun notifyQueued(id: Int, fileName: String) {
49+
if (!canPost() || id < 0) return
50+
val n = baseBuilder()
51+
.setContentTitle(context.getString(R.string.vt_notif_queued))
52+
.setContentText(fileName)
53+
.setProgress(0, 0, true)
54+
.setOngoing(true)
55+
.setOnlyAlertOnce(true)
56+
.build()
57+
post(id, n)
58+
}
59+
60+
fun notifyAnalyzing(id: Int, fileName: String) {
61+
if (!canPost() || id < 0) return
62+
val n = baseBuilder()
63+
.setContentTitle(context.getString(R.string.vt_notif_analyzing))
64+
.setContentText(fileName)
65+
.setProgress(0, 0, true)
66+
.setOngoing(true)
67+
.setOnlyAlertOnce(true)
68+
.build()
69+
post(id, n)
70+
}
71+
72+
fun notifyResult(id: Int, fileName: String, title: String, text: String) {
73+
if (!canPost() || id < 0) return
74+
val n = baseBuilder()
75+
.setContentTitle(title)
76+
.setContentText("$fileName · $text")
77+
.setProgress(0, 0, false)
78+
.setOngoing(false)
79+
.setAutoCancel(true)
80+
.build()
81+
post(id, n)
82+
}
83+
84+
fun cancel(id: Int) {
85+
if (id < 0) return
86+
manager.cancel(id)
87+
}
88+
89+
private fun baseBuilder(): NotificationCompat.Builder =
90+
NotificationCompat.Builder(context, CHANNEL_ID)
91+
.setSmallIcon(R.drawable.logo)
92+
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
93+
.setPriority(NotificationCompat.PRIORITY_LOW)
94+
.setSilent(true)
95+
96+
private fun post(id: Int, notification: Notification) {
97+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
98+
ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS)
99+
!= PackageManager.PERMISSION_GRANTED
100+
) return
101+
manager.notify(id, notification)
102+
}
103+
104+
private fun canPost(): Boolean {
105+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
106+
val granted = ContextCompat.checkSelfPermission(
107+
context, Manifest.permission.POST_NOTIFICATIONS
108+
) == PackageManager.PERMISSION_GRANTED
109+
if (!granted) return false
110+
}
111+
return manager.areNotificationsEnabled()
112+
}
113+
114+
private fun ensureChannel() {
115+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
116+
val sys = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
117+
if (sys.getNotificationChannel(CHANNEL_ID) != null) return
118+
val channel = NotificationChannel(
119+
CHANNEL_ID,
120+
context.getString(R.string.vt_notif_channel_name),
121+
NotificationManager.IMPORTANCE_LOW
122+
).apply {
123+
description = context.getString(R.string.vt_notif_channel_description)
124+
setShowBadge(false)
125+
}
126+
sys.createNotificationChannel(channel)
127+
}
128+
}
129+
130+
companion object {
131+
private const val CHANNEL_ID = "virustotal_scan"
132+
private var nextId = 3000
133+
@Synchronized
134+
private fun nextId(): Int = ++nextId
135+
}
136+
}

0 commit comments

Comments
 (0)