Skip to content

Commit 615efba

Browse files
committed
-
1 parent 524b2e1 commit 615efba

File tree

20 files changed

+347
-106
lines changed

20 files changed

+347
-106
lines changed

app/src/main/aidl/com/wifi/toolbox/IToolboxService.aidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ interface IToolboxService {
1414
void disconnectWifi();
1515
boolean startWifiScan(boolean allowUseCommand);
1616
List<Bundle> getSavedWifiList();
17-
void executeCommand(String command, IToolboxCallback callback);
17+
int executeCommand(String command, IToolboxCallback callback);
1818
int getNetIdBySsid(String ssid);
1919
List<Bundle> getWifiScanResults();
2020
void stopCommand(int taskId);

app/src/main/java/com/wifi/toolbox/services/AidlService.kt

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@file:Suppress("DEPRECATION")
12
package com.wifi.toolbox.services
23

34
import android.annotation.SuppressLint
@@ -12,17 +13,19 @@ import android.util.Log
1213
import com.topjohnwu.superuser.ipc.RootService
1314
import com.wifi.toolbox.IToolboxService
1415
import com.wifi.toolbox.IToolboxCallback
16+
import com.wifi.toolbox.utils.CommandRunner
1517
import com.wifi.toolbox.utils.ShizukuUtil.getWifiMethod
16-
import java.util.UUID
18+
import java.util.concurrent.ConcurrentHashMap
19+
import java.util.concurrent.atomic.AtomicInteger
1720

1821
class AidlService : RootService() {
19-
private val TAG = "ToolboxApp-Root"
20-
private val uuid = UUID.randomUUID().toString()
22+
private val TAG = "AidlService"
2123
private var expectedUid = -1
2224

25+
private val taskMap = ConcurrentHashMap<Int, Runnable>()
26+
private val taskIdGenerator = AtomicInteger(1)
27+
2328
inner class ToolboxIPC : IToolboxService.Stub() {
24-
private val activeCommands = mutableMapOf<Int, java.util.concurrent.Future<*>>()
25-
private val executor = java.util.concurrent.Executors.newCachedThreadPool()
2629

2730
private fun checkCaller() {
2831
val callingUid = getCallingUid()
@@ -437,34 +440,31 @@ class AidlService : RootService() {
437440

438441
override fun stopCommand(taskId: Int) {
439442
checkCaller()
440-
activeCommands.remove(taskId)?.cancel(true)
443+
taskMap.remove(taskId)?.run()
441444
}
442445

443-
override fun executeCommand(command: String, callback: IToolboxCallback) {
446+
override fun executeCommand(command: String, callback: IToolboxCallback): Int {
444447
checkCaller()
445-
val task = executor.submit {
446-
val out = StringBuilder()
447-
val result = com.topjohnwu.superuser.Shell.cmd(command)
448-
.to(object : java.util.AbstractList<String>() {
449-
override fun add(element: String): Boolean {
450-
callback.onOutput(element)
451-
out.append(element).append("\n")
452-
return true
453-
}
454-
455-
override val size: Int get() = 0
456-
override fun get(index: Int): String = ""
457-
}).exec()
458-
callback.onFinished(out.toString(), result.code)
459-
}
460-
activeCommands[command.hashCode()] = task
448+
val taskId = taskIdGenerator.getAndIncrement()
449+
450+
val stopFunc = CommandRunner.executeCommand(
451+
command, false,
452+
onOutputReceived = {
453+
callback.onOutput(it)
454+
}, onCommandFinished = {
455+
taskMap.remove(taskId)
456+
callback.onFinished(it.output, it.exitCode)
457+
})
458+
459+
taskMap[taskId] = stopFunc
460+
return taskId
461461
}
462462

463463
private fun getWifiService(): Any = asInterface("android.net.wifi.IWifiManager", "wifi")
464464
}
465465

466466
override fun onCreate() {
467-
Log.d(TAG, "ToolboxIPC: onCreate, $uuid")
467+
Log.d(TAG, "ToolboxIPC: onCreate")
468468
}
469469

470470
override fun onRebind(intent: Intent) {

app/src/main/java/com/wifi/toolbox/services/WifiLogcatService.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package com.wifi.toolbox.services
22

33
import android.util.Log
4+
import android.content.Context
45
import com.wifi.toolbox.R
6+
import com.wifi.toolbox.ToolboxApp
57
import com.wifi.toolbox.structs.PojieSettings
68
import com.wifi.toolbox.structs.WifiLogData
9+
import com.wifi.toolbox.utils.AidlServiceHelper
710
import com.wifi.toolbox.utils.CommandRunner
811
import com.wifi.toolbox.utils.ShizukuUtil
912
import kotlinx.coroutines.flow.MutableSharedFlow
1013
import kotlinx.coroutines.flow.asSharedFlow
1114
import java.util.function.Consumer
1215

1316
class WifiLogcatService(
14-
private val context: android.content.Context, private val pojieSettings: PojieSettings
17+
private val context: Context, private val pojieSettings: PojieSettings
1518
) : AutoCloseable {
1619
var stopFunc: Runnable? = null
1720

@@ -49,22 +52,28 @@ class WifiLogcatService(
4952
}
5053
}
5154

52-
fun executeCommand(
55+
private fun executeCommand(
5356
command: String,
5457
onOutputReceived: Consumer<String>?,
5558
onCommandFinished: Consumer<CommandRunner.CommandResult>?
5659
): Runnable {
60+
val app = context.applicationContext as ToolboxApp
5761
return when (val method = pojieSettings.commandMethod) {
5862
0 -> throw Exception("命令行实现方式为空,请先去设置中选择")
5963
1 -> ShizukuUtil.executeCommand(command, onOutputReceived, onCommandFinished)
64+
2 -> AidlServiceHelper.executeCommand(app, command, onOutputReceived, onCommandFinished)
65+
3 -> CommandRunner.executeCommand(command, true, onOutputReceived, onCommandFinished)
6066
else -> throw Exception(context.getString(R.string.tip_not_completed) + "(commandMethod=$method)")
6167
}
6268
}
6369

6470
fun executeCommandSync(command: String): CommandRunner.CommandResult {
71+
val app = context.applicationContext as ToolboxApp
6572
return when (val method = pojieSettings.commandMethod) {
6673
0 -> throw Exception("命令行实现方式为空,请先去设置中选择")
6774
1 -> ShizukuUtil.executeCommandSync(command)
75+
2 -> AidlServiceHelper.executeCommandSync(app, command)
76+
3 -> CommandRunner.executeCommandSync(command, true)
6877
else -> throw Exception(context.getString(R.string.tip_not_completed) + "(commandMethod=$method)")
6978
}
7079
}

app/src/main/java/com/wifi/toolbox/services/pojie/ConnectWorker.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,21 @@ class ConnectWorker(
6363
when (connectMode) {
6464
0 -> throw Exception(service.getString(R.string.connect_mode_empty))
6565
1 -> ShizukuUtil.connectToWifi(task.ssid, task.password)
66-
2 -> {
66+
2 -> AidlServiceHelper.connectToWifi(app, task.ssid, task.password)
67+
3 -> {
6768
val netId = ApiUtil.connectToWifiApi28(service, task.ssid, task.password)
6869
if (netId == -1) throw Exception(service.getString(R.string.connect_wifi_failed))
6970
}
7071

71-
3 -> { /* API 29 处理流程 */
72+
4 -> { /* API 29 处理流程 */
7273
}
7374

7475
else -> throw Exception(service.getString(R.string.tip_not_completed) + "(connectMode=$connectMode)")
7576
}
7677

7778
try {
7879
withTimeout(app.pojieConfig.maxTryTime.toLong()) {
79-
if (connectMode == 3) {
80+
if (connectMode == 4) {
8081
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
8182
suspendCancellableCoroutine { continuation ->
8283
launch(Dispatchers.Main) {
@@ -147,11 +148,11 @@ class ConnectWorker(
147148
connectMode: Int
148149
): Int {
149150
val isMatch =
150-
connectMode == 3 || (data.ssid == task.ssid && data.eventStartTime >= startTime)
151+
connectMode == 4 || (data.ssid == task.ssid && data.eventStartTime >= startTime)
151152
if (!isMatch) return -1
152153

153154
return when (data.event) {
154-
WifiLogData.EVENT_WIFI_CONNECTED -> if (connectMode != 3) SinglePojieTask.RESULT_SUCCESS else -1
155+
WifiLogData.EVENT_WIFI_CONNECTED -> if (connectMode != 4) SinglePojieTask.RESULT_SUCCESS else -1
155156
WifiLogData.EVENT_CONNECT_FAILED -> {
156157
if (readLogMode == 2 || System.currentTimeMillis() - data.eventStartTime > 2000) SinglePojieTask.RESULT_FAILED else -1
157158
}
@@ -206,7 +207,7 @@ class ConnectWorker(
206207
fun forgetNetwork(settings: PojieSettings, ssid: String): Boolean {
207208
val netId = when (settings.connectMode) {
208209
1 -> ShizukuUtil.getNetIdBySsid(ssid)
209-
2 -> ApiUtil.getNetIdBySsid(service, ssid)
210+
3 -> ApiUtil.getNetIdBySsid(service, ssid)
210211
else -> -1
211212
}
212213
if (netId == -1) return false
@@ -216,7 +217,7 @@ class ConnectWorker(
216217
true
217218
}
218219

219-
2 -> ApiUtil.forgetNetwork(service, netId)
220+
3 -> ApiUtil.forgetNetwork(service, netId)
220221
else -> false
221222
}
222223
}

app/src/main/java/com/wifi/toolbox/services/pojie/PojieNotification.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,15 @@ object PojieNotification {
5959
* @param context 上下文
6060
* @param contentText 要更新的内容
6161
*/
62-
fun update(context: Context, contentText: String) {
62+
fun update(context: Context, contentText: String, subText: String) {
6363
val notificationManager =
6464
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
6565
val notification = buildForeground(context).let {
6666
NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
6767
.setSmallIcon(R.drawable.ic_launcher_foreground)
6868
.setContentTitle(context.getString(R.string.wifi_pojie_name))
6969
.setContentText(contentText)
70+
.setSubText(subText)
7071
.setContentIntent(it.contentIntent)
7172
.setOngoing(true)
7273
.setPriority(NotificationCompat.PRIORITY_MIN)

app/src/main/java/com/wifi/toolbox/services/pojie/PojieTaskManager.kt

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.wifi.toolbox.services.pojie
22

3+
import android.content.Context
34
import androidx.compose.runtime.snapshotFlow
45
import com.wifi.toolbox.R
56
import com.wifi.toolbox.ToolboxApp
67
import com.wifi.toolbox.services.PojieService
78
import com.wifi.toolbox.structs.*
9+
import com.wifi.toolbox.utils.AidlServiceHelper
810
import com.wifi.toolbox.utils.PojieHistoryItem
911
import com.wifi.toolbox.utils.ShizukuUtil
1012
import kotlinx.coroutines.*
@@ -41,8 +43,16 @@ class PojieTaskManager(
4143

4244
safeScope.launch {
4345
while (isActive) {
44-
if (settings.connectMode != 3) ShizukuUtil.executeCommandSync("am force-stop com.android.settings")
45-
delay(100)
46+
if (settings.connectMode != 4) {
47+
if (AidlServiceHelper.executeCommandSync(
48+
app,
49+
"am force-stop com.android.settings"
50+
).exitCode != 0
51+
) {
52+
ShizukuUtil.executeCommandSync("am force-stop com.android.settings")
53+
}
54+
}
55+
delay(250)
4656
}
4757
}
4858

@@ -114,7 +124,11 @@ class PojieTaskManager(
114124
if (waitMs > 0) {
115125
val cooldownJob = scope.launch {
116126
service.log(service.getString(R.string.cooldown_log, waitMs))
117-
PojieNotification.update(service, service.getString(R.string.cooldown_status))
127+
PojieNotification.update(
128+
context = service,
129+
contentText = service.getString(R.string.cooldown_status),
130+
subText = ""
131+
)
118132
delay(waitMs)
119133
}
120134
currentWorkerJob = cooldownJob
@@ -170,9 +184,20 @@ class PojieTaskManager(
170184
currentPass
171185
), true
172186
)
187+
188+
val totalRemainingTime = app.runningPojieTasks
189+
.map {
190+
it.let { info ->
191+
PojieRunInfo.calculateAverageSpeed(info)
192+
?.times(info.tryList.size - info.tryIndex)
193+
}
194+
}
195+
.let { list -> if (list.any { it == null }) null else list.filterNotNull().sum() }
196+
173197
PojieNotification.update(
174-
service,
175-
service.getString(R.string.notif_attempting, task.ssid, currentPass)
198+
context = service,
199+
contentText = service.getString(R.string.notif_attempting, task.ssid, currentPass),
200+
subText = formatDuration(app, totalRemainingTime)
176201
)
177202

178203
val startTime = System.currentTimeMillis()
@@ -181,6 +206,7 @@ class PojieTaskManager(
181206
worker.performTaskLogic(app, SinglePojieTask(task.ssid, currentPass), settings)
182207
} catch (e: Exception) {
183208
if (e is CancellationException) throw e
209+
service.log("E: ${e.message}")
184210
SinglePojieTask.RESULT_ERROR
185211
}
186212
}
@@ -202,6 +228,25 @@ class PojieTaskManager(
202228
currentWorkerJob = null
203229
}
204230

231+
fun formatDuration(context: Context, ms: Long?): String {
232+
if (ms == null) {
233+
return context.getString(R.string.calculating_time)
234+
}
235+
val totalMinutes = ms / 60000
236+
if (totalMinutes < 1) return context.getString(R.string.time_unit_less_than_minute)
237+
238+
val days = totalMinutes / (24 * 60)
239+
val hours = (totalMinutes % (24 * 60)) / 60
240+
val minutes = totalMinutes % 60
241+
242+
val result = mutableListOf<String>()
243+
if (days > 0) result.add(context.getString(R.string.time_unit_day, days))
244+
if (hours > 0 || days > 0) result.add(context.getString(R.string.time_unit_hour, hours))
245+
result.add(context.getString(R.string.time_unit_minute, minutes))
246+
247+
return context.getString(R.string.remaining_time_format, result.joinToString(" "))
248+
}
249+
205250
private fun handleAttemptResult(
206251
app: ToolboxApp,
207252
task: PojieRunInfo,

app/src/main/java/com/wifi/toolbox/structs/PojieRunInfo.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,16 @@ data class PojieRunInfo(
1111
val retryCount: Int = 0,
1212
val textTip: String = ToolboxApp.instance.getString(R.string.task_preparing),
1313
val costList: List<Long> = emptyList()
14-
)
14+
) {
15+
companion object{
16+
fun calculateAverageSpeed(task: PojieRunInfo): Long? {
17+
val costs = task.costList
18+
if (costs.size < 5) return null
19+
20+
val avgMs = costs.average()
21+
if (avgMs <= 0) return null
22+
23+
return avgMs.toLong()
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)