移除KXH,迁移至EzXHelper

This commit is contained in:
LittleTurtle2333
2022-04-23 15:30:00 +08:00
parent 7e922f3ec6
commit b1373d7141
42 changed files with 1236 additions and 1797 deletions

View File

@@ -1,31 +1,27 @@
package com.lt2333.simplicitytools.hook.app package com.lt2333.simplicitytools.hook.app
import com.lt2333.simplicitytools.util.XSPUtils import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.lt2333.simplicitytools.util.hookBeforeMethod import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
import com.github.kyuubiran.ezxhelper.utils.loadClassOrNull
import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.AppRegister import com.lt2333.simplicitytools.util.xposed.base.AppRegister
import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.callbacks.XC_LoadPackage import de.robv.android.xposed.callbacks.XC_LoadPackage
object Updater: AppRegister() { object Updater : AppRegister() {
override val packageName: String = "com.android.updater" override val packageName: String = "com.android.updater"
override val processName: List<String> = emptyList() override val processName: List<String> = emptyList()
override val logTag: String = "WooBox" override val logTag: String = "WooBox"
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) { override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
if (XSPUtils.getBoolean("remove_ota_validate", false)) { XposedBridge.log("WooBox: 成功 Hook " + javaClass.simpleName)
var letter = 'a'
for (i in 0..25) { hasEnable("remove_ota_validate") {
val classIfExists = XposedHelpers.findClassIfExists( Array(26) { "com.android.updater.common.utils.${'a' + it}" }
"com.android.updater.common.utils.$letter", lpparam.classLoader .mapNotNull { loadClassOrNull(it) }
) ?: continue .firstOrNull() { it.declaredFields.size >= 9 && it.declaredMethods.size > 60 }
if (classIfExists.declaredFields.size >= 9 && classIfExists.declaredMethods.size > 60) { ?.findMethod { name == "T" && returnType == Boolean::class.java }
classIfExists.hookBeforeMethod("T") { ?.hookReturnConstant(false)
it.result = false
}
return
}
letter++
}
} }
} }
} }

View File

@@ -1,21 +1,15 @@
package com.lt2333.simplicitytools.hook.app.android package com.lt2333.simplicitytools.hook.app.android
import android.content.Context import android.content.Context
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object AllowUntrustedTouches : HookRegister() { object AllowUntrustedTouches : HookRegister() {
override fun init() = hasEnable("allow_untrusted_touches") {
override fun init() { findMethod("android.hardware.input.InputManager") {
hasEnable("allow_untrusted_touches") { name == "getBlockUntrustedTouchesMode" && parameterTypes[0] == Context::class.java
"android.hardware.input.InputManager".hookBeforeMethod( }.hookReturnConstant(0)
getDefaultClassLoader(),
"getBlockUntrustedTouchesMode",
Context::class.java
) {
it.result = 0
}
}
} }
} }

View File

@@ -1,17 +1,18 @@
package com.lt2333.simplicitytools.hook.app.android package com.lt2333.simplicitytools.hook.app.android
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object DeleteOnPostNotification : HookRegister() { object DeleteOnPostNotification : HookRegister() {
override fun init() { override fun init() {
"com.android.server.wm.AlertWindowNotification".hookBeforeMethod(getDefaultClassLoader(), "onPostNotification") { findMethod("com.android.server.wm.AlertWindowNotification") {
name == "onPostNotification"
}.hookBefore {
hasEnable("delete_on_post_notification") { hasEnable("delete_on_post_notification") {
it.result = null it.result = null
} }
} }
} }
} }

View File

@@ -1,17 +1,18 @@
package com.lt2333.simplicitytools.hook.app.android package com.lt2333.simplicitytools.hook.app.android
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object DisableFlagSecure : HookRegister() { object DisableFlagSecure : HookRegister() {
override fun init() { override fun init() {
"com.android.server.wm.WindowState".hookBeforeMethod(getDefaultClassLoader(), "isSecureLocked") { findMethod("com.android.server.wm.WindowState") {
name == "isSecureLocked"
}.hookBefore {
hasEnable("disable_flag_secure") { hasEnable("disable_flag_secure") {
it.result = false it.result = false
} }
} }
} }
} }

View File

@@ -1,17 +1,18 @@
package com.lt2333.simplicitytools.hook.app.android package com.lt2333.simplicitytools.hook.app.android
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.github.kyuubiran.ezxhelper.utils.putObject
import com.lt2333.simplicitytools.util.XSPUtils import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.setFloatField
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object MaxWallpaperScale : HookRegister() { object MaxWallpaperScale : HookRegister() {
override fun init() { override fun init() {
"com.android.server.wm.WallpaperController".hookBeforeMethod(getDefaultClassLoader(), "zoomOutToScale", Float::class.java) { findMethod("com.android.server.wm.WallpaperController") {
name == "zoomOutToScale" && parameterTypes[0] == Float::class.java
}.hookBefore {
val value = XSPUtils.getFloat("max_wallpaper_scale", 1.1f) val value = XSPUtils.getFloat("max_wallpaper_scale", 1.1f)
it.thisObject.setFloatField("mMaxWallpaperScale", value) it.thisObject.putObject("mMaxWallpaperScale", value)
} }
} }
} }

View File

@@ -1,38 +1,45 @@
package com.lt2333.simplicitytools.hook.app.android package com.lt2333.simplicitytools.hook.app.android
import android.content.Context import android.content.Context
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object RemoveSmallWindowRestrictions : HookRegister() { object RemoveSmallWindowRestrictions : HookRegister() {
override fun init() { override fun init() {
// 强制所有活动设为可以调整大小 // 强制所有活动设为可以调整大小
"com.android.server.wm.Task".hookBeforeMethod(getDefaultClassLoader(), "isResizeable") { findMethod("com.android.server.wm.Task") {
name == "isResizeable"
}.hookBefore {
hasEnable("remove_small_window_restrictions") { hasEnable("remove_small_window_restrictions") {
it.result = true it.result = true
} }
} }
"android.util.MiuiMultiWindowAdapter".hookAfterMethod(getDefaultClassLoader(), "getFreeformBlackList") { findMethod("android.util.MiuiMultiWindowAdapter") {
name == "getFreeformBlackList"
}.hookAfter {
hasEnable("remove_small_window_restrictions") { hasEnable("remove_small_window_restrictions") {
it.result = (it.result as MutableList<*>).apply { clear() } it.result = (it.result as MutableList<*>).apply { clear() }
} }
} }
"android.util.MiuiMultiWindowAdapter".hookAfterMethod(getDefaultClassLoader(), "getFreeformBlackListFromCloud", Context::class.java) { findMethod("android.util.MiuiMultiWindowAdapter") {
name == "getFreeformBlackListFromCloud" && parameterTypes[0] == Context::class.java
}.hookAfter {
hasEnable("remove_small_window_restrictions") { hasEnable("remove_small_window_restrictions") {
it.result = (it.result as MutableList<*>).apply { clear() } it.result = (it.result as MutableList<*>).apply { clear() }
} }
} }
"android.util.MiuiMultiWindowUtils".hookAfterMethod(getDefaultClassLoader(), "supportFreeform") { findMethod("android.util.MiuiMultiWindowUtils") {
name == "supportFreeform"
}.hookAfter {
hasEnable("remove_small_window_restrictions") { hasEnable("remove_small_window_restrictions") {
it.result = true it.result = true
} }
} }
} }
} }

View File

@@ -1,7 +1,8 @@
package com.lt2333.simplicitytools.hook.app.android package com.lt2333.simplicitytools.hook.app.android
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.XSPUtils import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object SystemPropertiesHook : HookRegister() { object SystemPropertiesHook : HookRegister() {
@@ -9,16 +10,12 @@ object SystemPropertiesHook : HookRegister() {
val mediaStepsSwitch = XSPUtils.getBoolean("media_volume_steps_switch", false) val mediaStepsSwitch = XSPUtils.getBoolean("media_volume_steps_switch", false)
val mediaSteps = XSPUtils.getInt("media_volume_steps", 15) val mediaSteps = XSPUtils.getInt("media_volume_steps", 15)
"android.os.SystemProperties".hookBeforeMethod( findMethod("android.os.SystemProperties") {
getDefaultClassLoader(), name == "getInt" && returnType == Int::class.java
"getInt", }.hookBefore {
String::class.java,
Int::class.java
) {
when (it.args[0] as String) { when (it.args[0] as String) {
"ro.config.media_vol_steps" -> if (mediaStepsSwitch) it.result = mediaSteps "ro.config.media_vol_steps" -> if (mediaStepsSwitch) it.result = mediaSteps
} }
} }
} }
} }

View File

@@ -3,52 +3,48 @@ package com.lt2333.simplicitytools.hook.app.miuihome
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.view.MotionEvent import android.view.MotionEvent
import com.github.kyuubiran.ezxhelper.utils.*
import com.lt2333.simplicitytools.util.* import com.lt2333.simplicitytools.util.*
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import com.yuk.miuihome.module.DoubleTapController import com.yuk.miuihome.module.DoubleTapController
import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.XposedHelpers
object DoubleTapToSleep : HookRegister() { object DoubleTapToSleep : HookRegister() {
override fun init() = hasEnable("double_tap_to_sleep") {
override fun init() { hookAllConstructorAfter("com.miui.home.launcher.Workspace") {
hasEnable("double_tap_to_sleep") { var mDoubleTapControllerEx =
"com.miui.home.launcher.Workspace".findClass(getDefaultClassLoader()) XposedHelpers.getAdditionalInstanceField(
.hookAfterAllConstructors {
var mDoubleTapControllerEx =
XposedHelpers.getAdditionalInstanceField(
it.thisObject,
"mDoubleTapControllerEx"
)
if (mDoubleTapControllerEx != null) return@hookAfterAllConstructors
mDoubleTapControllerEx = DoubleTapController((it.args[0] as Context))
XposedHelpers.setAdditionalInstanceField(
it.thisObject,
"mDoubleTapControllerEx",
mDoubleTapControllerEx
)
}
"com.miui.home.launcher.Workspace".findClass(getDefaultClassLoader()).hookBeforeMethod(
"dispatchTouchEvent", MotionEvent::class.java
) {
val mDoubleTapControllerEx = XposedHelpers.getAdditionalInstanceField(
it.thisObject, it.thisObject,
"mDoubleTapControllerEx" "mDoubleTapControllerEx"
) as DoubleTapController
if (!mDoubleTapControllerEx.isDoubleTapEvent(it.args[0] as MotionEvent)) return@hookBeforeMethod
val mCurrentScreenIndex = it.thisObject.getIntField("mCurrentScreenIndex")
val cellLayout = it.thisObject.callMethod("getCellLayout", mCurrentScreenIndex)
if (cellLayout != null) if (cellLayout.callMethod("lastDownOnOccupiedCell") as Boolean) return@hookBeforeMethod
if (it.thisObject.callMethod("isInNormalEditingMode") as Boolean) return@hookBeforeMethod
val context = it.thisObject.callMethod("getContext") as Context
context.sendBroadcast(
Intent("com.miui.app.ExtraStatusBarManager.action_TRIGGER_TOGGLE").putExtra(
"com.miui.app.ExtraStatusBarManager.extra_TOGGLE_ID",
10
)
) )
} if (mDoubleTapControllerEx != null) return@hookAllConstructorAfter
mDoubleTapControllerEx = DoubleTapController((it.args[0] as Context))
XposedHelpers.setAdditionalInstanceField(
it.thisObject,
"mDoubleTapControllerEx",
mDoubleTapControllerEx
)
}
findMethod("com.miui.home.launcher.Workspace") {
name == "dispatchTouchEvent" && parameterTypes[0] == MotionEvent::class.java
}.hookBefore {
val mDoubleTapControllerEx = XposedHelpers.getAdditionalInstanceField(
it.thisObject,
"mDoubleTapControllerEx"
) as DoubleTapController
if (!mDoubleTapControllerEx.isDoubleTapEvent(it.args[0] as MotionEvent)) return@hookBefore
val mCurrentScreenIndex = it.thisObject.getObject("mCurrentScreenIndex") as Int
val cellLayout = it.thisObject.invokeMethodAuto("getCellLayout", mCurrentScreenIndex)
if (cellLayout != null) if (cellLayout.invokeMethodAuto("lastDownOnOccupiedCell") as Boolean) return@hookBefore
if (it.thisObject.invokeMethodAuto("isInNormalEditingMode") as Boolean) return@hookBefore
val context = it.thisObject.invokeMethodAuto("getContext") as Context
context.sendBroadcast(
Intent("com.miui.app.ExtraStatusBarManager.action_TRIGGER_TOGGLE").putExtra(
"com.miui.app.ExtraStatusBarManager.extra_TOGGLE_ID",
10
)
)
} }
} }
} }

View File

@@ -1,29 +1,29 @@
package com.lt2333.simplicitytools.hook.app.securitycenter package com.lt2333.simplicitytools.hook.app.securitycenter
import android.view.View import android.view.View
import com.lt2333.simplicitytools.util.XSPUtils import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.lt2333.simplicitytools.util.findClass import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hookBeforeMethod import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object LockOneHundred : HookRegister() { object LockOneHundred : HookRegister() {
override fun init() { override fun init() {
//防止点击重新检测 //防止点击重新检测
val mainContentFrameClass = "com.miui.securityscan.ui.main.MainContentFrame".findClass(getDefaultClassLoader()) findMethod("com.miui.securityscan.ui.main.MainContentFrame") {
mainContentFrameClass.hookBeforeMethod("onClick", View::class.java) { name == "onClick" && parameterTypes[0] == View::class.java
if (XSPUtils.getBoolean("lock_one_hundred", false)) { }.hookBefore {
hasEnable("lock_one_hundred") {
it.result = null it.result = null
} }
} }
//锁定100分 //锁定100分
val scoreManagerClass = "com.miui.securityscan.scanner.ScoreManager".findClass(getDefaultClassLoader()) findMethod("com.miui.securityscan.scanner.ScoreManager") {
scoreManagerClass.hookBeforeMethod("B") { name == "B"
if (XSPUtils.getBoolean("lock_one_hundred", false)) { }.hookBefore {
hasEnable("lock_one_hundred") {
it.result = 0 it.result = 0
} }
} }
} }
} }

View File

@@ -1,22 +1,17 @@
package com.lt2333.simplicitytools.hook.app.securitycenter package com.lt2333.simplicitytools.hook.app.securitycenter
import android.widget.TextView import android.widget.TextView
import com.lt2333.simplicitytools.util.XSPUtils import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.lt2333.simplicitytools.util.findClass import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.hookAfterMethod import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.IXposedHookLoadPackage
import de.robv.android.xposed.callbacks.XC_LoadPackage
object RemoveOpenAppConfirmationPopup : HookRegister() { object RemoveOpenAppConfirmationPopup : HookRegister() {
override fun init() { override fun init() {
val textViewClass = "android.widget.TextView".findClass(getDefaultClassLoader()) findMethod("android.widget.TextView") {
textViewClass.hookAfterMethod( name == "setText" && parameterTypes[0] == CharSequence::class.java
"setText", }.hookAfter {
CharSequence::class.java hasEnable("remove_open_app_confirmation_popup") {
) {
if (XSPUtils.getBoolean("remove_open_app_confirmation_popup", false)) {
val textView = it.thisObject as TextView val textView = it.thisObject as TextView
if (it.args.isNotEmpty() && it.args[0]?.toString().equals( if (it.args.isNotEmpty() && it.args[0]?.toString().equals(
textView.context.resources.getString( textView.context.resources.getString(
@@ -33,5 +28,4 @@ object RemoveOpenAppConfirmationPopup : HookRegister() {
} }
} }
} }
} }

View File

@@ -13,14 +13,15 @@ import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import cn.fkj233.ui.activity.dp2px import cn.fkj233.ui.activity.dp2px
import com.lt2333.simplicitytools.util.XSPUtils import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.lt2333.simplicitytools.util.findClass import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.hookAfterMethod import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hookBeforeMethod import com.github.kyuubiran.ezxhelper.utils.loadClass
import com.lt2333.simplicitytools.util.*
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import java.lang.reflect.Field import java.lang.reflect.Field
object ShowBatteryTemperature: HookRegister() { object ShowBatteryTemperature : HookRegister() {
private fun getBatteryTemperature(context: Context): Int { private fun getBatteryTemperature(context: Context): Int {
return context.registerReceiver( return context.registerReceiver(
@@ -29,17 +30,26 @@ object ShowBatteryTemperature: HookRegister() {
)!!.getIntExtra("temperature", 0) / 10 )!!.getIntExtra("temperature", 0) / 10
} }
override fun init() { override fun init() = hasEnable("battery_life_function") {
if (!XSPUtils.getBoolean("battery_life_function", false)) return findMethod("com.miui.powercenter.a") {
val a = "com.miui.powercenter.a\$a".findClass(getDefaultClassLoader()) name == "b" && parameterTypes[0] == Context::class.java
"com.miui.powercenter.a".hookBeforeMethod(getDefaultClassLoader(), "b", Context::class.java) { }.hookBefore {
it.result = getBatteryTemperature(it.args[0] as Context).toString() it.result = getBatteryTemperature(it.args[0] as Context).toString()
} }
a.hookAfterMethod("run") {
findMethod("com.miui.powercenter.a\$a") {
name == "run"
}.hookAfter {
val context = AndroidAppHelper.currentApplication().applicationContext val context = AndroidAppHelper.currentApplication().applicationContext
val isDarkMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES val isDarkMode =
val currentTemperatureValue = context.resources.getIdentifier("current_temperature_value", "id", "com.miui.securitycenter") context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
val field = a.getDeclaredField("a") as Field val currentTemperatureValue = context.resources.getIdentifier(
"current_temperature_value",
"id",
"com.miui.securitycenter"
)
val field = loadClass("com.miui.powercenter.a\$a").getDeclaredField("a") as Field
field.isAccessible = true field.isAccessible = true
val view = field.get(it.thisObject) as View val view = field.get(it.thisObject) as View
val textView = view.findViewById<TextView>(currentTemperatureValue) val textView = view.findViewById<TextView>(currentTemperatureValue)
@@ -52,18 +62,25 @@ object ShowBatteryTemperature: HookRegister() {
textView.height = dp2px(context, 49.099983f) textView.height = dp2px(context, 49.099983f)
textView.textAlignment = View.TEXT_ALIGNMENT_VIEW_START textView.textAlignment = View.TEXT_ALIGNMENT_VIEW_START
val tempView = TextView(context) val tempView = TextView(context)
tempView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp2px(context, 49.099983f)) tempView.layoutParams = LinearLayout.LayoutParams(
(tempView.layoutParams as LinearLayout.LayoutParams).marginStart = dp2px(context, 3.599976f) LinearLayout.LayoutParams.MATCH_PARENT,
dp2px(context, 49.099983f)
)
(tempView.layoutParams as LinearLayout.LayoutParams).marginStart =
dp2px(context, 3.599976f)
tempView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13.099977f) tempView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13.099977f)
tempView.setTextColor(Color.parseColor(if (isDarkMode) "#e6e6e6" else "#333333")) tempView.setTextColor(Color.parseColor(if (isDarkMode) "#e6e6e6" else "#333333"))
tempView.setPadding(0, dp2px(context, 25f), 0, 0) tempView.setPadding(0, dp2px(context, 25f), 0, 0)
tempView.text = "" tempView.text = ""
tempView.typeface = Typeface.create(null, 500, false) tempView.typeface = Typeface.create(null, 500, false)
tempView.textAlignment = View.TEXT_ALIGNMENT_VIEW_START tempView.textAlignment = View.TEXT_ALIGNMENT_VIEW_START
val tempeValueContainer = context.resources.getIdentifier("tempe_value_container", "id", "com.miui.securitycenter") val tempeValueContainer = context.resources.getIdentifier(
"tempe_value_container",
"id",
"com.miui.securitycenter"
)
val linearLayout = view.findViewById<LinearLayout>(tempeValueContainer) val linearLayout = view.findViewById<LinearLayout>(tempeValueContainer)
linearLayout.addView(tempView) linearLayout.addView(tempView)
} }
} }
} }

View File

@@ -1,23 +1,16 @@
package com.lt2333.simplicitytools.hook.app.securitycenter package com.lt2333.simplicitytools.hook.app.securitycenter
import android.widget.TextView import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.lt2333.simplicitytools.util.XSPUtils import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.findClass import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object SkipWaitingTime : HookRegister() { object SkipWaitingTime : HookRegister() {
override fun init() { override fun init() {
val textViewClass = "android.widget.TextView".findClass(getDefaultClassLoader()) findMethod("android.widget.TextView") {
textViewClass.hookBeforeMethod( name == "setText" && parameterCount == 4
"setText", }.hookBefore {
CharSequence::class.java, hasEnable("skip_waiting_time") {
TextView.BufferType::class.java,
Boolean::class.java,
Int::class.java
) {
if (XSPUtils.getBoolean("skip_waiting_time", false)) {
if (it.args.isNotEmpty() && it.args[0]?.toString()?.startsWith("确定(") == true if (it.args.isNotEmpty() && it.args[0]?.toString()?.startsWith("确定(") == true
) { ) {
it.args[0] = "确定" it.args[0] = "确定"
@@ -25,14 +18,12 @@ object SkipWaitingTime : HookRegister() {
} }
} }
textViewClass.hookBeforeMethod( findMethod("android.widget.TextView") {
"setEnabled", name == "setEnabled" && parameterTypes[0] == Boolean::class.java
Boolean::class.java }.hookBefore {
) { hasEnable("skip_waiting_time") {
if (XSPUtils.getBoolean("skip_waiting_time", false)) {
it.args[0] = true it.args[0] = true
} }
} }
} }
} }

View File

@@ -1,6 +1,7 @@
package com.lt2333.simplicitytools.hook.app.settings package com.lt2333.simplicitytools.hook.app.settings
import android.app.NotificationChannel import android.app.NotificationChannel
import com.github.kyuubiran.ezxhelper.utils.*
import com.lt2333.simplicitytools.util.* import com.lt2333.simplicitytools.util.*
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.XposedHelpers
@@ -8,27 +9,29 @@ import de.robv.android.xposed.XposedHelpers
object ShowNotificationImportance : HookRegister() { object ShowNotificationImportance : HookRegister() {
override fun init() { override fun init() {
val channelNotificationSettingsClass = "com.android.settings.notification.ChannelNotificationSettings".findClass(getDefaultClassLoader()) findMethod("com.android.settings.notification.ChannelNotificationSettings"){
channelNotificationSettingsClass.hookBeforeMethod("removeDefaultPrefs") { name == "removeDefaultPrefs"
if (!XSPUtils.getBoolean("show_notification_importance", false)) return@hookBeforeMethod }.hookBefore {
val importance = it.thisObject.callMethod("findPreference", "importance") ?: return@hookBeforeMethod if (!XSPUtils.getBoolean("show_notification_importance", false)) return@hookBefore
val mChannel = it.thisObject.getObjectField("mChannel") as NotificationChannel val importance = it.thisObject.invokeMethodAuto("findPreference", "importance") ?: return@hookBefore
val index = importance.callMethod("findSpinnerIndexOfValue", mChannel.importance.toString()) as Int val mChannel = it.thisObject.getObject("mChannel") as NotificationChannel
if (index < 0) return@hookBeforeMethod val index = importance.invokeMethodAuto("findSpinnerIndexOfValue", mChannel.importance.toString()) as Int
importance.callMethod("setValueIndex", index) if (index < 0) return@hookBefore
importance.invokeMethodAuto("setValueIndex", index)
XposedHelpers.setAdditionalInstanceField(importance, "channelNotificationSettings", it.thisObject) XposedHelpers.setAdditionalInstanceField(importance, "channelNotificationSettings", it.thisObject)
it.result = null it.result = null
} }
val dropDownPreferenceClass = XposedHelpers.findClass("androidx.preference.Preference", getDefaultClassLoader()) findMethod("androidx.preference.Preference"){
dropDownPreferenceClass.hookAfterMethod("callChangeListener", Any::class.java) { name == "callChangeListener" && parameterTypes[0]==Any::class.java
val channelNotificationSettings = XposedHelpers.getAdditionalInstanceField(it.thisObject, "channelNotificationSettings") ?: return@hookAfterMethod }.hookAfter {
val mChannel = channelNotificationSettings.getObjectField("mChannel") as NotificationChannel val channelNotificationSettings = XposedHelpers.getAdditionalInstanceField(it.thisObject, "channelNotificationSettings") ?: return@hookAfter
mChannel.callMethod("setImportance", (it.args[0] as String).toInt()) val mChannel = channelNotificationSettings.getObject("mChannel") as NotificationChannel
val mBackend = channelNotificationSettings.getObjectField("mBackend") ?: return@hookAfterMethod mChannel.invokeMethodAuto("setImportance", (it.args[0] as String).toInt())
val mPkg = channelNotificationSettings.getObjectField("mPkg") as String val mBackend = channelNotificationSettings.getObjectOrNull("mBackend") ?: return@hookAfter
val mUid = channelNotificationSettings.getIntField("mUid") val mPkg = channelNotificationSettings.getObject("mPkg") as String
mBackend.callMethod("updateChannel", mPkg, mUid, mChannel) val mUid = channelNotificationSettings.getObject("mUid") as Int
mBackend.invokeMethodAuto("updateChannel", mPkg, mUid, mChannel)
} }
} }

View File

@@ -2,24 +2,22 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.util.TypedValue import android.util.TypedValue
import android.widget.TextView import android.widget.TextView
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.XSPUtils import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.getObjectField
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object BatteryPercentage: HookRegister() { object BatteryPercentage : HookRegister() {
override fun init() { override fun init() {
val size = XSPUtils.getFloat("battery_percentage_font_size", 0f) val size = XSPUtils.getFloat("battery_percentage_font_size", 0f)
if (size == 0f) return if (size == 0f) return
"com.android.systemui.statusbar.views.MiuiBatteryMeterView".hookAfterMethod( findMethod("com.android.systemui.statusbar.views.MiuiBatteryMeterView") {
getDefaultClassLoader(), name == "updateResources"
"updateResources" }.hookAfter {
) { (it.thisObject.getObject("mBatteryPercentView") as TextView).setTextSize(
(it.thisObject.getObjectField("mBatteryPercentView") as TextView).setTextSize(
TypedValue.COMPLEX_UNIT_DIP, size TypedValue.COMPLEX_UNIT_DIP, size
) )
} }
} }
} }

View File

@@ -9,216 +9,212 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import cn.fkj233.ui.activity.dp2px import cn.fkj233.ui.activity.dp2px
import com.github.kyuubiran.ezxhelper.utils.loadClass import com.github.kyuubiran.ezxhelper.utils.*
import com.lt2333.simplicitytools.util.* import com.lt2333.simplicitytools.util.SystemProperties
import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import com.lt2333.simplicitytools.view.WeatherView import com.lt2333.simplicitytools.view.WeatherView
object ControlCenterWeather: HookRegister() { object ControlCenterWeather : HookRegister() {
override fun init() = hasEnable("control_center_weather") {
var mWeatherView: TextView? = null
var mConstraintLayout: ConstraintLayout? = null
val isDisplayCity = XSPUtils.getBoolean("control_center_weather_city", false)
findMethod("com.android.systemui.controlcenter.phone.widget.QSControlCenterHeaderView") {
name == "onFinishInflate"
}.hookAfter {
val viewGroup = it.thisObject as ViewGroup
val context = viewGroup.context
override fun init() { // MIUI编译时间大于 2022-03-12 00:00:00 且为内测版
hasEnable("control_center_weather") { if (SystemProperties.get(context, "ro.build.date.utc")!!
var mWeatherView: TextView? = null .toInt() >= 1647014400 &&
var mConstraintLayout: ConstraintLayout? = null
val isDisplayCity = XSPUtils.getBoolean("control_center_weather_city", false) !SystemProperties.get(
"com.android.systemui.controlcenter.phone.widget.QSControlCenterHeaderView".hookAfterMethod( context,
getDefaultClassLoader(), "ro.build.version.incremental"
"onFinishInflate" )!!.endsWith("DEV") &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("XM")
) { ) {
val viewGroup = it.thisObject as ViewGroup //获取原组件
val context = viewGroup.context val big_time_ID =
context.resources.getIdentifier("big_time", "id", context.packageName)
val big_time: TextView = viewGroup.findViewById(big_time_ID)
// MIUI编译时间大于 2022-03-12 00:00:00 且为内测版 val date_time_ID =
if (SystemProperties.get(context, "ro.build.date.utc")!! context.resources.getIdentifier("date_time", "id", context.packageName)
.toInt() >= 1647014400 && val date_time: TextView = viewGroup.findViewById(date_time_ID)
!SystemProperties.get( //创建新布局
context, val mConstraintLayoutLp = LinearLayout.LayoutParams(
"ro.build.version.incremental" LinearLayout.LayoutParams.MATCH_PARENT,
)!!.endsWith("DEV") && LinearLayout.LayoutParams.WRAP_CONTENT
).also {
!SystemProperties.get( it.topMargin = context.resources.getDimensionPixelSize(
context, context.resources.getIdentifier(
"ro.build.version.incremental" "qs_control_header_tiles_margin_top",
)!!.endsWith("XM") "dimen",
) { context.packageName
//获取原组件
val big_time_ID =
context.resources.getIdentifier("big_time", "id", context.packageName)
val big_time: TextView = viewGroup.findViewById(big_time_ID)
val date_time_ID =
context.resources.getIdentifier("date_time", "id", context.packageName)
val date_time: TextView = viewGroup.findViewById(date_time_ID)
//创建新布局
val mConstraintLayoutLp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).also {
it.topMargin = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"qs_control_header_tiles_margin_top",
"dimen",
context.packageName
)
) )
}
mConstraintLayout =
ConstraintLayout(context).also { it.layoutParams = mConstraintLayoutLp }
(big_time.parent as ViewGroup).addView(mConstraintLayout, 0)
//从原布局中删除组件
(big_time.parent as ViewGroup).removeView(big_time)
(date_time.parent as ViewGroup).removeView(date_time)
//添加组件至新布局
mConstraintLayout!!.addView(big_time)
mConstraintLayout!!.addView(date_time)
//组件属性
val date_time_LP = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
).also {
it.startToEnd = big_time_ID
it.bottomToBottom = 0
it.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"notification_panel_time_date_space",
"dimen",
context.packageName
)
)
it.bottomMargin = dp2px(context, 5f)
}
date_time.layoutParams = date_time_LP
//创建天气组件
mWeatherView = WeatherView(context, isDisplayCity).apply {
setTextAppearance(
context.resources.getIdentifier(
"TextAppearance.QSControl.Date",
"style",
context.packageName
)
)
}
mConstraintLayout!!.addView(mWeatherView)
val mWeatherView_LP = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
).also {
it.startToEnd = big_time_ID
it.bottomToTop = date_time_ID
it.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"notification_panel_time_date_space",
"dimen",
context.packageName
)
)
}
(mWeatherView as WeatherView).layoutParams = mWeatherView_LP
} else {
val layoutParam =
loadClass("androidx.constraintlayout.widget.ConstraintLayout\$LayoutParams").getConstructor(
Int::class.java,
Int::class.java
).newInstance(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
) as ViewGroup.MarginLayoutParams
layoutParam.setObjectField(
"bottomToTop",
context.resources.getIdentifier("date_time", "id", context.packageName)
) )
layoutParam.setObjectField( }
"startToEnd",
context.resources.getIdentifier("big_time", "id", context.packageName) mConstraintLayout =
) ConstraintLayout(context).also { it.layoutParams = mConstraintLayoutLp }
layoutParam.marginStart = context.resources.getDimensionPixelSize(
(big_time.parent as ViewGroup).addView(mConstraintLayout, 0)
//从原布局中删除组件
(big_time.parent as ViewGroup).removeView(big_time)
(date_time.parent as ViewGroup).removeView(date_time)
//添加组件至新布局
mConstraintLayout!!.addView(big_time)
mConstraintLayout!!.addView(date_time)
//组件属性
val date_time_LP = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
).also {
it.startToEnd = big_time_ID
it.bottomToBottom = 0
it.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier( context.resources.getIdentifier(
"notification_panel_time_date_space", "notification_panel_time_date_space",
"dimen", "dimen",
context.packageName context.packageName
) )
) )
mWeatherView = WeatherView(context, isDisplayCity).apply { it.bottomMargin = dp2px(context, 5f)
setTextAppearance( }
context.resources.getIdentifier( date_time.layoutParams = date_time_LP
"TextAppearance.QSControl.Date",
"style",
context.packageName //创建天气组件
) mWeatherView = WeatherView(context, isDisplayCity).apply {
setTextAppearance(
context.resources.getIdentifier(
"TextAppearance.QSControl.Date",
"style",
context.packageName
) )
layoutParams = layoutParam )
}
viewGroup.addView(mWeatherView) }
mConstraintLayout!!.addView(mWeatherView)
val mWeatherView_LP = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
).also {
it.startToEnd = big_time_ID
it.bottomToTop = date_time_ID
it.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"notification_panel_time_date_space",
"dimen",
context.packageName
)
)
} }
(mWeatherView as WeatherView).setOnClickListener { (mWeatherView as WeatherView).layoutParams = mWeatherView_LP
try {
val intent = Intent().apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
component = ComponentName(
"com.miui.weather2",
"com.miui.weather2.ActivityWeatherMain"
)
}
context.startActivity(intent)
} catch (e: Exception) {
Toast.makeText(context, "启动失败", Toast.LENGTH_LONG).show()
}
}
} else {
val layoutParam =
loadClass("androidx.constraintlayout.widget.ConstraintLayout\$LayoutParams").getConstructor(
Int::class.java,
Int::class.java
).newInstance(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
) as ViewGroup.MarginLayoutParams
layoutParam.putObject(
"bottomToTop",
context.resources.getIdentifier("date_time", "id", context.packageName)
)
layoutParam.putObject(
"startToEnd",
context.resources.getIdentifier("big_time", "id", context.packageName)
)
layoutParam.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"notification_panel_time_date_space",
"dimen",
context.packageName
)
)
mWeatherView = WeatherView(context, isDisplayCity).apply {
setTextAppearance(
context.resources.getIdentifier(
"TextAppearance.QSControl.Date",
"style",
context.packageName
)
)
layoutParams = layoutParam
}
viewGroup.addView(mWeatherView)
} }
//解决横屏重叠
"com.android.systemui.controlcenter.phone.widget.QSControlCenterHeaderView".hookAfterMethod( (mWeatherView as WeatherView).setOnClickListener {
getDefaultClassLoader(), try {
"updateLayout" val intent = Intent().apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
component = ComponentName(
"com.miui.weather2",
"com.miui.weather2.ActivityWeatherMain"
)
}
context.startActivity(intent)
} catch (e: Exception) {
Toast.makeText(context, "启动失败", Toast.LENGTH_LONG).show()
}
}
}
//解决横屏重叠
findMethod("com.android.systemui.controlcenter.phone.widget.QSControlCenterHeaderView") {
name == "updateLayout"
}.hookAfter {
val viewGroup = it.thisObject as ViewGroup
val context = viewGroup.context
val mOrientation = viewGroup.getObject("mOrientation") as Int
// MIUI编译时间大于 2022-03-12 00:00:00 且为内测版
if (SystemProperties.get(context, "ro.build.date.utc")!!
.toInt() >= 1647014400 &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("DEV") &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("XM")
) { ) {
val viewGroup = it.thisObject as ViewGroup if (mOrientation == 1) {
val context = viewGroup.context mConstraintLayout!!.visibility = View.VISIBLE
val mOrientation = viewGroup.getObjectField("mOrientation") as Int
// MIUI编译时间大于 2022-03-12 00:00:00 且为内测版
if (SystemProperties.get(context, "ro.build.date.utc")!!
.toInt() >= 1647014400 &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("DEV") &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("XM")
) {
if (mOrientation == 1) {
mConstraintLayout!!.visibility = View.VISIBLE
} else {
mConstraintLayout!!.visibility = View.GONE
}
} else { } else {
if (mOrientation == 1) { mConstraintLayout!!.visibility = View.GONE
mWeatherView!!.visibility = View.VISIBLE }
} else { } else {
mWeatherView!!.visibility = View.GONE if (mOrientation == 1) {
} mWeatherView!!.visibility = View.VISIBLE
} else {
mWeatherView!!.visibility = View.GONE
} }
} }
} }
} }
} }

View File

@@ -1,22 +1,17 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.XSPUtils import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object CustomMobileTypeText : HookRegister() { object CustomMobileTypeText : HookRegister() {
override fun init() = hasEnable("custom_mobile_type_text_switch") {
override fun init() { findMethod("com.android.systemui.statusbar.policy.MobileSignalController") {
hasEnable("custom_mobile_type_text_switch") { name == "getMobileTypeName" && parameterTypes[0] == Int::class.java
"com.android.systemui.statusbar.policy.MobileSignalController".hookAfterMethod( }.hookAfter {
getDefaultClassLoader(), it.result = XSPUtils.getString("custom_mobile_type_text", "5G")
"getMobileTypeName",
Int::class.java
) {
it.result = XSPUtils.getString("custom_mobile_type_text","5G")
}
} }
} }
} }

View File

@@ -2,17 +2,21 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.content.Context import android.content.Context
import android.net.TrafficStats import android.net.TrafficStats
import android.util.AttributeSet
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity import android.view.Gravity
import android.widget.TextView import android.widget.TextView
import com.github.kyuubiran.ezxhelper.init.InitFields import com.github.kyuubiran.ezxhelper.init.InitFields
import com.github.kyuubiran.ezxhelper.utils.findConstructor
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.R import com.lt2333.simplicitytools.R
import com.lt2333.simplicitytools.util.* import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import java.text.DecimalFormat import java.text.DecimalFormat
object DoubleLineNetworkSpeed: HookRegister() { object DoubleLineNetworkSpeed : HookRegister() {
private var mLastTotalUp: Long = 0 private var mLastTotalUp: Long = 0
private var mLastTotalDown: Long = 0 private var mLastTotalDown: Long = 0
@@ -26,7 +30,7 @@ object DoubleLineNetworkSpeed: HookRegister() {
private val getDualSize = XSPUtils.getInt("status_bar_network_speed_dual_row_size", 0) private val getDualSize = XSPUtils.getInt("status_bar_network_speed_dual_row_size", 0)
private val getDualAlign = XSPUtils.getInt("status_bar_network_speed_dual_row_gravity", 0) private val getDualAlign = XSPUtils.getInt("status_bar_network_speed_dual_row_gravity", 0)
override fun init() { override fun init() = hasEnable("status_bar_dual_row_network_speed") {
val none = InitFields.moduleRes.getString(R.string.none) val none = InitFields.moduleRes.getString(R.string.none)
@@ -37,43 +41,47 @@ object DoubleLineNetworkSpeed: HookRegister() {
?.lastOrNull().toString() ?.lastOrNull().toString()
} }
hasEnable("status_bar_dual_row_network_speed") { findConstructor("com.android.systemui.statusbar.views.NetworkSpeedView") {
"com.android.systemui.statusbar.views.NetworkSpeedView".findClass(getDefaultClassLoader()) parameterCount == 2
.hookAfterConstructor(Context::class.java, AttributeSet::class.java) { }.hookAfter {
val mView = it.thisObject as TextView val mView = it.thisObject as TextView
mView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 7f) mView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 7f)
if (getDualSize != 0) { if (getDualSize != 0) {
mView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, getDualSize.toFloat()) mView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, getDualSize.toFloat())
} }
mView.isSingleLine = false mView.isSingleLine = false
mView.setLineSpacing(0F, 0.8F) mView.setLineSpacing(0F, 0.8F)
if (getDualAlign == 0) { if (getDualAlign == 0) {
mView.gravity = Gravity.LEFT or Gravity.CENTER_VERTICAL mView.gravity = Gravity.LEFT or Gravity.CENTER_VERTICAL
} else { } else {
mView.gravity = Gravity.RIGHT or Gravity.CENTER_VERTICAL mView.gravity = Gravity.RIGHT or Gravity.CENTER_VERTICAL
} }
} }
"com.android.systemui.statusbar.policy.NetworkSpeedController".hookBeforeMethod( findMethod("com.android.systemui.statusbar.policy.NetworkSpeedController") {
getDefaultClassLoader(), name == "formatSpeed" && parameterCount == 2
"formatSpeed", }.hookBefore {
Context::class.java, if (getDualAlign == 0) {
Long::class.java it.result =
) { "$upIcon ${getTotalUpSpeed(it.args[0] as Context)}\n${downIcon} ${
if (getDualAlign == 0) { getTotalDownloadSpeed(
it.result = it.args[0] as Context
"$upIcon ${getTotalUpSpeed(it.args[0]as Context)}\n${downIcon} ${getTotalDownloadSpeed(it.args[0]as Context)}" )
} else { }"
it.result = } else {
"${getTotalUpSpeed(it.args[0]as Context)} ${upIcon}\n${getTotalDownloadSpeed(it.args[0]as Context)} $downIcon" it.result =
} "${getTotalUpSpeed(it.args[0] as Context)} ${upIcon}\n${
getTotalDownloadSpeed(
it.args[0] as Context
)
} $downIcon"
} }
} }
} }
//获取总的上行速度 //获取总的上行速度
private fun getTotalUpSpeed(context: Context): String { private fun getTotalUpSpeed(context: Context): String {
var totalUpSpeed = 0F var totalUpSpeed: Float
val currentTotalTxBytes = TrafficStats.getTotalTxBytes() val currentTotalTxBytes = TrafficStats.getTotalTxBytes()
val nowTimeStampTotalUp = System.currentTimeMillis() val nowTimeStampTotalUp = System.currentTimeMillis()
@@ -81,16 +89,28 @@ object DoubleLineNetworkSpeed: HookRegister() {
//计算上传速度 //计算上传速度
val bytes = val bytes =
(currentTotalTxBytes - mLastTotalUp) * 1000 / (nowTimeStampTotalUp - lastTimeStampTotalUp).toFloat() (currentTotalTxBytes - mLastTotalUp) * 1000 / (nowTimeStampTotalUp - lastTimeStampTotalUp).toFloat()
var unit = "" var unit: String
if (bytes >= 1048576) { if (bytes >= 1048576) {
totalUpSpeed = totalUpSpeed =
DecimalFormat("0.0").format(bytes / 1048576).toFloat() DecimalFormat("0.0").format(bytes / 1048576).toFloat()
unit = context.resources.getString(context.resources.getIdentifier("megabyte_per_second","string",context.packageName)) unit = context.resources.getString(
context.resources.getIdentifier(
"megabyte_per_second",
"string",
context.packageName
)
)
} else { } else {
totalUpSpeed = totalUpSpeed =
DecimalFormat("0.0").format(bytes / 1024).toFloat() DecimalFormat("0.0").format(bytes / 1024).toFloat()
unit = context.resources.getString(context.resources.getIdentifier("kilobyte_per_second","string",context.packageName)) unit = context.resources.getString(
context.resources.getIdentifier(
"kilobyte_per_second",
"string",
context.packageName
)
)
} }
//保存当前的流量总和和上次的时间戳 //保存当前的流量总和和上次的时间戳
@@ -106,7 +126,7 @@ object DoubleLineNetworkSpeed: HookRegister() {
//获取总的下行速度 //获取总的下行速度
private fun getTotalDownloadSpeed(context: Context): String { private fun getTotalDownloadSpeed(context: Context): String {
var totalDownSpeed = 0F var totalDownSpeed: Float
val currentTotalRxBytes = TrafficStats.getTotalRxBytes() val currentTotalRxBytes = TrafficStats.getTotalRxBytes()
val nowTimeStampTotalDown = System.currentTimeMillis() val nowTimeStampTotalDown = System.currentTimeMillis()
@@ -114,16 +134,28 @@ object DoubleLineNetworkSpeed: HookRegister() {
val bytes = val bytes =
(currentTotalRxBytes - mLastTotalDown) * 1000 / (nowTimeStampTotalDown - lastTimeStampTotalDown).toFloat() (currentTotalRxBytes - mLastTotalDown) * 1000 / (nowTimeStampTotalDown - lastTimeStampTotalDown).toFloat()
var unit = "" var unit: String
if (bytes >= 1048576) { if (bytes >= 1048576) {
totalDownSpeed = totalDownSpeed =
DecimalFormat("0.0").format(bytes / 1048576).toFloat() DecimalFormat("0.0").format(bytes / 1048576).toFloat()
unit = context.resources.getString(context.resources.getIdentifier("megabyte_per_second","string",context.packageName)) unit = context.resources.getString(
context.resources.getIdentifier(
"megabyte_per_second",
"string",
context.packageName
)
)
} else { } else {
totalDownSpeed = totalDownSpeed =
DecimalFormat("0.0").format(bytes / 1024).toFloat() DecimalFormat("0.0").format(bytes / 1024).toFloat()
unit = context.resources.getString(context.resources.getIdentifier("kilobyte_per_second","string",context.packageName)) unit = context.resources.getString(
context.resources.getIdentifier(
"kilobyte_per_second",
"string",
context.packageName
)
)
} }
//保存当前的流量总和和上次的时间戳 //保存当前的流量总和和上次的时间戳
mLastTotalDown = currentTotalRxBytes mLastTotalDown = currentTotalRxBytes

View File

@@ -4,42 +4,46 @@ import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import com.lt2333.simplicitytools.util.getObjectField import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object HideBatteryIcon : HookRegister() { object HideBatteryIcon : HookRegister() {
override fun init() { override fun init() {
"com.android.systemui.statusbar.views.MiuiBatteryMeterView".hookAfterMethod(getDefaultClassLoader(), "updateResources") { findMethod("com.android.systemui.statusbar.views.MiuiBatteryMeterView") {
name == "updateResources"
}.hookAfter {
//隐藏电池图标 //隐藏电池图标
hasEnable("hide_battery_icon") { hasEnable("hide_battery_icon") {
(it.thisObject.getObjectField("mBatteryIconView") as ImageView).visibility = View.GONE (it.thisObject.getObject("mBatteryIconView") as ImageView).visibility = View.GONE
if (it.thisObject.getObjectField("mBatteryStyle") == 1) { if (it.thisObject.getObject("mBatteryStyle") == 1) {
(it.thisObject.getObjectField("mBatteryDigitalView") as FrameLayout).visibility = View.GONE (it.thisObject.getObject("mBatteryDigitalView") as FrameLayout).visibility =
View.GONE
} }
} }
//隐藏电池内的百分比 //隐藏电池内的百分比
hasEnable("hide_battery_percentage_icon") { hasEnable("hide_battery_percentage_icon") {
(it.thisObject.getObjectField("mBatteryPercentMarkView") as TextView).textSize = 0F (it.thisObject.getObject("mBatteryPercentMarkView") as TextView).textSize = 0F
} }
//隐藏电池百分号 //隐藏电池百分号
hasEnable("hide_battery_percentage_icon") { hasEnable("hide_battery_percentage_icon") {
(it.thisObject.getObjectField("mBatteryPercentMarkView") as TextView).textSize = 0F (it.thisObject.getObject("mBatteryPercentMarkView") as TextView).textSize = 0F
} }
}
"com.android.systemui.statusbar.views.MiuiBatteryMeterView".hookAfterMethod(getDefaultClassLoader(), "updateChargeAndText") { findMethod("com.android.systemui.statusbar.views.MiuiBatteryMeterView") {
//隐藏电池充电图标 name == "updateChargeAndText"
hasEnable("hide_battery_charging_icon") { }.hookAfter {
(it.thisObject.getObjectField("mBatteryChargingInView") as ImageView).visibility = View.GONE //隐藏电池充电图标
(it.thisObject.getObjectField("mBatteryChargingView") as ImageView).visibility = View.GONE hasEnable("hide_battery_charging_icon") {
} (it.thisObject.getObject("mBatteryChargingInView") as ImageView).visibility =
View.GONE
(it.thisObject.getObject("mBatteryChargingView") as ImageView).visibility =
View.GONE
} }
} }
} }
} }

View File

@@ -2,38 +2,38 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import com.lt2333.simplicitytools.util.getObjectField import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XC_MethodHook
object HideHDIcon: HookRegister() { object HideHDIcon : HookRegister() {
override fun init() { override fun init() {
val iconState = "com.android.systemui.statusbar.phone.StatusBarSignalPolicy\$MobileIconState" findMethod("com.android.systemui.statusbar.StatusBarMobileView") {
"com.android.systemui.statusbar.StatusBarMobileView".hookAfterMethod(getDefaultClassLoader(), "initViewState", iconState) { name == "initViewState" && parameterCount == 1
hasEnable("hide_big_hd_icon") { }.hookAfter {
(it.thisObject.getObjectField("mVolte") as ImageView).visibility = View.GONE hide(it)
}
hasEnable("hide_small_hd_icon") {
(it.thisObject.getObjectField("mSmallHd") as ImageView).visibility = View.GONE
}
hasEnable("hide_hd_no_service_icon") {
(it.thisObject.getObjectField("mVolteNoService") as ImageView).visibility = View.GONE
}
} }
"com.android.systemui.statusbar.StatusBarMobileView".hookAfterMethod(getDefaultClassLoader(), "updateState", iconState) { findMethod("com.android.systemui.statusbar.StatusBarMobileView") {
hasEnable("hide_big_hd_icon") { name == "updateState" && parameterCount == 1
(it.thisObject.getObjectField("mVolte") as ImageView).visibility = View.GONE }.hookAfter {
} hide(it)
hasEnable("hide_small_hd_icon") {
(it.thisObject.getObjectField("mSmallHd") as ImageView).visibility = View.GONE
}
hasEnable("hide_hd_no_service_icon") {
(it.thisObject.getObjectField("mVolteNoService") as ImageView).visibility = View.GONE
}
} }
} }
private fun hide(it: XC_MethodHook.MethodHookParam) {
hasEnable("hide_big_hd_icon") {
(it.thisObject.getObject("mVolte") as ImageView).visibility = View.GONE
}
hasEnable("hide_small_hd_icon") {
(it.thisObject.getObject("mSmallHd") as ImageView).visibility = View.GONE
}
hasEnable("hide_hd_no_service_icon") {
(it.thisObject.getObject("mVolteNoService") as ImageView).visibility =
View.GONE
}
}
} }

View File

@@ -2,28 +2,32 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import com.lt2333.simplicitytools.util.getObjectField import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XC_MethodHook
object HideMobileActivityIcon: HookRegister() { object HideMobileActivityIcon : HookRegister() {
override fun init() { override fun init() {
val iconState = "com.android.systemui.statusbar.phone.StatusBarSignalPolicy\$MobileIconState" findMethod("com.android.systemui.statusbar.StatusBarMobileView") {
"com.android.systemui.statusbar.StatusBarMobileView".hookAfterMethod(getDefaultClassLoader(), "initViewState", iconState) { name == "initViewState" && parameterCount == 1
hasEnable("hide_mobile_activity_icon") { }.hookAfter {
(it.thisObject.getObjectField("mLeftInOut") as ImageView).visibility = View.GONE hide(it)
(it.thisObject.getObjectField("mRightInOut") as ImageView).visibility = View.GONE
}
} }
"com.android.systemui.statusbar.StatusBarMobileView".hookAfterMethod(getDefaultClassLoader(), "updateState", iconState) { findMethod("com.android.systemui.statusbar.StatusBarMobileView") {
hasEnable("hide_mobile_activity_icon") { name == "updateState" && parameterCount == 1
(it.thisObject.getObjectField("mLeftInOut") as ImageView).visibility = View.GONE }.hookAfter {
(it.thisObject.getObjectField("mRightInOut") as ImageView).visibility = View.GONE hide(it)
}
} }
} }
private fun hide(it: XC_MethodHook.MethodHookParam) {
hasEnable("hide_mobile_activity_icon") {
(it.thisObject.getObject("mLeftInOut") as ImageView).visibility = View.GONE
(it.thisObject.getObject("mRightInOut") as ImageView).visibility = View.GONE
}
}
} }

View File

@@ -3,32 +3,28 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.XSPUtils import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.getObjectField
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XC_MethodHook
object HideMobileTypeIcon: HookRegister() { object HideMobileTypeIcon : HookRegister() {
private val isBigType = XSPUtils.getBoolean("big_mobile_type_icon", false) private val isBigType = XSPUtils.getBoolean("big_mobile_type_icon", false)
override fun init() { override fun init() {
val iconState = "com.android.systemui.statusbar.phone.StatusBarSignalPolicy\$MobileIconState" findMethod("com.android.systemui.statusbar.StatusBarMobileView") {
"com.android.systemui.statusbar.StatusBarMobileView".hookAfterMethod( name == "initViewState" && parameterCount == 1
getDefaultClassLoader(), }.hookAfter {
"initViewState",
iconState
) {
hideMobileTypeIcon(it) hideMobileTypeIcon(it)
} }
"com.android.systemui.statusbar.StatusBarMobileView".hookAfterMethod( findMethod("com.android.systemui.statusbar.StatusBarMobileView") {
getDefaultClassLoader(), name == "updateState" && parameterCount == 1
"updateState", }.hookAfter {
iconState
) {
hideMobileTypeIcon(it) hideMobileTypeIcon(it)
} }
} }
@@ -36,21 +32,20 @@ object HideMobileTypeIcon: HookRegister() {
private fun hideMobileTypeIcon(it: XC_MethodHook.MethodHookParam) { private fun hideMobileTypeIcon(it: XC_MethodHook.MethodHookParam) {
hasEnable("hide_mobile_type_icon") { hasEnable("hide_mobile_type_icon") {
if (isBigType) { if (isBigType) {
(it.thisObject.getObjectField("mMobileType") as TextView).visibility = (it.thisObject.getObject("mMobileType") as TextView).visibility =
View.GONE View.GONE
(it.thisObject.getObjectField("mMobileTypeImage") as ImageView).visibility = (it.thisObject.getObject("mMobileTypeImage") as ImageView).visibility =
View.GONE View.GONE
(it.thisObject.getObjectField("mMobileTypeSingle") as TextView).visibility = (it.thisObject.getObject("mMobileTypeSingle") as TextView).visibility =
View.GONE View.GONE
} else { } else {
(it.thisObject.getObjectField("mMobileType") as TextView).visibility = (it.thisObject.getObject("mMobileType") as TextView).visibility =
View.INVISIBLE View.INVISIBLE
(it.thisObject.getObjectField("mMobileTypeImage") as ImageView).visibility = (it.thisObject.getObject("mMobileTypeImage") as ImageView).visibility =
View.INVISIBLE View.INVISIBLE
(it.thisObject.getObjectField("mMobileTypeSingle") as TextView).visibility = (it.thisObject.getObject("mMobileTypeSingle") as TextView).visibility =
View.INVISIBLE View.INVISIBLE
} }
} }
} }
} }

View File

@@ -1,21 +1,20 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import android.widget.TextView import android.widget.TextView
import com.lt2333.simplicitytools.util.XSPUtils import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.lt2333.simplicitytools.util.findClass import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.hookAfterMethod import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object HideNetworkSpeedSplitter: HookRegister() { object HideNetworkSpeedSplitter : HookRegister() {
override fun init() { override fun init() {
val networkSpeedSplitterClass = "com.android.systemui.statusbar.views.NetworkSpeedSplitter".findClass(getDefaultClassLoader()) findMethod("com.android.systemui.statusbar.views.NetworkSpeedSplitter") {
networkSpeedSplitterClass.hookAfterMethod("init") { name == "init"
if (XSPUtils.getBoolean("hide_network_speed_splitter", false)) { }.hookAfter {
hasEnable("hide_network_speed_splitter") {
val textView = it.thisObject as TextView val textView = it.thisObject as TextView
textView.text = " " textView.text = " "
} }
} }
} }
} }

View File

@@ -1,13 +1,15 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object HideSimIcon: HookRegister() { object HideSimIcon : HookRegister() {
override fun init() { override fun init() {
"com.android.systemui.statusbar.phone.StatusBarSignalPolicy".hookBeforeMethod(getDefaultClassLoader(), "hasCorrectSubs", MutableList::class.java) { findMethod("com.android.systemui.statusbar.phone.StatusBarSignalPolicy") {
name == "hasCorrectSubs" && parameterTypes[0] == MutableList::class.java
}.hookBefore {
val list = it.args[0] as MutableList<*> val list = it.args[0] as MutableList<*>
val size = list.size val size = list.size
hasEnable("hide_sim_two_icon", extraCondition = { size == 2 }) { hasEnable("hide_sim_two_icon", extraCondition = { size == 2 }) {
@@ -18,5 +20,4 @@ object HideSimIcon: HookRegister() {
} }
} }
} }
} }

View File

@@ -1,26 +1,24 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XC_MethodHook
object HideStatusBarIcon: HookRegister() { object HideStatusBarIcon : HookRegister() {
override fun init() { override fun init() {
"com.android.systemui.statusbar.phone.StatusBarIconControllerImpl".hookBeforeMethod( findMethod("com.android.systemui.statusbar.phone.StatusBarIconControllerImpl") {
getDefaultClassLoader(), name == "setIconVisibility" && parameterCount == 2
"setIconVisibility", }.hookBefore {
String::class.java, hideIcon(it)
Boolean::class.java }
) { hideIcon(it) }
"com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl".hookBeforeMethod( findMethod("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl") {
getDefaultClassLoader(), name == "setIconVisibility" && parameterCount == 2
"setIconVisibility", }.hookBefore {
String::class.java, hideIcon(it)
Boolean::class.java }
) { hideIcon(it) }
} }
private fun hideIcon(it: XC_MethodHook.MethodHookParam) { private fun hideIcon(it: XC_MethodHook.MethodHookParam) {

View File

@@ -1,17 +1,18 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.isNonNull
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object HideStatusBarNetworkSpeedSecond: HookRegister() { object HideStatusBarNetworkSpeedSecond : HookRegister() {
override fun init() { override fun init() {
"com.android.systemui.statusbar.views.NetworkSpeedView".hookBeforeMethod(getDefaultClassLoader(), "setNetworkSpeed", String::class.java) { findMethod("com.android.systemui.statusbar.views.NetworkSpeedView") {
name == "setNetworkSpeed" && parameterTypes[0] == String::class.java
}.hookBefore {
hasEnable("hide_status_bar_network_speed_second") { hasEnable("hide_status_bar_network_speed_second") {
it.args[0].isNonNull { s -> if (it.args[0] != null) {
it.args[0] = (s as String) (it.args[0] as String)
.replace("/", "") .replace("/", "")
.replace("s", "") .replace("s", "")
.replace("'", "") .replace("'", "")
@@ -20,5 +21,4 @@ object HideStatusBarNetworkSpeedSecond: HookRegister() {
} }
} }
} }
} }

View File

@@ -3,35 +3,39 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import com.lt2333.simplicitytools.util.getObjectField import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XC_MethodHook
object HideWifiActivityIcon: HookRegister() { object HideWifiActivityIcon : HookRegister() {
override fun init() { override fun init() {
val iconState = "com.android.systemui.statusbar.phone.StatusBarSignalPolicy\$WifiIconState" findMethod("com.android.systemui.statusbar.StatusBarWifiView") {
"com.android.systemui.statusbar.StatusBarWifiView".hookAfterMethod(getDefaultClassLoader(), "initViewState", iconState) { name == "initViewState" && parameterCount == 1
//隐藏WIFI箭头 }.hookAfter {
hasEnable("hide_wifi_activity_icon") { hide(it)
(it.thisObject.getObjectField("mWifiActivityView") as ImageView).visibility = View.INVISIBLE
}
//隐藏WIFI标准图标
hasEnable("hide_wifi_standard_icon") {
(it.thisObject.getObjectField("mWifiStandardView") as TextView).visibility = View.INVISIBLE
}
} }
"com.android.systemui.statusbar.StatusBarWifiView".hookAfterMethod(getDefaultClassLoader(), "updateState", iconState) { findMethod("com.android.systemui.statusbar.StatusBarWifiView") {
//隐藏WIFI箭头 name == "updateState" && parameterCount == 1
hasEnable("hide_wifi_activity_icon") { }.hookAfter {
(it.thisObject.getObjectField("mWifiActivityView") as ImageView).visibility = View.INVISIBLE hide(it)
} }
//隐藏WIFI标准图标 }
hasEnable("hide_wifi_standard_icon") {
(it.thisObject.getObjectField("mWifiStandardView") as TextView).visibility = View.INVISIBLE private fun hide(it: XC_MethodHook.MethodHookParam) {
} //隐藏WIFI箭头
hasEnable("hide_wifi_activity_icon") {
(it.thisObject.getObject("mWifiActivityView") as ImageView).visibility =
View.INVISIBLE
}
//隐藏WIFI标准图标
hasEnable("hide_wifi_standard_icon") {
(it.thisObject.getObject("mWifiStandardView") as TextView).visibility =
View.INVISIBLE
} }
} }

View File

@@ -4,11 +4,11 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Handler import android.os.Handler
import android.provider.Settings import android.provider.Settings
import android.util.AttributeSet
import android.util.Log import android.util.Log
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import com.lt2333.simplicitytools.util.* import com.github.kyuubiran.ezxhelper.utils.*
import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XC_MethodHook
import java.lang.reflect.Method import java.lang.reflect.Method
@@ -19,67 +19,48 @@ object LockScreenClockDisplaySeconds : HookRegister() {
private var nowTime: Date = Calendar.getInstance().time private var nowTime: Date = Calendar.getInstance().time
override fun init() { override fun init() = hasEnable("lock_screen_clock_display_seconds") {
hasEnable("lock_screen_clock_display_seconds") { findConstructor("com.miui.clock.MiuiBaseClock") {
"com.miui.clock.MiuiBaseClock".findClass(getDefaultClassLoader()) paramCount == 2
.hookAfterConstructor( }.hookAfter {
Context::class.java, try {
AttributeSet::class.java val viewGroup = it.thisObject as LinearLayout
) { val d: Method = viewGroup.javaClass.getDeclaredMethod("updateTime")
try { val r = Runnable {
val viewGroup = it.thisObject as LinearLayout d.isAccessible = true
d.invoke(viewGroup)
}
val d: Method = viewGroup.javaClass.getDeclaredMethod("updateTime") class T : TimerTask() {
val r = Runnable { override fun run() {
d.isAccessible = true Handler(viewGroup.context.mainLooper).post(r)
d.invoke(viewGroup)
}
class T : TimerTask() {
override fun run() {
Handler(viewGroup.context.mainLooper).post(r)
}
}
Timer().scheduleAtFixedRate(
T(),
1000 - System.currentTimeMillis() % 1000,
1000
)
} catch (e: java.lang.Exception) {
} }
} }
"com.miui.clock.MiuiLeftTopClock".hookAfterMethod( Timer().scheduleAtFixedRate(T(), 1000 - System.currentTimeMillis() % 1000, 1000)
getDefaultClassLoader(), } catch (e: Exception) {
"updateTime"
) {
updateTime(it, false)
}
"com.miui.clock.MiuiLeftTopLargeClock".hookAfterMethod(
getDefaultClassLoader(),
"updateTime"
) {
updateTime(it, false)
}
"com.miui.clock.MiuiCenterHorizontalClock".hookAfterMethod(
getDefaultClassLoader(),
"updateTime"
) {
updateTime(it, false)
}
"com.miui.clock.MiuiVerticalClock".hookAfterMethod(
getDefaultClassLoader(),
"updateTime"
) {
updateTime(it, true)
} }
} }
findMethod("com.miui.clock.MiuiLeftTopClock") {
name == "updateTime"
}.hookAfter { updateTime(it, false) }
findMethod("com.miui.clock.MiuiCenterHorizontalClock") {
name == "updateTime"
}.hookAfter { updateTime(it, false) }
findMethod("com.miui.clock.MiuiLeftTopLargeClock") {
name == "updateTime"
}.hookAfter { updateTime(it, false) }
findMethod("com.miui.clock.MiuiVerticalClock") {
name == "updateTime"
}.hookAfter { updateTime(it, true) }
} }
private fun updateTime(it: XC_MethodHook.MethodHookParam, isVertical: Boolean) { private fun updateTime(it: XC_MethodHook.MethodHookParam, isVertical: Boolean) {
val textV = it.thisObject.getObjectField("mTimeText") as TextView val textV = it.thisObject.getObject("mTimeText") as TextView
val c: Context = textV.context val c: Context = textV.context
Log.d( Log.d(

View File

@@ -1,15 +1,14 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.widget.TextView import android.widget.TextView
import com.github.kyuubiran.ezxhelper.init.InitFields import com.github.kyuubiran.ezxhelper.init.InitFields
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.R import com.lt2333.simplicitytools.R
import com.lt2333.simplicitytools.util.findClass
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XposedHelpers
import java.io.BufferedReader import java.io.BufferedReader
import java.io.FileReader import java.io.FileReader
import java.lang.reflect.Method import java.lang.reflect.Method
@@ -17,26 +16,19 @@ import kotlin.math.roundToInt
object LockScreenCurrent : HookRegister() { object LockScreenCurrent : HookRegister() {
override fun init() { override fun init() = hasEnable("lock_screen_charging_current") {
hasEnable("lock_screen_charging_current") { findMethod("com.android.keyguard.charge.ChargeUtils") {
"com.android.keyguard.charge.ChargeUtils".findClass(getDefaultClassLoader()) name == "getChargingHintText" && parameterCount == 3
.hookAfterMethod( }.hookAfter {
"getChargingHintText", it.result = getCurrent() + "\n" + it.result
Context::class.java, }
Boolean::class.java,
Int::class.java findMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView") {
) { name == "onFinishInflate"
it.result = getCurrent() + "\n" + it.result }.hookAfter {
} (it.thisObject.getObject(
"com.android.systemui.statusbar.phone.KeyguardBottomAreaView".findClass(getDefaultClassLoader()) "mIndicationText"
.hookAfterMethod( ) as TextView).isSingleLine = false
"onFinishInflate"
) {
(XposedHelpers.getObjectField(
it.thisObject,
"mIndicationText"
) as TextView).isSingleLine = false
}
} }
} }

View File

@@ -1,72 +1,67 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import android.annotation.SuppressLint
import android.app.KeyguardManager import android.app.KeyguardManager
import android.content.Context import android.content.Context
import android.os.SystemClock import android.os.SystemClock
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.View.OnTouchListener import android.view.View.OnTouchListener
import com.lt2333.simplicitytools.util.findClass import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.XposedHelpers
object LockScreenDoubleTapToSleep: HookRegister() { object LockScreenDoubleTapToSleep : HookRegister() {
override fun init() = hasEnable("lock_screen_double_tap_to_sleep") {
@SuppressLint("ClickableViewAccessibility") findMethod("com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer") {
override fun init() { name == "onFinishInflate"
hasEnable("lock_screen_double_tap_to_sleep") { }.hookBefore {
"com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer".findClass( val view = it.thisObject as View
getDefaultClassLoader() XposedHelpers.setAdditionalInstanceField(view, "currentTouchTime", 0L)
).hookBeforeMethod("onFinishInflate") { XposedHelpers.setAdditionalInstanceField(view, "currentTouchX", 0f)
val view = it.thisObject as View XposedHelpers.setAdditionalInstanceField(view, "currentTouchY", 0f)
XposedHelpers.setAdditionalInstanceField(view, "currentTouchTime", 0L) view.setOnTouchListener(OnTouchListener { v, event ->
XposedHelpers.setAdditionalInstanceField(view, "currentTouchX", 0f) if (event.action != MotionEvent.ACTION_DOWN) return@OnTouchListener false
XposedHelpers.setAdditionalInstanceField(view, "currentTouchY", 0f) var currentTouchTime =
view.setOnTouchListener(OnTouchListener { v, event -> XposedHelpers.getAdditionalInstanceField(view, "currentTouchTime") as Long
if (event.action != MotionEvent.ACTION_DOWN) return@OnTouchListener false var currentTouchX =
var currentTouchTime = XposedHelpers.getAdditionalInstanceField(view, "currentTouchX") as Float
XposedHelpers.getAdditionalInstanceField(view, "currentTouchTime") as Long var currentTouchY =
var currentTouchX = XposedHelpers.getAdditionalInstanceField(view, "currentTouchY") as Float
XposedHelpers.getAdditionalInstanceField(view, "currentTouchX") as Float val lastTouchTime = currentTouchTime
var currentTouchY = val lastTouchX = currentTouchX
XposedHelpers.getAdditionalInstanceField(view, "currentTouchY") as Float val lastTouchY = currentTouchY
val lastTouchTime = currentTouchTime currentTouchTime = System.currentTimeMillis()
val lastTouchX = currentTouchX currentTouchX = event.x
val lastTouchY = currentTouchY currentTouchY = event.y
currentTouchTime = System.currentTimeMillis() if (currentTouchTime - lastTouchTime < 250L && Math.abs(currentTouchX - lastTouchX) < 100f && Math.abs(
currentTouchX = event.x currentTouchY - lastTouchY
currentTouchY = event.y ) < 100f
if (currentTouchTime - lastTouchTime < 250L && Math.abs(currentTouchX - lastTouchX) < 100f && Math.abs( ) {
currentTouchY - lastTouchY val keyguardMgr =
) < 100f v.context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
) { if (keyguardMgr.isKeyguardLocked) {
val keyguardMgr = XposedHelpers.callMethod(
v.context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager v.context.getSystemService(Context.POWER_SERVICE),
if (keyguardMgr.isKeyguardLocked) { "goToSleep",
XposedHelpers.callMethod( SystemClock.uptimeMillis()
v.context.getSystemService(Context.POWER_SERVICE), )
"goToSleep",
SystemClock.uptimeMillis()
)
}
currentTouchTime = 0L
currentTouchX = 0f
currentTouchY = 0f
} }
XposedHelpers.setAdditionalInstanceField( currentTouchTime = 0L
view, currentTouchX = 0f
"currentTouchTime", currentTouchY = 0f
currentTouchTime }
) XposedHelpers.setAdditionalInstanceField(
XposedHelpers.setAdditionalInstanceField(view, "currentTouchX", currentTouchX) view,
XposedHelpers.setAdditionalInstanceField(view, "currentTouchY", currentTouchY) "currentTouchTime",
false currentTouchTime
}) )
} XposedHelpers.setAdditionalInstanceField(view, "currentTouchX", currentTouchX)
XposedHelpers.setAdditionalInstanceField(view, "currentTouchY", currentTouchY)
v.performClick()
false
})
} }
} }
} }

View File

@@ -1,25 +1,29 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import com.lt2333.simplicitytools.util.* import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookReplace
import com.github.kyuubiran.ezxhelper.utils.invokeMethod
import com.github.kyuubiran.ezxhelper.utils.putObject
import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object MaximumNumberOfNotificationIcons: HookRegister() { object MaximumNumberOfNotificationIcons : HookRegister() {
override fun init() { override fun init() {
val icons = XSPUtils.getInt("maximum_number_of_notification_icons",3) val icons = XSPUtils.getInt("maximum_number_of_notification_icons", 3)
val dots = XSPUtils.getInt("maximum_number_of_notification_dots",3) val dots = XSPUtils.getInt("maximum_number_of_notification_dots", 3)
"com.android.systemui.statusbar.phone.NotificationIconContainer".replaceMethod(getDefaultClassLoader(), "miuiShowNotificationIcons", Boolean::class.java) { findMethod("com.android.systemui.statusbar.phone.NotificationIconContainer") {
if (it.args[0] as Boolean) { name == "miuiShowNotificationIcons" && parameterCount == 1
it.thisObject.setIntField("MAX_DOTS", dots) }.hookReplace {
it.thisObject.setIntField("MAX_STATIC_ICONS", icons) if (it.args[0] as Boolean) {
it.thisObject.setIntField("MAX_VISIBLE_ICONS_ON_LOCK", icons) it.thisObject.putObject("MAX_DOTS", dots)
} else { it.thisObject.putObject("MAX_STATIC_ICONS", icons)
it.thisObject.setIntField("MAX_DOTS", 0) it.thisObject.putObject("MAX_VISIBLE_ICONS_ON_LOCK", icons)
it.thisObject.setIntField("MAX_STATIC_ICONS", 0) } else {
it.thisObject.setIntField("MAX_VISIBLE_ICONS_ON_LOCK", 0) it.thisObject.putObject("MAX_DOTS", 0)
} it.thisObject.putObject("MAX_STATIC_ICONS", 0)
it.thisObject.callMethod("updateState") it.thisObject.putObject("MAX_VISIBLE_ICONS_ON_LOCK", 0)
} }
it.thisObject.invokeMethod("updateState")
}
} }
} }

View File

@@ -9,216 +9,210 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import cn.fkj233.ui.activity.dp2px import cn.fkj233.ui.activity.dp2px
import com.github.kyuubiran.ezxhelper.utils.loadClass import com.github.kyuubiran.ezxhelper.utils.*
import com.lt2333.simplicitytools.util.* import com.lt2333.simplicitytools.util.*
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import com.lt2333.simplicitytools.view.WeatherView import com.lt2333.simplicitytools.view.WeatherView
object NotificationWeather: HookRegister() { object NotificationWeather : HookRegister() {
override fun init() { override fun init() = hasEnable("notification_weather") {
hasEnable("notification_weather") { var mWeatherView: TextView? = null
var mWeatherView: TextView? = null var mConstraintLayout: ConstraintLayout? = null
var mConstraintLayout: ConstraintLayout? = null val isDisplayCity = XSPUtils.getBoolean("notification_weather_city", false)
val isDisplayCity = XSPUtils.getBoolean("notification_weather_city", false) findMethod("com.android.systemui.qs.MiuiNotificationHeaderView") {
"com.android.systemui.qs.MiuiNotificationHeaderView".hookAfterMethod( name == "onFinishInflate"
getDefaultClassLoader(), }.hookAfter {
"onFinishInflate" val viewGroup = it.thisObject as ViewGroup
val context = viewGroup.context
// MIUI编译时间大于 2022-03-12 00:00:00 且为内测版
if (SystemProperties.get(context, "ro.build.date.utc")!!
.toInt() >= 1647014400 &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("DEV") &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("XM")
) { ) {
val viewGroup = it.thisObject as ViewGroup //获取原组件
val context = viewGroup.context val big_time_ID =
context.resources.getIdentifier("big_time", "id", context.packageName)
val big_time: TextView = viewGroup.findViewById(big_time_ID)
// MIUI编译时间大于 2022-03-12 00:00:00 且为内测版 val date_time_ID =
if (SystemProperties.get(context, "ro.build.date.utc")!! context.resources.getIdentifier("date_time", "id", context.packageName)
.toInt() >= 1647014400 && val date_time: TextView = viewGroup.findViewById(date_time_ID)
!SystemProperties.get( //创建新布局
context, val mConstraintLayoutLp = LinearLayout.LayoutParams(
"ro.build.version.incremental" LinearLayout.LayoutParams.MATCH_PARENT,
)!!.endsWith("DEV") && LinearLayout.LayoutParams.WRAP_CONTENT
).also {
!SystemProperties.get( it.topMargin = context.resources.getDimensionPixelSize(
context, context.resources.getIdentifier(
"ro.build.version.incremental" "qs_control_header_tiles_margin_top",
)!!.endsWith("XM") "dimen",
) { context.packageName
//获取原组件
val big_time_ID =
context.resources.getIdentifier("big_time", "id", context.packageName)
val big_time: TextView = viewGroup.findViewById(big_time_ID)
val date_time_ID =
context.resources.getIdentifier("date_time", "id", context.packageName)
val date_time: TextView = viewGroup.findViewById(date_time_ID)
//创建新布局
val mConstraintLayoutLp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).also {
it.topMargin = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"qs_control_header_tiles_margin_top",
"dimen",
context.packageName
)
) )
}
mConstraintLayout =
ConstraintLayout(context).also { it.layoutParams = mConstraintLayoutLp }
(big_time.parent as ViewGroup).addView(mConstraintLayout, 0)
//从原布局中删除组件
(big_time.parent as ViewGroup).removeView(big_time)
(date_time.parent as ViewGroup).removeView(date_time)
//添加组件至新布局
mConstraintLayout!!.addView(big_time)
mConstraintLayout!!.addView(date_time)
//组件属性
val date_time_LP = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
).also {
it.startToEnd = big_time_ID
it.bottomToBottom = 0
it.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"notification_panel_time_date_space",
"dimen",
context.packageName
)
)
it.bottomMargin = dp2px(context, 5f)
}
date_time.layoutParams = date_time_LP
//创建天气组件
mWeatherView = WeatherView(context, isDisplayCity).apply {
setTextAppearance(
context.resources.getIdentifier(
"TextAppearance.QSControl.Date",
"style",
context.packageName
)
)
}
mConstraintLayout!!.addView(mWeatherView)
val mWeatherView_LP = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
).also {
it.startToEnd = big_time_ID
it.bottomToTop = date_time_ID
it.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"notification_panel_time_date_space",
"dimen",
context.packageName
)
)
}
(mWeatherView as WeatherView).layoutParams = mWeatherView_LP
} else {
val layoutParam =
loadClass("androidx.constraintlayout.widget.ConstraintLayout\$LayoutParams").getConstructor(
Int::class.java,
Int::class.java
).newInstance(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
) as ViewGroup.MarginLayoutParams
layoutParam.setObjectField(
"bottomToTop",
context.resources.getIdentifier("date_time", "id", context.packageName)
) )
layoutParam.setObjectField( }
"startToEnd",
context.resources.getIdentifier("big_time", "id", context.packageName) mConstraintLayout =
) ConstraintLayout(context).also { it.layoutParams = mConstraintLayoutLp }
layoutParam.marginStart = context.resources.getDimensionPixelSize(
(big_time.parent as ViewGroup).addView(mConstraintLayout, 0)
//从原布局中删除组件
(big_time.parent as ViewGroup).removeView(big_time)
(date_time.parent as ViewGroup).removeView(date_time)
//添加组件至新布局
mConstraintLayout!!.addView(big_time)
mConstraintLayout!!.addView(date_time)
//组件属性
val date_time_LP = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
).also {
it.startToEnd = big_time_ID
it.bottomToBottom = 0
it.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier( context.resources.getIdentifier(
"notification_panel_time_date_space", "notification_panel_time_date_space",
"dimen", "dimen",
context.packageName context.packageName
) )
) )
mWeatherView = WeatherView(context, isDisplayCity).apply { it.bottomMargin = dp2px(context, 5f)
setTextAppearance( }
context.resources.getIdentifier( date_time.layoutParams = date_time_LP
"TextAppearance.QSControl.Date",
"style",
context.packageName //创建天气组件
) mWeatherView = WeatherView(context, isDisplayCity).apply {
setTextAppearance(
context.resources.getIdentifier(
"TextAppearance.QSControl.Date",
"style",
context.packageName
) )
layoutParams = layoutParam )
}
viewGroup.addView(mWeatherView) }
mConstraintLayout!!.addView(mWeatherView)
val mWeatherView_LP = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
).also {
it.startToEnd = big_time_ID
it.bottomToTop = date_time_ID
it.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"notification_panel_time_date_space",
"dimen",
context.packageName
)
)
} }
(mWeatherView as WeatherView).setOnClickListener { (mWeatherView as WeatherView).layoutParams = mWeatherView_LP
try {
val intent = Intent().apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
component = ComponentName(
"com.miui.weather2",
"com.miui.weather2.ActivityWeatherMain"
)
}
context.startActivity(intent)
} catch (e: Exception) {
Toast.makeText(context, "启动失败", Toast.LENGTH_LONG).show()
}
}
} else {
val layoutParam =
loadClass("androidx.constraintlayout.widget.ConstraintLayout\$LayoutParams").getConstructor(
Int::class.java,
Int::class.java
).newInstance(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
) as ViewGroup.MarginLayoutParams
layoutParam.putObject(
"bottomToTop",
context.resources.getIdentifier("date_time", "id", context.packageName)
)
layoutParam.putObject(
"startToEnd",
context.resources.getIdentifier("big_time", "id", context.packageName)
)
layoutParam.marginStart = context.resources.getDimensionPixelSize(
context.resources.getIdentifier(
"notification_panel_time_date_space",
"dimen",
context.packageName
)
)
mWeatherView = WeatherView(context, isDisplayCity).apply {
setTextAppearance(
context.resources.getIdentifier(
"TextAppearance.QSControl.Date",
"style",
context.packageName
)
)
layoutParams = layoutParam
}
viewGroup.addView(mWeatherView)
} }
//解决横屏重叠
"com.android.systemui.qs.MiuiNotificationHeaderView".hookAfterMethod( (mWeatherView as WeatherView).setOnClickListener {
getDefaultClassLoader(), try {
"updateLayout" val intent = Intent().apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
component = ComponentName(
"com.miui.weather2",
"com.miui.weather2.ActivityWeatherMain"
)
}
context.startActivity(intent)
} catch (e: Exception) {
Toast.makeText(context, "启动失败", Toast.LENGTH_LONG).show()
}
}
}
findMethod("com.android.systemui.qs.MiuiNotificationHeaderView") {
name == "updateLayout"
}.hookAfter {
val viewGroup = it.thisObject as ViewGroup
val context = viewGroup.context
val mOrientation = viewGroup.getObject("mOrientation") as Int
// MIUI编译时间大于 2022-03-12 00:00:00 且为内测版
if (SystemProperties.get(context, "ro.build.date.utc")!!
.toInt() >= 1647014400 &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("DEV") &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("XM")
) { ) {
val viewGroup = it.thisObject as ViewGroup if (mOrientation == 1) {
val context = viewGroup.context mConstraintLayout!!.visibility = View.VISIBLE
val mOrientation = viewGroup.getObjectField("mOrientation") as Int
// MIUI编译时间大于 2022-03-12 00:00:00 且为内测版
if (SystemProperties.get(context, "ro.build.date.utc")!!
.toInt() >= 1647014400 &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("DEV") &&
!SystemProperties.get(
context,
"ro.build.version.incremental"
)!!.endsWith("XM")
) {
if (mOrientation == 1) {
mConstraintLayout!!.visibility = View.VISIBLE
} else {
mConstraintLayout!!.visibility = View.GONE
}
} else { } else {
if (mOrientation == 1) { mConstraintLayout!!.visibility = View.GONE
mWeatherView!!.visibility = View.VISIBLE }
} else { } else {
mWeatherView!!.visibility = View.GONE if (mOrientation == 1) {
} mWeatherView!!.visibility = View.VISIBLE
} else {
mWeatherView!!.visibility = View.GONE
} }
} }
} }
} }
} }

View File

@@ -6,96 +6,91 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import com.github.kyuubiran.ezxhelper.utils.loadClass import com.github.kyuubiran.ezxhelper.utils.*
import com.lt2333.simplicitytools.util.* import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import com.lt2333.simplicitytools.view.WeatherView import com.lt2333.simplicitytools.view.WeatherView
object OldNotificationWeather: HookRegister() { object OldNotificationWeather : HookRegister() {
override fun init() = hasEnable("notification_weather") {
var mWeatherView: TextView? = null
val isDisplayCity = XSPUtils.getBoolean("notification_weather_city", false)
findMethod("com.android.systemui.qs.MiuiQSHeaderView") {
name == "onFinishInflate"
}.hookAfter {
val viewGroup = it.thisObject as ViewGroup
val context = viewGroup.context
val layoutParam =
loadClass("androidx.constraintlayout.widget.ConstraintLayout\$LayoutParams")
.getConstructor(Int::class.java, Int::class.java)
.newInstance(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
) as ViewGroup.MarginLayoutParams
override fun init() { layoutParam.putObject(
hasEnable("notification_weather") { "endToStart",
var mWeatherView: TextView? = null context.resources.getIdentifier(
val isDisplayCity = XSPUtils.getBoolean("notification_weather_city", false) "notification_shade_shortcut",
"com.android.systemui.qs.MiuiQSHeaderView".hookAfterMethod( "id",
getDefaultClassLoader(), context.packageName
"onFinishInflate" )
) { )
val viewGroup = it.thisObject as ViewGroup layoutParam.putObject(
val context = viewGroup.context "topToTop",
val layoutParam = context.resources.getIdentifier(
loadClass("androidx.constraintlayout.widget.ConstraintLayout\$LayoutParams") "notification_shade_shortcut",
.getConstructor(Int::class.java, Int::class.java) "id",
.newInstance( context.packageName
ViewGroup.LayoutParams.WRAP_CONTENT, )
ViewGroup.LayoutParams.WRAP_CONTENT )
) as ViewGroup.MarginLayoutParams layoutParam.putObject(
"bottomToBottom",
context.resources.getIdentifier(
"notification_shade_shortcut",
"id",
context.packageName
)
)
layoutParam.setObjectField( mWeatherView = WeatherView(context, isDisplayCity).apply {
"endToStart", setTextAppearance(
context.resources.getIdentifier( context.resources.getIdentifier(
"notification_shade_shortcut", "TextAppearance.StatusBar.Expanded.Clock.QuickSettingDate",
"id", "style",
context.packageName context.packageName
) )
) )
layoutParam.setObjectField( layoutParams = layoutParam
"topToTop",
context.resources.getIdentifier(
"notification_shade_shortcut",
"id",
context.packageName
)
)
layoutParam.setObjectField(
"bottomToBottom",
context.resources.getIdentifier(
"notification_shade_shortcut",
"id",
context.packageName
)
)
mWeatherView = WeatherView(context, isDisplayCity).apply {
setTextAppearance(
context.resources.getIdentifier(
"TextAppearance.StatusBar.Expanded.Clock.QuickSettingDate",
"style",
context.packageName
)
)
layoutParams = layoutParam
}
viewGroup.addView(mWeatherView)
(mWeatherView as WeatherView).setOnClickListener {
try {
val intent = Intent().apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
component = ComponentName(
"com.miui.weather2",
"com.miui.weather2.ActivityWeatherMain"
)
}
context.startActivity(intent)
} catch (e: Exception) {
Toast.makeText(context, "启动失败,可能是不支持", Toast.LENGTH_LONG).show()
}
}
} }
//解决横屏重叠 viewGroup.addView(mWeatherView)
"com.android.systemui.qs.MiuiQSHeaderView".hookAfterMethod( (mWeatherView as WeatherView).setOnClickListener {
getDefaultClassLoader(), try {
"updateLayout" val intent = Intent().apply {
) { flags = Intent.FLAG_ACTIVITY_NEW_TASK
val mOritation = it.thisObject.getObjectField("mOrientation") as Int component = ComponentName(
if (mOritation == 1) { "com.miui.weather2",
mWeatherView!!.visibility = View.VISIBLE "com.miui.weather2.ActivityWeatherMain"
} else { )
mWeatherView!!.visibility = View.GONE }
context.startActivity(intent)
} catch (e: Exception) {
Toast.makeText(context, "启动失败,可能是不支持", Toast.LENGTH_LONG).show()
} }
} }
} }
//解决横屏重叠
findMethod("com.android.systemui.qs.MiuiQSHeaderView") {
name == "updateLayout"
}.hookAfter {
val mOritation = it.thisObject.getObject("mOrientation") as Int
if (mOritation == 1) {
mWeatherView!!.visibility = View.VISIBLE
} else {
mWeatherView!!.visibility = View.GONE
}
}
} }
} }

View File

@@ -2,52 +2,48 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.content.res.Configuration import android.content.res.Configuration
import android.view.ViewGroup import android.view.ViewGroup
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.github.kyuubiran.ezxhelper.utils.putObject
import com.lt2333.simplicitytools.util.XSPUtils import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.XposedHelpers
object OldQSCustom: HookRegister() { object OldQSCustom : HookRegister() {
override fun init() = hasEnable("old_qs_custom_switch") {
val mRows = XSPUtils.getInt("qs_custom_rows", 3)
val mRowsHorizontal = XSPUtils.getInt("qs_custom_rows_horizontal", 2)
val mColumns = XSPUtils.getInt("qs_custom_columns", 4)
val mColumnsUnexpanded = XSPUtils.getInt("qs_custom_columns_unexpanded", 5)
override fun init() { findMethod("com.android.systemui.qs.MiuiQuickQSPanel") {
hasEnable("old_qs_custom_switch") { name == "setMaxTiles" && parameterCount == 1
val mRows = XSPUtils.getInt("qs_custom_rows", 3) }.hookBefore {
val mRowsHorizontal = XSPUtils.getInt("qs_custom_rows_horizontal", 2) //未展开时的列数
val mColumns = XSPUtils.getInt("qs_custom_columns", 4) it.args[0] = mColumnsUnexpanded
val mColumnsUnexpanded = XSPUtils.getInt("qs_custom_columns_unexpanded", 5) }
"com.android.systemui.qs.MiuiQuickQSPanel".hookBeforeMethod( findMethod("com.android.systemui.qs.MiuiTileLayout") {
getDefaultClassLoader(), name == "updateColumns"
"setMaxTiles", Int::class.java }.hookAfter {
) { //展开时的列数
//未展开时的列数 it.thisObject.putObject("mColumns", mColumns)
it.args[0] = mColumnsUnexpanded }
}
"com.android.systemui.qs.MiuiTileLayout".hookAfterMethod( findMethod("com.android.systemui.qs.MiuiTileLayout") {
getDefaultClassLoader(), name == "updateResources"
"updateColumns" }.hookAfter {
) { //展开时的行数
//展开时的列数 val viewGroup = it.thisObject as ViewGroup
XposedHelpers.setObjectField(it.thisObject, "mColumns", mColumns) val mConfiguration: Configuration = viewGroup.context.resources.configuration
} if (mConfiguration.orientation == Configuration.ORIENTATION_PORTRAIT) {
"com.android.systemui.qs.MiuiTileLayout".hookAfterMethod( XposedHelpers.setObjectField(viewGroup, "mMaxAllowedRows", mRows)
getDefaultClassLoader(), } else {
"updateResources" XposedHelpers.setObjectField(viewGroup, "mMaxAllowedRows", mRowsHorizontal)
) {
//展开时的行数
val viewGroup = it.thisObject as ViewGroup
val mConfiguration: Configuration = viewGroup.context.resources.configuration
if (mConfiguration.orientation == Configuration.ORIENTATION_PORTRAIT) {
XposedHelpers.setObjectField(viewGroup, "mMaxAllowedRows", mRows)
} else {
XposedHelpers.setObjectField(viewGroup, "mMaxAllowedRows", mRowsHorizontal)
}
viewGroup.requestLayout()
} }
viewGroup.requestLayout()
} }
} }
} }

View File

@@ -2,34 +2,41 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.view.View import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import com.lt2333.simplicitytools.util.getObjectField import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object RemoveLockScreenCamera: HookRegister() { object RemoveLockScreenCamera : HookRegister() {
override fun init() { override fun init() {
//屏蔽右下角组件显示 //屏蔽右下角组件显示
"com.android.systemui.statusbar.phone.KeyguardBottomAreaView".hookAfterMethod(getDefaultClassLoader(), "onFinishInflate") { findMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView") {
name == "onFinishInflate"
}.hookAfter {
hasEnable("remove_lock_screen_camera") { hasEnable("remove_lock_screen_camera") {
(it.thisObject.getObjectField("mRightAffordanceViewLayout") as LinearLayout).visibility = View.GONE (it.thisObject.getObject("mRightAffordanceViewLayout") as LinearLayout).visibility =
View.GONE
} }
} }
//屏蔽滑动撞墙动画 //屏蔽滑动撞墙动画
"com.android.keyguard.KeyguardMoveRightController".hookBeforeMethod(getDefaultClassLoader(), "onTouchMove", Float::class.java, Float::class.java) { findMethod("com.android.keyguard.KeyguardMoveRightController") {
name == "onTouchMove" && parameterCount == 2
}.hookBefore {
hasEnable("remove_lock_screen_camera") { hasEnable("remove_lock_screen_camera") {
it.result = false it.result = false
} }
} }
"com.android.keyguard.KeyguardMoveRightController".hookBeforeMethod(getDefaultClassLoader(), "reset") { findMethod("com.android.keyguard.KeyguardMoveRightController") {
name == "reset"
}.hookBefore {
hasEnable("remove_lock_screen_camera") { hasEnable("remove_lock_screen_camera") {
it.result = null it.result = null
} }
} }
} }
} }

View File

@@ -1,17 +1,18 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object RemoveTheLeftSideOfTheLockScreen: HookRegister() { object RemoveTheLeftSideOfTheLockScreen : HookRegister() {
override fun init() { override fun init() {
"com.android.keyguard.negative.MiuiKeyguardMoveLeftViewContainer".hookBeforeMethod(getDefaultClassLoader(), "inflateLeftView") { findMethod("com.android.keyguard.negative.MiuiKeyguardMoveLeftViewContainer") {
name == "inflateLeftView"
}.hookBefore {
hasEnable("remove_the_left_side_of_the_lock_screen") { hasEnable("remove_the_left_side_of_the_lock_screen") {
it.result = null it.result = null
} }
} }
} }
} }

View File

@@ -9,121 +9,116 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
import com.lt2333.simplicitytools.util.XSPUtils import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.XposedHelpers
object StatusBarBigMobileTypeIcon: HookRegister() { object StatusBarBigMobileTypeIcon : HookRegister() {
private val upAndDownPosition = XSPUtils.getInt("big_mobile_type_icon_up_and_down_position", 0) private val upAndDownPosition = XSPUtils.getInt("big_mobile_type_icon_up_and_down_position", 0)
private val leftAndRightMargin = XSPUtils.getInt("big_mobile_type_icon_left_and_right_margins", 0) private val leftAndRightMargin =
XSPUtils.getInt("big_mobile_type_icon_left_and_right_margins", 0)
private val isBold = XSPUtils.getBoolean("big_mobile_type_icon_bold", true) private val isBold = XSPUtils.getBoolean("big_mobile_type_icon_bold", true)
private val size = XSPUtils.getFloat("big_mobile_type_icon_size", 12.5f) private val size = XSPUtils.getFloat("big_mobile_type_icon_size", 12.5f)
override fun init() { override fun init() = hasEnable("big_mobile_type_icon") {
hasEnable("big_mobile_type_icon") { findMethod("com.android.systemui.statusbar.StatusBarMobileView") {
"com.android.systemui.statusbar.StatusBarMobileView".hookAfterMethod( name == "init"
getDefaultClassLoader(), }.hookAfter {
"init" val statusBarMobileView = it.thisObject as ViewGroup
) { val context: Context = statusBarMobileView.context
val statusBarMobileView = it.thisObject as ViewGroup val res: Resources = context.resources
val context: Context = statusBarMobileView.context
val res: Resources = context.resources
//获取组件 //获取组件
val mobileContainerLeftId: Int = val mobileContainerLeftId: Int =
res.getIdentifier("mobile_container_left", "id", "com.android.systemui") res.getIdentifier("mobile_container_left", "id", "com.android.systemui")
val mobileContainerLeft = val mobileContainerLeft =
statusBarMobileView.findViewById<ViewGroup>(mobileContainerLeftId) statusBarMobileView.findViewById<ViewGroup>(mobileContainerLeftId)
val mobileTypeId: Int = val mobileTypeId: Int =
res.getIdentifier("mobile_type", "id", "com.android.systemui") res.getIdentifier("mobile_type", "id", "com.android.systemui")
val mobileType = statusBarMobileView.findViewById<TextView>(mobileTypeId) val mobileType = statusBarMobileView.findViewById<TextView>(mobileTypeId)
val mobileLeftMobileInoutId: Int = res.getIdentifier( val mobileLeftMobileInoutId: Int = res.getIdentifier(
"mobile_left_mobile_inout", "mobile_left_mobile_inout",
"id", "id",
"com.android.systemui" "com.android.systemui"
) )
val mobileLeftMobileInout = val mobileLeftMobileInout =
statusBarMobileView.findViewById<ImageView>(mobileLeftMobileInoutId) statusBarMobileView.findViewById<ImageView>(mobileLeftMobileInoutId)
//获取插入位置 //获取插入位置
val mobileContainerRightId: Int = res.getIdentifier( val mobileContainerRightId: Int = res.getIdentifier(
"mobile_container_right", "mobile_container_right",
"id", "id",
"com.android.systemui" "com.android.systemui"
) )
val mobileContainerRight = val mobileContainerRight =
statusBarMobileView.findViewById<ViewGroup>(mobileContainerRightId) statusBarMobileView.findViewById<ViewGroup>(mobileContainerRightId)
val rightParentLayout = mobileContainerRight.parent as ViewGroup val rightParentLayout = mobileContainerRight.parent as ViewGroup
val mobileContainerRightIndex = val mobileContainerRightIndex =
rightParentLayout.indexOfChild(mobileContainerRight) rightParentLayout.indexOfChild(mobileContainerRight)
//创建新布局 //创建新布局
val newLinearLayoutLP = LinearLayout.LayoutParams( val newLinearLayoutLP = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.MATCH_PARENT LinearLayout.LayoutParams.MATCH_PARENT
).also { ).also {
}
val newLinearlayout = LinearLayout(context).also {
it.layoutParams = newLinearLayoutLP
it.id = mobileContainerLeftId
it.setPadding(leftAndRightMargin, 0, leftAndRightMargin, 0)
}
XposedHelpers.setObjectField(it.thisObject, "mMobileLeftContainer", newLinearlayout)
rightParentLayout.addView(
newLinearlayout,
mobileContainerRightIndex
)
//将组件插入新的布局
(mobileType.parent as ViewGroup).removeView(mobileType)
(mobileLeftMobileInout.parent as ViewGroup).removeView(mobileLeftMobileInout)
(mobileContainerLeft.parent as ViewGroup).removeView(mobileContainerLeft)
newLinearlayout.addView(mobileType) //类型
val mobileTypeLp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).also {
it.gravity = Gravity.CENTER_VERTICAL
it.topMargin = upAndDownPosition
}
mobileType.also {
it.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size)
if (isBold) {
it.typeface = Typeface.DEFAULT_BOLD
}
it.layoutParams = mobileTypeLp
}
newLinearlayout.addView(mobileLeftMobileInout) //箭头
val mobileLeftMobileInoutLp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
mobileLeftMobileInout.also {
it.layoutParams = mobileLeftMobileInoutLp
}
//屏蔽更新布局
"com.android.systemui.statusbar.StatusBarMobileView".hookBeforeMethod(
getDefaultClassLoader(),
"updateMobileTypeLayout", String::class.java
) {
it.result = null
}
} }
val newLinearlayout = LinearLayout(context).also {
it.layoutParams = newLinearLayoutLP
it.id = mobileContainerLeftId
it.setPadding(leftAndRightMargin, 0, leftAndRightMargin, 0)
}
XposedHelpers.setObjectField(it.thisObject, "mMobileLeftContainer", newLinearlayout)
rightParentLayout.addView(
newLinearlayout,
mobileContainerRightIndex
)
//将组件插入新的布局
(mobileType.parent as ViewGroup).removeView(mobileType)
(mobileLeftMobileInout.parent as ViewGroup).removeView(mobileLeftMobileInout)
(mobileContainerLeft.parent as ViewGroup).removeView(mobileContainerLeft)
newLinearlayout.addView(mobileType) //类型
val mobileTypeLp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).also {
it.gravity = Gravity.CENTER_VERTICAL
it.topMargin = upAndDownPosition
}
mobileType.also {
it.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size)
if (isBold) {
it.typeface = Typeface.DEFAULT_BOLD
}
it.layoutParams = mobileTypeLp
}
newLinearlayout.addView(mobileLeftMobileInout) //箭头
val mobileLeftMobileInoutLp = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
mobileLeftMobileInout.also {
it.layoutParams = mobileLeftMobileInoutLp
}
//屏蔽更新布局
findMethod("com.android.systemui.statusbar.StatusBarMobileView") {
name == "updateMobileTypeLayout" && parameterTypes[0] == String::class.java
}.hookReturnConstant(null)
} }
} }
} }

View File

@@ -1,69 +1,62 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.SystemClock import android.os.SystemClock
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View.OnTouchListener import android.view.View.OnTouchListener
import android.view.ViewGroup import android.view.ViewGroup
import com.lt2333.simplicitytools.util.findClass import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.XposedHelpers
object StatusBarDoubleTapToSleep: HookRegister() { object StatusBarDoubleTapToSleep : HookRegister() {
override fun init() = hasEnable("status_bar_double_tap_to_sleep") {
@SuppressLint("ClickableViewAccessibility") findMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView") {
override fun init() { name == "onFinishInflate"
hasEnable("status_bar_double_tap_to_sleep") { }.hookBefore {
"com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView".findClass( val view = it.thisObject as ViewGroup
getDefaultClassLoader() XposedHelpers.setAdditionalInstanceField(view, "currentTouchTime", 0L)
).hookBeforeMethod( XposedHelpers.setAdditionalInstanceField(view, "currentTouchX", 0f)
"onFinishInflate" XposedHelpers.setAdditionalInstanceField(view, "currentTouchY", 0f)
) { view.setOnTouchListener(OnTouchListener { v, event ->
val view = it.thisObject as ViewGroup if (event.action != MotionEvent.ACTION_DOWN) return@OnTouchListener false
XposedHelpers.setAdditionalInstanceField(view, "currentTouchTime", 0L) var currentTouchTime =
XposedHelpers.setAdditionalInstanceField(view, "currentTouchX", 0f) XposedHelpers.getAdditionalInstanceField(view, "currentTouchTime") as Long
XposedHelpers.setAdditionalInstanceField(view, "currentTouchY", 0f) var currentTouchX =
view.setOnTouchListener(OnTouchListener { v, event -> XposedHelpers.getAdditionalInstanceField(view, "currentTouchX") as Float
if (event.action != MotionEvent.ACTION_DOWN) return@OnTouchListener false var currentTouchY =
var currentTouchTime = XposedHelpers.getAdditionalInstanceField(view, "currentTouchY") as Float
XposedHelpers.getAdditionalInstanceField(view, "currentTouchTime") as Long val lastTouchTime = currentTouchTime
var currentTouchX = val lastTouchX = currentTouchX
XposedHelpers.getAdditionalInstanceField(view, "currentTouchX") as Float val lastTouchY = currentTouchY
var currentTouchY = currentTouchTime = System.currentTimeMillis()
XposedHelpers.getAdditionalInstanceField(view, "currentTouchY") as Float currentTouchX = event.x
val lastTouchTime = currentTouchTime currentTouchY = event.y
val lastTouchX = currentTouchX if (currentTouchTime - lastTouchTime < 250L && Math.abs(currentTouchX - lastTouchX) < 100f && Math.abs(
val lastTouchY = currentTouchY currentTouchY - lastTouchY
currentTouchTime = System.currentTimeMillis() ) < 100f
currentTouchX = event.x ) {
currentTouchY = event.y XposedHelpers.callMethod(
if (currentTouchTime - lastTouchTime < 250L && Math.abs(currentTouchX - lastTouchX) < 100f && Math.abs( v.context.getSystemService(Context.POWER_SERVICE),
currentTouchY - lastTouchY "goToSleep",
) < 100f SystemClock.uptimeMillis()
) {
XposedHelpers.callMethod(
v.context.getSystemService(Context.POWER_SERVICE),
"goToSleep",
SystemClock.uptimeMillis()
)
currentTouchTime = 0L
currentTouchX = 0f
currentTouchY = 0f
}
XposedHelpers.setAdditionalInstanceField(
view,
"currentTouchTime",
currentTouchTime
) )
XposedHelpers.setAdditionalInstanceField(view, "currentTouchX", currentTouchX) currentTouchTime = 0L
XposedHelpers.setAdditionalInstanceField(view, "currentTouchY", currentTouchY) currentTouchX = 0f
false currentTouchY = 0f
}) }
} XposedHelpers.setAdditionalInstanceField(
view,
"currentTouchTime",
currentTouchTime
)
XposedHelpers.setAdditionalInstanceField(view, "currentTouchX", currentTouchX)
XposedHelpers.setAdditionalInstanceField(view, "currentTouchY", currentTouchY)
v.performClick()
false
})
} }
} }
} }

View File

@@ -1,11 +1,9 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import android.annotation.SuppressLint
import android.app.KeyguardManager import android.app.KeyguardManager
import android.content.Context import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.os.Bundle
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -13,45 +11,53 @@ import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import cn.fkj233.ui.activity.dp2px import cn.fkj233.ui.activity.dp2px
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.getObject
import com.github.kyuubiran.ezxhelper.utils.hookAfter
import com.lt2333.simplicitytools.util.XSPUtils import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.findClass import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.getObjectField
import com.lt2333.simplicitytools.util.hookAfterMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.XposedHelpers
@SuppressLint("StaticFieldLeak")
object StatusBarLayout : HookRegister() { object StatusBarLayout : HookRegister() {
private var mLeftLayout: LinearLayout? = null
private var mRightLayout: LinearLayout? = null
private var mCenterLayout: LinearLayout? = null
private var statusBar: ViewGroup? = null
private var statusBarLeft = 0 private var statusBarLeft = 0
private var statusBarTop = 0 private var statusBarTop = 0
private var statusBarRight = 0 private var statusBarRight = 0
private var statusBarBottom = 0 private var statusBarBottom = 0
override fun init() { override fun init() {
var mLeftLayout: LinearLayout? = null
var mRightLayout: LinearLayout? = null
var mCenterLayout: LinearLayout? = null
var statusBar: ViewGroup? = null
fun updateLayout(context: Context) {
//判断屏幕方向
val mConfiguration: Configuration = context.resources.configuration
if (mConfiguration.orientation == Configuration.ORIENTATION_PORTRAIT) {
mLeftLayout!!.setPadding(statusBarLeft, 0, 0, 0)
mRightLayout!!.setPadding(0, 0, statusBarRight, 0)
statusBar!!.setPadding(0, statusBarTop, 0, statusBarBottom)
} else {
//横屏状态
mLeftLayout!!.setPadding(175, 0, 0, 0)
mRightLayout!!.setPadding(0, 0, 175, 0)
statusBar!!.setPadding(0, statusBarTop, 0, statusBarBottom)
}
}
when (XSPUtils.getInt("status_bar_layout_mode", 0)) { when (XSPUtils.getInt("status_bar_layout_mode", 0)) {
//默认 //默认
0 -> return 0 -> return
//时钟居中 //时钟居中
1 -> { 1 -> {
val collapsedStatusBarFragmentClass = findMethod("com.android.systemui.statusbar.phone.CollapsedStatusBarFragment") {
"com.android.systemui.statusbar.phone.CollapsedStatusBarFragment".findClass( name == "onViewCreated" && parameterCount == 2
getDefaultClassLoader() }.hookAfter {
)
collapsedStatusBarFragmentClass.hookAfterMethod(
"onViewCreated",
View::class.java,
Bundle::class.java
) { param ->
val MiuiPhoneStatusBarView: ViewGroup = val MiuiPhoneStatusBarView: ViewGroup =
param.thisObject.getObjectField("mStatusBar") as ViewGroup it.thisObject.getObject("mStatusBar") as ViewGroup
val context: Context = MiuiPhoneStatusBarView.context val context: Context = MiuiPhoneStatusBarView.context
val res: Resources = MiuiPhoneStatusBarView.resources val res: Resources = MiuiPhoneStatusBarView.resources
val statusBarId: Int = val statusBarId: Int =
@@ -76,7 +82,7 @@ object StatusBarLayout : HookRegister() {
statusBar = MiuiPhoneStatusBarView.findViewById(statusBarId) statusBar = MiuiPhoneStatusBarView.findViewById(statusBarId)
val statusBarContents: ViewGroup = val statusBarContents: ViewGroup =
MiuiPhoneStatusBarView.findViewById(statusBarContentsId) MiuiPhoneStatusBarView.findViewById(statusBarContentsId)
if (statusBar == null) return@hookAfterMethod if (statusBar == null) return@hookAfter
val clock: TextView = MiuiPhoneStatusBarView.findViewById(clockId) val clock: TextView = MiuiPhoneStatusBarView.findViewById(clockId)
val phoneStatusBarLeftContainer: ViewGroup = val phoneStatusBarLeftContainer: ViewGroup =
MiuiPhoneStatusBarView.findViewById(phoneStatusBarLeftContainerId) MiuiPhoneStatusBarView.findViewById(phoneStatusBarLeftContainerId)
@@ -159,13 +165,11 @@ object StatusBarLayout : HookRegister() {
updateLayout(context) updateLayout(context)
} }
} }
val phoneStatusBarViewClass =
"com.android.systemui.statusbar.phone.PhoneStatusBarView".findClass(
getDefaultClassLoader()
)
phoneStatusBarViewClass.hookAfterMethod("updateLayoutForCutout") { findMethod("com.android.systemui.statusbar.phone.PhoneStatusBarView") {
if (XSPUtils.getBoolean("layout_compatibility_mode", false)) { name == "updateLayoutForCutout"
}.hookAfter {
hasEnable("layout_compatibility_mode") {
val context = (it.thisObject as ViewGroup).context val context = (it.thisObject as ViewGroup).context
updateLayout(context) updateLayout(context)
} }
@@ -173,18 +177,11 @@ object StatusBarLayout : HookRegister() {
} }
//时钟居右 //时钟居右
2 -> { 2 -> {
val collapsedStatusBarFragmentClass = findMethod("com.android.systemui.statusbar.phone.CollapsedStatusBarFragment") {
"com.android.systemui.statusbar.phone.CollapsedStatusBarFragment".findClass( name == "onViewCreated" && parameterCount == 2
getDefaultClassLoader() }.hookAfter {
) val MiuiPhoneStatusBarView =
it.thisObject.getObject("mStatusBar") as ViewGroup
collapsedStatusBarFragmentClass.hookAfterMethod(
"onViewCreated",
View::class.java,
Bundle::class.java
) { param ->
val MiuiPhoneStatusBarView: ViewGroup =
param.thisObject.getObjectField("mStatusBar") as ViewGroup
val context: Context = MiuiPhoneStatusBarView.context val context: Context = MiuiPhoneStatusBarView.context
val res: Resources = MiuiPhoneStatusBarView.resources val res: Resources = MiuiPhoneStatusBarView.resources
@@ -196,7 +193,7 @@ object StatusBarLayout : HookRegister() {
//查找组件 //查找组件
statusBar = MiuiPhoneStatusBarView.findViewById(statusBarId) statusBar = MiuiPhoneStatusBarView.findViewById(statusBarId)
if (statusBar == null) return@hookAfterMethod if (statusBar == null) return@hookAfter
val clock: TextView = MiuiPhoneStatusBarView.findViewById(clockId) val clock: TextView = MiuiPhoneStatusBarView.findViewById(clockId)
val battery: ViewGroup = MiuiPhoneStatusBarView.findViewById(batteryId) val battery: ViewGroup = MiuiPhoneStatusBarView.findViewById(batteryId)
@@ -219,18 +216,11 @@ object StatusBarLayout : HookRegister() {
} }
//时钟居中+图标居左 //时钟居中+图标居左
3 -> { 3 -> {
val collapsedStatusBarFragmentClass = findMethod("com.android.systemui.statusbar.phone.CollapsedStatusBarFragment") {
"com.android.systemui.statusbar.phone.CollapsedStatusBarFragment".findClass( name == "onViewCreated" && parameterCount == 2
getDefaultClassLoader() }.hookAfter {
) val MiuiPhoneStatusBarView =
it.thisObject.getObject("mStatusBar") as ViewGroup
collapsedStatusBarFragmentClass.hookAfterMethod(
"onViewCreated",
View::class.java,
Bundle::class.java
) { param ->
val MiuiPhoneStatusBarView: ViewGroup =
param.thisObject.getObjectField("mStatusBar") as ViewGroup
val context: Context = MiuiPhoneStatusBarView.context val context: Context = MiuiPhoneStatusBarView.context
val res: Resources = MiuiPhoneStatusBarView.resources val res: Resources = MiuiPhoneStatusBarView.resources
val statusBarId: Int = val statusBarId: Int =
@@ -280,7 +270,7 @@ object StatusBarLayout : HookRegister() {
statusBar = MiuiPhoneStatusBarView.findViewById(statusBarId) statusBar = MiuiPhoneStatusBarView.findViewById(statusBarId)
val statusBarContents: ViewGroup = val statusBarContents: ViewGroup =
MiuiPhoneStatusBarView.findViewById(statusBarContentsId) MiuiPhoneStatusBarView.findViewById(statusBarContentsId)
if (statusBar == null) return@hookAfterMethod if (statusBar == null) return@hookAfter
val clock: TextView = MiuiPhoneStatusBarView.findViewById(clockId) val clock: TextView = MiuiPhoneStatusBarView.findViewById(clockId)
val phoneStatusBarLeftContainer: ViewGroup = val phoneStatusBarLeftContainer: ViewGroup =
MiuiPhoneStatusBarView.findViewById(phoneStatusBarLeftContainerId) MiuiPhoneStatusBarView.findViewById(phoneStatusBarLeftContainerId)
@@ -399,26 +389,19 @@ object StatusBarLayout : HookRegister() {
} }
} }
//兼容模式 //兼容模式
val phoneStatusBarViewClass = findMethod("com.android.systemui.statusbar.phone.PhoneStatusBarView") {
"com.android.systemui.statusbar.phone.PhoneStatusBarView".findClass( name == "updateLayoutForCutout"
getDefaultClassLoader() }.hookAfter {
)
phoneStatusBarViewClass.hookAfterMethod("updateLayoutForCutout") {
if (XSPUtils.getBoolean("layout_compatibility_mode", false)) { if (XSPUtils.getBoolean("layout_compatibility_mode", false)) {
val context = (it.thisObject as ViewGroup).context val context = (it.thisObject as ViewGroup).context
updateLayout(context) updateLayout(context)
} }
} }
//解决重叠
val miuiCollapsedStatusBarFragmentClass =
"com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment".findClass(
getDefaultClassLoader()
)
miuiCollapsedStatusBarFragmentClass.hookAfterMethod( //解决重叠
"showClock", findMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment") {
Boolean::class.java name == "showClock" && parameterTypes[0] == Boolean::class.java
) { }.hookAfter {
val MiuiPhoneStatusBarView = val MiuiPhoneStatusBarView =
XposedHelpers.getObjectField(it.thisObject, "mStatusBar") as ViewGroup XposedHelpers.getObjectField(it.thisObject, "mStatusBar") as ViewGroup
val res = MiuiPhoneStatusBarView.resources val res = MiuiPhoneStatusBarView.resources
@@ -436,21 +419,8 @@ object StatusBarLayout : HookRegister() {
} }
} }
} }
}
private fun updateLayout(context: Context) {
//判断屏幕方向
val mConfiguration: Configuration = context.resources.configuration
if (mConfiguration.orientation == Configuration.ORIENTATION_PORTRAIT) {
mLeftLayout!!.setPadding(statusBarLeft, 0, 0, 0)
mRightLayout!!.setPadding(0, 0, statusBarRight, 0)
statusBar!!.setPadding(0, statusBarTop, 0, statusBarBottom)
} else {
//横屏状态
mLeftLayout!!.setPadding(175, 0, 0, 0)
mRightLayout!!.setPadding(0, 0, 175, 0)
statusBar!!.setPadding(0, statusBarTop, 0, statusBarBottom)
}
} }
} }

View File

@@ -1,17 +1,18 @@
package com.lt2333.simplicitytools.hook.app.systemui package com.lt2333.simplicitytools.hook.app.systemui
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object StatusBarNetworkSpeedRefreshSpeed: HookRegister() { object StatusBarNetworkSpeedRefreshSpeed : HookRegister() {
override fun init() { override fun init() {
"com.android.systemui.statusbar.policy.NetworkSpeedController".hookBeforeMethod(getDefaultClassLoader(), "postUpdateNetworkSpeedDelay", Long::class.java) { findMethod("com.android.systemui.statusbar.policy.NetworkSpeedController") {
name == "postUpdateNetworkSpeedDelay" && parameterTypes[0] == Long::class.java
}.hookBefore {
hasEnable("status_bar_network_speed_refresh_speed") { hasEnable("status_bar_network_speed_refresh_speed") {
it.args[0] = 1000L it.args[0] = 1000L
} }
} }
} }
} }

View File

@@ -3,16 +3,14 @@ package com.lt2333.simplicitytools.hook.app.systemui
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.provider.Settings import android.provider.Settings
import android.util.AttributeSet
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity import android.view.Gravity
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import com.lt2333.simplicitytools.util.* import com.github.kyuubiran.ezxhelper.utils.*
import com.lt2333.simplicitytools.util.XSPUtils
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
import java.lang.reflect.Method import java.lang.reflect.Method
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@@ -41,17 +39,14 @@ object StatusBarTimeCustomization : HookRegister() {
override fun init() { override fun init() {
if (isOpen) { if (isOpen) {
var c: Context? = null var c: Context? = null
val miuiClockClass =
"com.android.systemui.statusbar.views.MiuiClock".findClass(getDefaultClassLoader()) findConstructor("com.android.systemui.statusbar.views.MiuiClock") {
miuiClockClass.hookAfterConstructor( paramCount == 3
Context::class.java, }.hookAfter {
AttributeSet::class.java,
Integer.TYPE
) {
try { try {
c = it.args[0] as Context c = it.args[0] as Context
val textV = it.thisObject as TextView val textV = it.thisObject as TextView
if (textV.resources.getResourceEntryName(textV.id) != "clock") return@hookAfterConstructor if (textV.resources.getResourceEntryName(textV.id) != "clock") return@hookAfter
textV.isSingleLine = false textV.isSingleLine = false
if (isDoubleLine) { if (isDoubleLine) {
str = "\n" str = "\n"
@@ -79,10 +74,13 @@ object StatusBarTimeCustomization : HookRegister() {
} }
} }
Timer().scheduleAtFixedRate(T(), 1000 - System.currentTimeMillis() % 1000, 1000) Timer().scheduleAtFixedRate(T(), 1000 - System.currentTimeMillis() % 1000, 1000)
} catch (e: java.lang.Exception) { } catch (e: Exception) {
} }
} }
miuiClockClass.hookAfterMethod("updateTime") {
findMethod("com.android.systemui.statusbar.views.MiuiClock") {
name == "updateTime"
}.hookAfter {
try { try {
val textV = it.thisObject as TextView val textV = it.thisObject as TextView
if (textV.resources.getResourceEntryName(textV.id) == "clock") { if (textV.resources.getResourceEntryName(textV.id) == "clock") {
@@ -97,18 +95,13 @@ object StatusBarTimeCustomization : HookRegister() {
} catch (e: Exception) { } catch (e: Exception) {
} }
} }
if (isCenterAlign) { if (isCenterAlign) {
val collapsedStatusBarFragmentClass = findMethod("com.android.systemui.statusbar.phone.CollapsedStatusBarFragment") {
"com.android.systemui.statusbar.phone.CollapsedStatusBarFragment".findClass( name == "onViewCreated" && parameterCount == 2
getDefaultClassLoader() }.hookAfter {
) val MiuiPhoneStatusBarView =
collapsedStatusBarFragmentClass.hookAfterMethod( it.thisObject.getObject("mStatusBar") as ViewGroup
"onViewCreated",
View::class.java,
Bundle::class.java
) {
val MiuiPhoneStatusBarView: ViewGroup =
it.thisObject.getObjectField("mStatusBar") as ViewGroup
val res: Resources = MiuiPhoneStatusBarView.resources val res: Resources = MiuiPhoneStatusBarView.resources
val clockId: Int = res.getIdentifier("clock", "id", "com.android.systemui") val clockId: Int = res.getIdentifier("clock", "id", "com.android.systemui")
val clock: TextView = MiuiPhoneStatusBarView.findViewById(clockId) val clock: TextView = MiuiPhoneStatusBarView.findViewById(clockId)

View File

@@ -1,18 +1,18 @@
package com.lt2333.simplicitytools.hook.app.thememanager package com.lt2333.simplicitytools.hook.app.thememanager
import com.lt2333.simplicitytools.util.findClass import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.hookBeforeMethod
import com.lt2333.simplicitytools.util.xposed.base.HookRegister import com.lt2333.simplicitytools.util.xposed.base.HookRegister
object RemoveAds : HookRegister() { object RemoveAds : HookRegister() {
override fun init() { override fun init() {
"com.android.thememanager.basemodule.ad.model.AdInfoResponse".hookBeforeMethod(getDefaultClassLoader(), "isAdValid", "com.android.thememanager.basemodule.ad.model.AdInfo".findClass(getDefaultClassLoader())) { findMethod("com.android.thememanager.basemodule.ad.model.AdInfoResponse") {
name == "isAdValid" && parameterCount == 1
}.hookBefore {
hasEnable("remove_thememanager_ads") { hasEnable("remove_thememanager_ads") {
it.result = false it.result = false
} }
} }
} }
} }

View File

@@ -1,502 +0,0 @@
package com.lt2333.simplicitytools.util
import android.content.res.XResources
import android.util.Log
import dalvik.system.BaseDexClassLoader
import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.XC_MethodReplacement
import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.XposedHelpers
import de.robv.android.xposed.callbacks.XC_LayoutInflated
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.util.*
const val TAG = "SimplicityTools"
fun log(any: Any?, online: Boolean = false) {
val msg: String = if (any is Throwable) Log.getStackTraceString(any) else any.toString()
// Log.d(TAG, msg)
XposedBridge.log("$TAG: $msg")
}
typealias MethodHookParam = XC_MethodHook.MethodHookParam
typealias Replacer = (XC_MethodHook.MethodHookParam) -> Any?
typealias Hooker = (XC_MethodHook.MethodHookParam) -> Unit
fun Class<*>.hookMethod(method: String?, vararg args: Any?) = try {
XposedHelpers.findAndHookMethod(this, method, *args)
} catch (e: NoSuchMethodError) {
log(e)
null
} catch (e: XposedHelpers.ClassNotFoundError) {
log(e)
null
} catch (e: ClassNotFoundException) {
log(e)
null
}
fun Member.hookMethod(callback: XC_MethodHook) = try {
XposedBridge.hookMethod(this, callback)
} catch (e: Throwable) {
log(e)
null
}
inline fun XC_MethodHook.MethodHookParam.callHooker(crossinline hooker: Hooker) = try {
hooker(this)
} catch (e: Throwable) {
log("Error occurred calling hooker on ${this.method}")
log(e)
}
inline fun XC_MethodHook.MethodHookParam.callReplacer(crossinline replacer: Replacer) = try {
replacer(this)
} catch (e: Throwable) {
log("Error occurred calling replacer on ${this.method}")
log(e)
null
}
inline fun Member.replaceMethod(crossinline replacer: Replacer) =
hookMethod(object : XC_MethodReplacement() {
override fun replaceHookedMethod(param: MethodHookParam) = param.callReplacer(replacer)
})
inline fun Member.hookAfterMethod(crossinline hooker: Hooker) =
hookMethod(object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Member.hookBeforeMethod(crossinline hooker: (XC_MethodHook.MethodHookParam) -> Unit) =
hookMethod(object : XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.hookBeforeMethod(
method: String?,
vararg args: Any?,
crossinline hooker: Hooker
) = hookMethod(method, *args, object : XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.hookAfterMethod(
method: String?,
vararg args: Any?,
crossinline hooker: Hooker
) = hookMethod(method, *args, object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.replaceMethod(
method: String?,
vararg args: Any?,
crossinline replacer: Replacer
) = hookMethod(method, *args, object : XC_MethodReplacement() {
override fun replaceHookedMethod(param: MethodHookParam) = param.callReplacer(replacer)
})
fun Class<*>.hookAllMethods(methodName: String?, hooker: XC_MethodHook): Set<XC_MethodHook.Unhook> =
try {
XposedBridge.hookAllMethods(this, methodName, hooker)
} catch (e: NoSuchMethodError) {
log(e)
emptySet()
} catch (e: XposedHelpers.ClassNotFoundError) {
log(e)
emptySet()
} catch (e: ClassNotFoundException) {
log(e)
emptySet()
}
inline fun Class<*>.hookBeforeAllMethods(methodName: String?, crossinline hooker: Hooker) =
hookAllMethods(methodName, object : XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.hookAfterAllMethods(methodName: String?, crossinline hooker: Hooker) =
hookAllMethods(methodName, object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.replaceAfterAllMethods(methodName: String?, crossinline replacer: Replacer) =
hookAllMethods(methodName, object : XC_MethodReplacement() {
override fun replaceHookedMethod(param: MethodHookParam) = param.callReplacer(replacer)
})
fun Class<*>.hookConstructor(vararg args: Any?) = try {
XposedHelpers.findAndHookConstructor(this, *args)
} catch (e: NoSuchMethodError) {
log(e)
null
} catch (e: XposedHelpers.ClassNotFoundError) {
log(e)
null
} catch (e: ClassNotFoundException) {
log(e)
null
}
inline fun Class<*>.hookBeforeConstructor(vararg args: Any?, crossinline hooker: Hooker) =
hookConstructor(*args, object : XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.hookAfterConstructor(vararg args: Any?, crossinline hooker: Hooker) =
hookConstructor(*args, object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.replaceConstructor(vararg args: Any?, crossinline hooker: Hooker) =
hookConstructor(*args, object : XC_MethodReplacement() {
override fun replaceHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
fun Class<*>.hookAllConstructors(hooker: XC_MethodHook): Set<XC_MethodHook.Unhook> = try {
XposedBridge.hookAllConstructors(this, hooker)
} catch (e: NoSuchMethodError) {
log(e)
emptySet()
} catch (e: XposedHelpers.ClassNotFoundError) {
log(e)
emptySet()
} catch (e: ClassNotFoundException) {
log(e)
emptySet()
}
inline fun Class<*>.hookAfterAllConstructors(crossinline hooker: Hooker) =
hookAllConstructors(object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.hookBeforeAllConstructors(crossinline hooker: Hooker) =
hookAllConstructors(object : XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
inline fun Class<*>.replaceAfterAllConstructors(crossinline hooker: Hooker) =
hookAllConstructors(object : XC_MethodReplacement() {
override fun replaceHookedMethod(param: MethodHookParam) = param.callHooker(hooker)
})
fun String.hookMethod(classLoader: ClassLoader, method: String?, vararg args: Any?) = try {
findClass(classLoader).hookMethod(method, *args)
} catch (e: XposedHelpers.ClassNotFoundError) {
log(e)
null
} catch (e: ClassNotFoundException) {
log(e)
null
}
inline fun String.hookBeforeMethod(
classLoader: ClassLoader,
method: String?,
vararg args: Any?,
crossinline hooker: Hooker
) = try {
findClass(classLoader).hookBeforeMethod(method, *args, hooker = hooker)
} catch (e: XposedHelpers.ClassNotFoundError) {
log(e)
null
} catch (e: ClassNotFoundException) {
log(e)
null
}
inline fun String.hookAfterMethod(
classLoader: ClassLoader,
method: String?,
vararg args: Any?,
crossinline hooker: Hooker
) = try {
findClass(classLoader).hookAfterMethod(method, *args, hooker = hooker)
} catch (e: XposedHelpers.ClassNotFoundError) {
log(e)
null
} catch (e: ClassNotFoundException) {
log(e)
null
}
inline fun String.replaceMethod(
classLoader: ClassLoader,
method: String?,
vararg args: Any?,
crossinline replacer: Replacer
) = try {
findClass(classLoader).replaceMethod(method, *args, replacer = replacer)
} catch (e: XposedHelpers.ClassNotFoundError) {
log(e)
null
} catch (e: ClassNotFoundException) {
log(e)
null
}
fun XC_MethodHook.MethodHookParam.invokeOriginalMethod(): Any? =
XposedBridge.invokeOriginalMethod(method, thisObject, args)
inline fun <T, R> T.runCatchingOrNull(func: T.() -> R?) = try {
func()
} catch (e: Throwable) {
null
}
fun Any.getObjectField(field: String?): Any? = XposedHelpers.getObjectField(this, field)
fun Any.getObjectFieldOrNull(field: String?): Any? = runCatchingOrNull {
XposedHelpers.getObjectField(this, field)
}
@Suppress("UNCHECKED_CAST")
fun <T> Any.getObjectFieldAs(field: String?) = XposedHelpers.getObjectField(this, field) as T
@Suppress("UNCHECKED_CAST")
fun <T> Any.getObjectFieldOrNullAs(field: String?) = runCatchingOrNull {
XposedHelpers.getObjectField(this, field) as T
}
fun Any.getIntField(field: String?) = XposedHelpers.getIntField(this, field)
fun Any.getIntFieldOrNull(field: String?) = runCatchingOrNull {
XposedHelpers.getIntField(this, field)
}
fun Any.getLongField(field: String?) = XposedHelpers.getLongField(this, field)
fun Any.getLongFieldOrNull(field: String?) = runCatchingOrNull {
XposedHelpers.getLongField(this, field)
}
fun Any.getBooleanFieldOrNull(field: String?) = runCatchingOrNull {
XposedHelpers.getBooleanField(this, field)
}
fun Any.callMethod(methodName: String?, vararg args: Any?): Any? =
XposedHelpers.callMethod(this, methodName, *args)
fun Any.callMethodOrNull(methodName: String?, vararg args: Any?): Any? = runCatchingOrNull {
XposedHelpers.callMethod(this, methodName, *args)
}
fun Class<*>.callStaticMethod(methodName: String?, vararg args: Any?): Any? =
XposedHelpers.callStaticMethod(this, methodName, *args)
fun Class<*>.callStaticMethodOrNull(methodName: String?, vararg args: Any?): Any? =
runCatchingOrNull {
XposedHelpers.callStaticMethod(this, methodName, *args)
}
@Suppress("UNCHECKED_CAST")
fun <T> Class<*>.callStaticMethodAs(methodName: String?, vararg args: Any?) =
XposedHelpers.callStaticMethod(this, methodName, *args) as T
@Suppress("UNCHECKED_CAST")
fun <T> Class<*>.callStaticMethodOrNullAs(methodName: String?, vararg args: Any?) =
runCatchingOrNull {
XposedHelpers.callStaticMethod(this, methodName, *args) as T
}
@Suppress("UNCHECKED_CAST")
fun <T> Class<*>.getStaticObjectFieldAs(field: String?) = XposedHelpers.getStaticObjectField(
this,
field
) as T
@Suppress("UNCHECKED_CAST")
fun <T> Class<*>.getStaticObjectFieldOrNullAs(field: String?) = runCatchingOrNull {
XposedHelpers.getStaticObjectField(this, field) as T
}
fun Class<*>.getStaticObjectField(field: String?): Any? =
XposedHelpers.getStaticObjectField(this, field)
fun Class<*>.getStaticObjectFieldOrNull(field: String?): Any? = runCatchingOrNull {
XposedHelpers.getStaticObjectField(this, field)
}
fun Class<*>.setStaticObjectField(field: String?, obj: Any?) = apply {
XposedHelpers.setStaticObjectField(this, field, obj)
}
fun Class<*>.setStaticObjectFieldIfExist(field: String?, obj: Any?) = apply {
try {
XposedHelpers.setStaticObjectField(this, field, obj)
} catch (ignored: Throwable) {
}
}
inline fun <reified T> Class<*>.findFieldByExactType(): Field? =
XposedHelpers.findFirstFieldByExactType(this, T::class.java)
fun Class<*>.findFieldByExactType(type: Class<*>): Field? =
XposedHelpers.findFirstFieldByExactType(this, type)
@Suppress("UNCHECKED_CAST")
fun <T> Any.callMethodAs(methodName: String?, vararg args: Any?) =
XposedHelpers.callMethod(this, methodName, *args) as T
@Suppress("UNCHECKED_CAST")
fun <T> Any.callMethodOrNullAs(methodName: String?, vararg args: Any?) = runCatchingOrNull {
XposedHelpers.callMethod(this, methodName, *args) as T
}
fun Any.callMethod(methodName: String?, parameterTypes: Array<Class<*>>, vararg args: Any?): Any? =
XposedHelpers.callMethod(this, methodName, parameterTypes, *args)
fun Any.callMethodOrNull(
methodName: String?,
parameterTypes: Array<Class<*>>,
vararg args: Any?
): Any? = runCatchingOrNull {
XposedHelpers.callMethod(this, methodName, parameterTypes, *args)
}
fun Class<*>.callStaticMethod(
methodName: String?,
parameterTypes: Array<Class<*>>,
vararg args: Any?
): Any? = XposedHelpers.callStaticMethod(this, methodName, parameterTypes, *args)
fun Class<*>.callStaticMethodOrNull(
methodName: String?,
parameterTypes: Array<Class<*>>,
vararg args: Any?
): Any? = runCatchingOrNull {
XposedHelpers.callStaticMethod(this, methodName, parameterTypes, *args)
}
fun String.findClass(classLoader: ClassLoader?): Class<*> =
XposedHelpers.findClass(this, classLoader)
fun String.findClassOrNull(classLoader: ClassLoader?): Class<*>? =
XposedHelpers.findClassIfExists(this, classLoader)
fun Class<*>.new(vararg args: Any?): Any = XposedHelpers.newInstance(this, *args)
fun Class<*>.new(parameterTypes: Array<Class<*>>, vararg args: Any?): Any =
XposedHelpers.newInstance(this, parameterTypes, *args)
fun Class<*>.findField(field: String?): Field = XposedHelpers.findField(this, field)
fun Class<*>.findFieldOrNull(field: String?): Field? = XposedHelpers.findFieldIfExists(this, field)
fun <T> T.setIntField(field: String?, value: Int) = apply {
XposedHelpers.setIntField(this, field, value)
}
fun <T> T.setLongField(field: String?, value: Long) = apply {
XposedHelpers.setLongField(this, field, value)
}
fun <T> T.setFloatField(field: String?, value: Float) = apply {
XposedHelpers.setFloatField(this, field, value)
}
fun <T> T.setObjectField(field: String?, value: Any?) = apply {
XposedHelpers.setObjectField(this, field, value)
}
fun <T> T.setBooleanField(field: String?, value: Boolean) = apply {
XposedHelpers.setBooleanField(this, field, value)
}
inline fun XResources.hookLayout(
id: Int,
crossinline hooker: (XC_LayoutInflated.LayoutInflatedParam) -> Unit
) {
try {
hookLayout(id, object : XC_LayoutInflated() {
override fun handleLayoutInflated(liparam: LayoutInflatedParam) {
try {
hooker(liparam)
} catch (e: Throwable) {
log(e)
}
}
})
} catch (e: Throwable) {
log(e)
}
}
inline fun XResources.hookLayout(
pkg: String,
type: String,
name: String,
crossinline hooker: (XC_LayoutInflated.LayoutInflatedParam) -> Unit
) {
try {
val id = getIdentifier(name, type, pkg)
hookLayout(id, hooker)
} catch (e: Throwable) {
log(e)
}
}
fun Class<*>.findFirstFieldByExactType(type: Class<*>): Field =
XposedHelpers.findFirstFieldByExactType(this, type)
fun Class<*>.findFirstFieldByExactTypeOrNull(type: Class<*>?): Field? = runCatchingOrNull {
XposedHelpers.findFirstFieldByExactType(this, type)
}
fun Any.getFirstFieldByExactType(type: Class<*>): Any? =
javaClass.findFirstFieldByExactType(type).get(this)
@Suppress("UNCHECKED_CAST")
fun <T> Any.getFirstFieldByExactTypeAs(type: Class<*>) =
javaClass.findFirstFieldByExactType(type).get(this) as? T
inline fun <reified T : Any> Any.getFirstFieldByExactType() =
javaClass.findFirstFieldByExactType(T::class.java).get(this) as? T
fun Any.getFirstFieldByExactTypeOrNull(type: Class<*>?): Any? = runCatchingOrNull {
javaClass.findFirstFieldByExactTypeOrNull(type)?.get(this)
}
@Suppress("UNCHECKED_CAST")
fun <T> Any.getFirstFieldByExactTypeOrNullAs(type: Class<*>?) =
getFirstFieldByExactTypeOrNull(type) as? T
inline fun <reified T> Any.getFirstFieldByExactTypeOrNull() =
getFirstFieldByExactTypeOrNull(T::class.java) as? T
fun ClassLoader.allClassesList(): List<String> {
var classLoader = this
while (classLoader !is BaseDexClassLoader) {
if (classLoader.parent != null) classLoader = classLoader.parent
else return emptyList()
}
return classLoader.getObjectField("pathList")
?.getObjectFieldAs<Array<Any>>("dexElements")
?.flatMap {
it.getObjectField("dexFile")?.callMethodAs<Enumeration<String>>("entries")?.toList()
.orEmpty()
}.orEmpty()
}
inline fun ClassLoader.findDexClassLoader(): BaseDexClassLoader? {
var classLoader = this
while (classLoader !is BaseDexClassLoader) {
if (classLoader.parent != null) classLoader = classLoader.parent
else return null
}
return classLoader
}
inline fun <T> T?.isNull(crossinline isNull: () -> Unit):T? {
if (this == null) isNull()
return this
}
inline fun <T> T?.isNonNull(crossinline nonNull: (T) -> Unit): T? {
if (this != null) nonNull(this)
return this
}