From 1d250bb9fb7b3d00d1252699da5657da25d7aee2 Mon Sep 17 00:00:00 2001 From: Nullptr Date: Thu, 29 Dec 2022 20:11:53 +0800 Subject: [PATCH] Refactor ServiceClient --- .../hidemyapplist/service/ConfigManager.kt | 2 +- .../hidemyapplist/service/ServiceClient.kt | 85 +++++++++++++++++++ .../hidemyapplist/service/ServiceHelper.kt | 51 ----------- .../hidemyapplist/ui/fragment/HomeFragment.kt | 12 +-- .../hidemyapplist/ui/fragment/LogsFragment.kt | 6 +- .../ui/fragment/SettingsFragment.kt | 8 +- 6 files changed, 99 insertions(+), 65 deletions(-) create mode 100644 app/src/main/java/icu/nullptr/hidemyapplist/service/ServiceClient.kt delete mode 100644 app/src/main/java/icu/nullptr/hidemyapplist/service/ServiceHelper.kt diff --git a/app/src/main/java/icu/nullptr/hidemyapplist/service/ConfigManager.kt b/app/src/main/java/icu/nullptr/hidemyapplist/service/ConfigManager.kt index 949b0d6..49dbbe3 100644 --- a/app/src/main/java/icu/nullptr/hidemyapplist/service/ConfigManager.kt +++ b/app/src/main/java/icu/nullptr/hidemyapplist/service/ConfigManager.kt @@ -35,7 +35,7 @@ object ConfigManager { private fun saveConfig() { val text = config.toString() configFile.writeText(text) - ServiceHelper.submitConfig(text) + ServiceClient.syncConfig(text) } var detailLog: Boolean diff --git a/app/src/main/java/icu/nullptr/hidemyapplist/service/ServiceClient.kt b/app/src/main/java/icu/nullptr/hidemyapplist/service/ServiceClient.kt new file mode 100644 index 0000000..8ccc627 --- /dev/null +++ b/app/src/main/java/icu/nullptr/hidemyapplist/service/ServiceClient.kt @@ -0,0 +1,85 @@ +package icu.nullptr.hidemyapplist.service + +import android.os.IBinder.DeathRecipient +import android.os.Parcel +import android.os.RemoteException +import android.os.ServiceManager +import android.util.Log +import icu.nullptr.hidemyapplist.common.Constants +import icu.nullptr.hidemyapplist.common.IHMAService +import java.lang.reflect.InvocationHandler +import java.lang.reflect.Method +import java.lang.reflect.Proxy + +object ServiceClient : IHMAService, DeathRecipient { + + private const val TAG = "ServiceHelper" + + private class ServiceProxy(private val obj: IHMAService) : InvocationHandler { + override fun invoke(proxy: Any?, method: Method, args: Array?): Any? { + val result = method.invoke(obj, *args.orEmpty()) + if (result == null) Log.i(TAG, "Call service method ${method.name}") + else Log.i(TAG, "Call service method ${method.name} with result " + result.toString().take(20)) + return result + } + } + + @Volatile + private var service: IHMAService? = null + + override fun binderDied() { + service = null + Log.e(TAG, "Binder died") + } + + override fun asBinder() = service?.asBinder() + + private fun getService(): IHMAService? { + if (service != null) return service + val pm = ServiceManager.getService("package") + val data = Parcel.obtain() + val reply = Parcel.obtain() + val remote = try { + data.writeInterfaceToken(Constants.DESCRIPTOR) + data.writeInt(Constants.ACTION_GET_BINDER) + pm.transact(Constants.TRANSACTION, data, reply, 0) + reply.readException() + val binder = reply.readStrongBinder() + binder.linkToDeath(this, 0) + IHMAService.Stub.asInterface(binder) + } catch (e: RemoteException) { + Log.d(TAG, "Failed to get binder") + null + } finally { + data.recycle() + reply.recycle() + } + if (remote != null) { + Log.i(TAG, "Binder acquired") + service = Proxy.newProxyInstance( + javaClass.classLoader, + arrayOf(IHMAService::class.java), + ServiceProxy(remote) + ) as IHMAService + } + return service + } + + override fun getServiceVersion() = getService()?.serviceVersion ?: 0 + + override fun getFilterCount() = getService()?.filterCount ?: 0 + + override fun getLogs() = getService()?.logs + + override fun clearLogs() { + getService()?.clearLogs() + } + + override fun syncConfig(json: String) { + getService()?.syncConfig(json) + } + + override fun stopService(cleanEnv: Boolean) { + getService()?.stopService(cleanEnv) + } +} diff --git a/app/src/main/java/icu/nullptr/hidemyapplist/service/ServiceHelper.kt b/app/src/main/java/icu/nullptr/hidemyapplist/service/ServiceHelper.kt deleted file mode 100644 index f25706d..0000000 --- a/app/src/main/java/icu/nullptr/hidemyapplist/service/ServiceHelper.kt +++ /dev/null @@ -1,51 +0,0 @@ -package icu.nullptr.hidemyapplist.service - -import android.os.Parcel -import android.os.RemoteException -import android.os.ServiceManager -import android.util.Log -import icu.nullptr.hidemyapplist.common.Constants -import icu.nullptr.hidemyapplist.common.IHMAService - -object ServiceHelper { - - private const val TAG = "ServiceHelper" - - private fun getService(): IHMAService? { - val pm = ServiceManager.getService("package") - val data = Parcel.obtain() - val reply = Parcel.obtain() - return try { - data.writeInterfaceToken(Constants.DESCRIPTOR) - data.writeInt(Constants.ACTION_GET_BINDER) - pm.transact(Constants.TRANSACTION, data, reply, 0) - reply.readException() - val binder = reply.readStrongBinder() - IHMAService.Stub.asInterface(binder) - } catch (e: RemoteException) { - Log.d(TAG, "Failed to get binder") - null - } finally { - data.recycle() - reply.recycle() - } - } - - fun getServiceVersion() = getService()?.serviceVersion ?: 0 - - fun getFilterCount() = getService()?.filterCount ?: 0 - - fun getLogs() = getService()?.logs - - fun cleanLogs() { - getService()?.clearLogs() - } - - fun submitConfig(json: String) { - getService()?.syncConfig(json) - } - - fun stopSystemService(cleanEnv: Boolean) { - getService()?.stopService(cleanEnv) - } -} diff --git a/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/HomeFragment.kt b/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/HomeFragment.kt index d10c0ea..caa2792 100644 --- a/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/HomeFragment.kt +++ b/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/HomeFragment.kt @@ -23,7 +23,7 @@ import icu.nullptr.hidemyapplist.data.fetchLatestUpdate import icu.nullptr.hidemyapplist.hmaApp import icu.nullptr.hidemyapplist.service.ConfigManager import icu.nullptr.hidemyapplist.service.PrefManager -import icu.nullptr.hidemyapplist.service.ServiceHelper +import icu.nullptr.hidemyapplist.service.ServiceClient import icu.nullptr.hidemyapplist.ui.activity.AboutActivity import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.getColor import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.themeColor @@ -132,7 +132,7 @@ class HomeFragment : Fragment(R.layout.fragment_home) { override fun onStart() { super.onStart() - val serviceVersion = ServiceHelper.getServiceVersion() + val serviceVersion = ServiceClient.serviceVersion val color = when { !hmaApp.isHooked -> getColor(R.color.gray) serviceVersion == 0 -> getColor(R.color.invalid) @@ -146,19 +146,19 @@ class HomeFragment : Fragment(R.layout.fragment_home) { if (hmaApp.isHooked) { binding.moduleStatusIcon.setImageResource(R.drawable.outline_done_all_24) val versionNameSimple = BuildConfig.VERSION_NAME.substringBefore(".r") - binding.moduleStatus.text = String.format(getString(R.string.home_xposed_activated), versionNameSimple, BuildConfig.VERSION_CODE) + binding.moduleStatus.text = getString(R.string.home_xposed_activated, versionNameSimple, BuildConfig.VERSION_CODE) } else { binding.moduleStatusIcon.setImageResource(R.drawable.outline_extension_off_24) binding.moduleStatus.setText(R.string.home_xposed_not_activated) } if (serviceVersion != 0) { if (serviceVersion < icu.nullptr.hidemyapplist.common.BuildConfig.SERVICE_VERSION) { - binding.serviceStatus.text = String.format(getString(R.string.home_xposed_service_old)) + binding.serviceStatus.text = getString(R.string.home_xposed_service_old) } else { - binding.serviceStatus.text = String.format(getString(R.string.home_xposed_service_on), serviceVersion) + binding.serviceStatus.text = getString(R.string.home_xposed_service_on, serviceVersion) } binding.filterCount.visibility = View.VISIBLE - binding.filterCount.text = String.format(getString(R.string.home_xposed_filter_count), ServiceHelper.getFilterCount()) + binding.filterCount.text = getString(R.string.home_xposed_filter_count, ServiceClient.filterCount) } else { binding.serviceStatus.setText(R.string.home_xposed_service_off) binding.filterCount.visibility = View.GONE diff --git a/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/LogsFragment.kt b/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/LogsFragment.kt index 1ae05a3..f583a26 100644 --- a/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/LogsFragment.kt +++ b/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/LogsFragment.kt @@ -13,7 +13,7 @@ import com.tsng.hidemyapplist.R import com.tsng.hidemyapplist.databinding.FragmentLogsBinding import icu.nullptr.hidemyapplist.hmaApp import icu.nullptr.hidemyapplist.service.PrefManager -import icu.nullptr.hidemyapplist.service.ServiceHelper +import icu.nullptr.hidemyapplist.service.ServiceClient import icu.nullptr.hidemyapplist.ui.adapter.LogAdapter import icu.nullptr.hidemyapplist.ui.util.makeToast import icu.nullptr.hidemyapplist.ui.util.setupToolbar @@ -44,7 +44,7 @@ class LogsFragment : Fragment(R.layout.fragment_logs) { private fun updateLogs() { lifecycleScope.launch { - logCache = ServiceHelper.getLogs() + logCache = ServiceClient.logs val raw = logCache?.split("\n") if (raw == null) { binding.serviceOff.visibility = View.VISIBLE @@ -80,7 +80,7 @@ class LogsFragment : Fragment(R.layout.fragment_logs) { saveSAFLauncher.launch("hma_logs_$date.log") } R.id.menu_delete -> { - ServiceHelper.cleanLogs() + ServiceClient.clearLogs() updateLogs() } R.id.menu_filter_debug -> { diff --git a/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/SettingsFragment.kt b/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/SettingsFragment.kt index 1040ba5..d68f896 100644 --- a/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/SettingsFragment.kt +++ b/app/src/main/java/icu/nullptr/hidemyapplist/ui/fragment/SettingsFragment.kt @@ -21,7 +21,7 @@ import icu.nullptr.hidemyapplist.common.Constants import icu.nullptr.hidemyapplist.hmaApp import icu.nullptr.hidemyapplist.service.ConfigManager import icu.nullptr.hidemyapplist.service.PrefManager -import icu.nullptr.hidemyapplist.service.ServiceHelper +import icu.nullptr.hidemyapplist.service.ServiceClient import icu.nullptr.hidemyapplist.ui.util.makeToast import icu.nullptr.hidemyapplist.ui.util.setupToolbar import icu.nullptr.hidemyapplist.util.LangList @@ -164,16 +164,16 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) { ?.isEnabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R findPreference("stopSystemService")?.setOnPreferenceClickListener { - if (ServiceHelper.getServiceVersion() != 0) { + if (ServiceClient.serviceVersion != 0) { MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.settings_is_clean_env) .setMessage(R.string.settings_is_clean_env_summary) .setPositiveButton(R.string.yes) { _, _ -> - ServiceHelper.stopSystemService(true) + ServiceClient.stopService(true) makeToast(R.string.settings_stop_system_service) } .setNegativeButton(R.string.no) { _, _ -> - ServiceHelper.stopSystemService(false) + ServiceClient.stopService(false) makeToast(R.string.settings_stop_system_service) } .setNeutralButton(android.R.string.cancel, null)