1
1
package com.houvven.lsposed.scope.demo
2
2
3
- import android.content.ComponentName
4
- import android.content.ServiceConnection
5
3
import android.os.Bundle
6
- import android.os.IBinder
7
- import android.util.Log
8
4
import androidx.activity.ComponentActivity
9
- import io.github.houvven.lservice.ILSPosedBridgeService
10
- import io.github.houvven.lservice.LSPosedBridgeRootService
5
+ import androidx.activity.compose.setContent
6
+ import androidx.compose.foundation.layout.Arrangement
7
+ import androidx.compose.foundation.layout.Column
8
+ import androidx.compose.material3.MaterialTheme
9
+ import androidx.compose.material3.Text
10
+ import androidx.compose.runtime.LaunchedEffect
11
+ import androidx.compose.runtime.getValue
12
+ import androidx.compose.runtime.mutableStateOf
13
+ import androidx.compose.runtime.remember
14
+ import androidx.compose.runtime.setValue
15
+ import androidx.compose.ui.Modifier
16
+ import io.github.houvven.lservice.LServiceBridgeRootService
17
+ import kotlinx.coroutines.delay
11
18
import org.lsposed.lspd.ILSPManagerService
12
- import org.lsposed.lspd.service.ILSPApplicationService
13
- import java.util.Optional
14
19
15
20
class MainActivity : ComponentActivity () {
21
+
22
+ private var managerService: ILSPManagerService ? = null
23
+
16
24
override fun onCreate (savedInstanceState : Bundle ? ) {
17
25
super .onCreate(savedInstanceState)
18
- LSPosedBridgeRootService .bindRootService(this , LSPosedBridgeServiceConnection )
19
- Thread {
20
- while (! LSPosedBridgeServiceConnection .serviceOptional.isPresent) {
21
- Thread .sleep(200 )
22
- }
23
26
24
- LSPosedBridgeServiceConnection .serviceOptional.ifPresent { bridgeService ->
25
- val applicationServiceBinder =
26
- bridgeService.obtainLSPosedApplicationServiceBinder() ? : return @ifPresent
27
- val applicationService =
28
- ILSPApplicationService .Stub .asInterface(applicationServiceBinder)
29
-
30
- val managerServiceBinder =
31
- bridgeService.obtainLSPosedManagerServiceBinder(applicationService)
32
- ? : return @ifPresent
33
- val managerService = ILSPManagerService .Stub .asInterface(managerServiceBinder)
34
- val xposedApiVersion = managerService.xposedApiVersion
35
- Log .i(" MainActivity" , " xposedApiVersion: $xposedApiVersion " )
36
- }
37
- }.start()
38
- }
27
+ val connection = LServiceBridgeRootService .DefaultServiceConnection ()
28
+ LServiceBridgeRootService .bind(this .applicationContext, connection, apkFile)
29
+
30
+ setContent {
31
+ var isBinderAlive by remember { mutableStateOf(false ) }
32
+ var api by remember { mutableStateOf(" " ) }
33
+ var xposedApiVersion by remember { mutableStateOf(" " ) }
34
+ var xposedVersionName by remember { mutableStateOf(" " ) }
35
+ var xposedVersionCode by remember { mutableStateOf(" " ) }
39
36
40
- object LSPosedBridgeServiceConnection : ServiceConnection {
37
+ MaterialTheme {
38
+ Column (
39
+ verticalArrangement = Arrangement .Top ,
40
+ modifier = Modifier
41
+ ) {
42
+ Text (text = " api: $api " )
43
+ Text (text = " xposedApiVersion: $xposedApiVersion " )
44
+ Text (text = " xposedVersionName: $xposedVersionName " )
45
+ Text (text = " xposedVersionCode: $xposedVersionCode " )
46
+ }
47
+ }
41
48
42
- private const val TAG = " LSPosedBridgeServiceConnection"
49
+ LaunchedEffect (key1 = this ) {
50
+ while (connection.lServiceBridge == null ) {
51
+ delay(200 )
52
+ }
53
+ isBinderAlive = true
54
+ }
43
55
44
- var serviceOptional: Optional <ILSPosedBridgeService > = Optional .empty()
45
- private set
56
+ LaunchedEffect (key1 = isBinderAlive) {
57
+ while (managerService == null ) {
58
+ runCatching {
59
+ managerService = connection.getManagerService(connection.applicationService)
60
+ }.onFailure { delay(200 ) }
61
+ }
62
+ managerService!! .let {
63
+ api = it.api
64
+ xposedApiVersion = it.xposedApiVersion.toString()
65
+ xposedVersionName = it.xposedVersionName
66
+ xposedVersionCode = it.xposedVersionCode.toString()
67
+ }
68
+ }
46
69
47
- override fun onServiceConnected (name : ComponentName , service : IBinder ) {
48
- Log .i(TAG , " onServiceConnected: $name , ${service.interfaceDescriptor} " )
49
- serviceOptional = Optional .of(ILSPosedBridgeService .Stub .asInterface(service))
50
70
}
71
+ }
51
72
52
- override fun onServiceDisconnected (name : ComponentName ? ) {
53
- Log .i(TAG , " onServiceDisconnected: $name " )
54
- serviceOptional = Optional .empty()
73
+ private val apkFile: String
74
+ get() {
75
+ val file = cacheDir.resolve(" lsposed.apk" )
76
+ if (! file.exists()) {
77
+ assets.open(" lsposed-manager.apk" ).use { inputStream ->
78
+ file.outputStream().use { out ->
79
+ out .write(inputStream.readBytes())
80
+ out .flush()
81
+ }
82
+ }
83
+ }
84
+ return file.absolutePath
55
85
}
56
- }
57
86
}
0 commit comments