11package com.houvven.lsposed.scope.demo
22
3- import android.content.ComponentName
4- import android.content.ServiceConnection
53import android.os.Bundle
6- import android.os.IBinder
7- import android.util.Log
84import 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
1118import org.lsposed.lspd.ILSPManagerService
12- import org.lsposed.lspd.service.ILSPApplicationService
13- import java.util.Optional
1419
1520class MainActivity : ComponentActivity () {
21+
22+ private var managerService: ILSPManagerService ? = null
23+
1624 override fun onCreate (savedInstanceState : Bundle ? ) {
1725 super .onCreate(savedInstanceState)
18- LSPosedBridgeRootService .bindRootService(this , LSPosedBridgeServiceConnection )
19- Thread {
20- while (! LSPosedBridgeServiceConnection .serviceOptional.isPresent) {
21- Thread .sleep(200 )
22- }
2326
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(" " ) }
3936
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+ }
4148
42- private const val TAG = " LSPosedBridgeServiceConnection"
49+ LaunchedEffect (key1 = this ) {
50+ while (connection.lServiceBridge == null ) {
51+ delay(200 )
52+ }
53+ isBinderAlive = true
54+ }
4355
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+ }
4669
47- override fun onServiceConnected (name : ComponentName , service : IBinder ) {
48- Log .i(TAG , " onServiceConnected: $name , ${service.interfaceDescriptor} " )
49- serviceOptional = Optional .of(ILSPosedBridgeService .Stub .asInterface(service))
5070 }
71+ }
5172
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
5585 }
56- }
5786}
0 commit comments