diff --git a/app/src/main/java/com/fankes/tsbattery/hook/entity/WeChatHooker.kt b/app/src/main/java/com/fankes/tsbattery/hook/entity/WeChatHooker.kt index e9401b4..15349ad 100644 --- a/app/src/main/java/com/fankes/tsbattery/hook/entity/WeChatHooker.kt +++ b/app/src/main/java/com/fankes/tsbattery/hook/entity/WeChatHooker.kt @@ -22,8 +22,10 @@ package com.fankes.tsbattery.hook.entity import android.app.Activity +import android.content.Context import android.os.Build import android.view.Gravity +import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout @@ -35,16 +37,16 @@ import com.fankes.tsbattery.hook.factory.hookSystemWakeLock import com.fankes.tsbattery.hook.factory.jumpToModuleSettings import com.fankes.tsbattery.hook.factory.startModuleSettings import com.fankes.tsbattery.utils.factory.absoluteStatusBarHeight -import com.fankes.tsbattery.utils.factory.dp import com.fankes.tsbattery.utils.factory.appVersionCode import com.fankes.tsbattery.utils.factory.appVersionName +import com.fankes.tsbattery.utils.factory.dp import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.factory.current import com.highcapable.yukihookapi.hook.factory.injectModuleAppResources import com.highcapable.yukihookapi.hook.factory.processName import com.highcapable.yukihookapi.hook.factory.registerModuleAppActivities import com.highcapable.yukihookapi.hook.log.loggerI -import com.highcapable.yukihookapi.hook.type.android.BundleClass +import com.highcapable.yukihookapi.hook.type.android.ViewClass /** * Hook 微信 @@ -65,6 +67,30 @@ object WeChatHooker : YukiBaseHooker() { /** 微信存在的类 - 未测试每个版本是否都存在 */ private const val SettingsUIClass = "${PackageName.WECHAT}.plugin.setting.ui.setting.SettingsUI" + /** TSBattery 图标 TAG 名称 */ + private const val TSBARRERY_ICON_TAG = "tsbattery_icon" + + /** + * 创建 TSBattery 图标 + * @param context 当前实例 + * @return [LinearLayout] + */ + private fun createPreferenceIcon(context: Context) = LinearLayout(context).apply { + tag = TSBARRERY_ICON_TAG + gravity = Gravity.END or Gravity.BOTTOM + layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + addView(ImageView(context).apply { + layoutParams = ViewGroup.MarginLayoutParams(20.dp(context), 20.dp(context)).apply { + topMargin = context.absoluteStatusBarHeight + 15.dp(context) + rightMargin = 20.dp(context) + } + setColorFilter(ResourcesCompat.getColor(resources, R.color.colorTextGray, null)) + setImageResource(R.drawable.ic_icon) + if (Build.VERSION.SDK_INT >= 26) tooltipText = "TSBattery 设置" + setOnClickListener { context.startModuleSettings() } + }) + } + override fun onHook() { onAppLifecycle { onCreate { @@ -97,32 +123,26 @@ object WeChatHooker : YukiBaseHooker() { SettingsUIClass.hook { injectMember { method { - name = "onCreate" - param(BundleClass) + name = "onResume" + emptyParam() } afterHook { method { name = "get_fragment" emptyParam() superClass(isOnlySuperClass = true) - }.get(instance).call()?.current() - ?.field { name = "mController" } - ?.current()?.method { name = "getContentView" } - ?.invoke()?.addView(LinearLayout(instance()).apply { - context.injectModuleAppResources() - gravity = Gravity.END or Gravity.BOTTOM - layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) - addView(ImageView(context).apply { - layoutParams = ViewGroup.MarginLayoutParams(20.dp(context), 20.dp(context)).apply { - topMargin = context.absoluteStatusBarHeight + 15.dp(context) - rightMargin = 20.dp(context) - } - setColorFilter(ResourcesCompat.getColor(resources, R.color.colorTextGray, null)) - setImageResource(R.drawable.ic_icon) - if (Build.VERSION.SDK_INT >= 26) tooltipText = "TSBattery 设置" - setOnClickListener { context.startModuleSettings() } - }) - }) + }.get(instance).call()?.current()?.method { + name = "getView" + emptyParam() + returnType = ViewClass + superClass(isOnlySuperClass = true) + }?.invoke()?.also { + it.context?.injectModuleAppResources() + runCatching { it.getChildAt(0) as? ViewGroup? }.getOrNull()?.also { rootView -> + if (rootView.findViewWithTag(TSBARRERY_ICON_TAG) == null) + rootView.addView(createPreferenceIcon(it.context)) + } + } } } }