diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6ea5e49..c793f25 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> () + + private fun dispatchServiceState( + listener: ServiceStateListener, + service: XposedService? + ) { + if (serviceStateListeners.contains(listener)) { + listener.onServiceStateChanged(service) + } + } + + fun addServiceStateListener( + listener: ServiceStateListener, + notifyImmediately: Boolean + ) { + serviceStateListeners.add(listener) + if (notifyImmediately) { + dispatchServiceState(listener, mService) + } + } + + fun removeServiceStateListener(listener: ServiceStateListener) { + serviceStateListeners.remove(listener) + } + } + + private fun notifyServiceStateChanged(service: XposedService?) { + for (listener in serviceStateListeners) { + dispatchServiceState(listener, service) + } + } + + override fun onCreate() { + super.onCreate() + XposedServiceHelper.registerListener(this) + } + + interface ServiceStateListener { + fun onServiceStateChanged(service: XposedService?) + } + + override fun onServiceBind(service: XposedService) { + mService = service + notifyServiceStateChanged(mService) + } + + override fun onServiceDied(service: XposedService) { + mService = null + notifyServiceStateChanged(mService) + } +} diff --git a/app/src/main/java/io/github/libxposed/example/MainActivity.kt b/app/src/main/java/io/github/libxposed/example/MainActivity.kt index ec8d6b7..55b8dbc 100644 --- a/app/src/main/java/io/github/libxposed/example/MainActivity.kt +++ b/app/src/main/java/io/github/libxposed/example/MainActivity.kt @@ -3,50 +3,86 @@ package io.github.libxposed.example import android.annotation.SuppressLint import android.app.Activity import android.os.Bundle -import android.os.Handler -import android.os.Looper import android.widget.Toast import io.github.libxposed.example.databinding.ActivityMainBinding import io.github.libxposed.service.XposedService import io.github.libxposed.service.XposedService.OnScopeEventListener -import io.github.libxposed.service.XposedServiceHelper import java.io.FileWriter import kotlin.random.Random -class MainActivity : Activity() { - +@SuppressLint("SetTextI18n") +class MainActivity : Activity(), App.ServiceStateListener { private var mService: XposedService? = null + private lateinit var binding: ActivityMainBinding private val mCallback = object : OnScopeEventListener { override fun onScopeRequestApproved(approved: List) { runOnUiThread { - Toast.makeText(this@MainActivity, "onScopeRequestApproved: $approved", Toast.LENGTH_SHORT).show() + Toast.makeText( + this@MainActivity, + "onScopeRequestApproved: $approved", + Toast.LENGTH_SHORT + ).show() + binding.scope.text = "Scope: " + mService?.scope } } override fun onScopeRequestFailed(message: String) { runOnUiThread { - Toast.makeText(this@MainActivity, "onScopeRequestFailed: $message", Toast.LENGTH_SHORT).show() + Toast.makeText( + this@MainActivity, + "onScopeRequestFailed: $message", + Toast.LENGTH_SHORT + ).show() + binding.scope.text = "Scope: " + mService?.scope } } } - @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val binding = ActivityMainBinding.inflate(layoutInflater) - setContentView(binding.root) + binding = ActivityMainBinding.inflate(layoutInflater) + binding.let { + setContentView(it.root) + it.binder.text = "Loading" + } + } + + override fun onStart() { + super.onStart() + App.addServiceStateListener(this, true) + } - binding.binder.text = "Loading" - XposedServiceHelper.registerListener(object : XposedServiceHelper.OnServiceListener { - override fun onServiceBind(service: XposedService) { - mService = service + override fun onStop() { + App.removeServiceStateListener(this) + super.onStop() + } + + override fun onServiceStateChanged(service: XposedService?) { + mService = service + runOnUiThread { + if (service == null) { + binding.binder.text = "Binder is null" + } else { binding.binder.text = "Binder acquired" binding.api.text = "API " + service.apiVersion binding.framework.text = "Framework " + service.frameworkName binding.frameworkVersion.text = "Framework version " + service.frameworkVersion - binding.frameworkVersionCode.text = "Framework version code " + service.frameworkVersionCode - binding.frameworkProperties.text = "Framework properties: " + service.frameworkProperties.toHexString() + binding.frameworkVersionCode.text = + "Framework version code " + service.frameworkVersionCode + val cap = service.frameworkProperties + val capStringList = mutableListOf() + if (cap.and(XposedService.PROP_CAP_SYSTEM) != 0L) { + capStringList.add("PROP_CAP_SYSTEM") + } + if (cap.and(XposedService.PROP_CAP_REMOTE) != 0L) { + capStringList.add("PROP_CAP_REMOTE") + } + if (cap.and(XposedService.PROP_RT_API_PROTECTION) != 0L) { + capStringList.add("PROP_RT_API_PROTECTION") + } + binding.frameworkProperties.text = + "Framework properties: $capStringList" binding.scope.text = "Scope: " + service.scope binding.requestScope.setOnClickListener { @@ -57,7 +93,7 @@ class MainActivity : Activity() { val old = prefs.getInt("test", -1) val new = Random.nextInt() Toast.makeText(this@MainActivity, "$old -> $new", Toast.LENGTH_SHORT).show() - prefs.edit().putInt("test", new).apply() + prefs.edit()?.putInt("test", new)?.apply() } binding.remoteFile.setOnClickListener { service.openRemoteFile("test.txt").use { pfd -> @@ -67,16 +103,6 @@ class MainActivity : Activity() { } } } - - override fun onServiceDied(service: XposedService) { - } - }) - - val handler = Handler(Looper.getMainLooper()) - handler.postDelayed({ - if (mService == null) { - binding.binder.text = "Binder is null" - } - }, 5000) + } } } diff --git a/build.gradle.kts b/build.gradle.kts index a596355..7f0594e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,3 @@ tasks.register("Delete", Delete::class) { - delete(rootProject.buildDir) + delete(rootProject.layout.buildDirectory) }