Skip to content

Commit

Permalink
修复移动数据的重复监听问题 && 修复 dexkit 无写入缓存的问题 (#1016)
Browse files Browse the repository at this point in the history
Co-authored-by: 铃柒柒 <[email protected]>
  • Loading branch information
xzakota and lingqiqi5211 authored Dec 3, 2024
1 parent c980690 commit be515fe
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
public class DexKit {
public boolean isInit = false;
// 更新版本可触发全部缓存重建,建议使用整数
private final String version = "3";
private static final String version = "4";
private static final String TYPE_METHOD = "METHOD";
private static final String TYPE_CLASS = "CLASS";
private static final String TYPE_FIELD = "FIELD";
Expand Down Expand Up @@ -126,14 +126,15 @@ public static DexKitBridge getDexKitBridge() {
private void versionCheck() {
String versionName = Helpers.getPackageVersionName(loadPackageParam);
String versionCode = Integer.toString(Helpers.getPackageVersionCode(loadPackageParam));
String nameFile = getFile("versionName"),
codeFile = getFile("versionCode"),
dexkitVersion = getFile("cacheVersion");
String nameFile = getFile("versionName");
String codeFile = getFile("versionCode");
String dexkitVersion = getFile("cacheVersion");

boolean isMkdir = FileUtils.mkdirs(dexPath);
if (!isMkdir) {
if (!FileUtils.mkdirs(dexPath)) {
isMkdir = false;
XposedLogUtils.logE(callTAG, "failed to create mkdirs: " + dexPath + " cant use dexkit cache!!");
return;
} else {
isMkdir = true;
}

boolean isDexkitVersionTouched = FileUtils.touch(dexkitVersion);
Expand All @@ -156,8 +157,8 @@ private void versionCheck() {
return;
}

String verName = FileUtils.read(nameFile),
codeName = FileUtils.read(codeFile);
String verName = FileUtils.read(nameFile);
String codeName = FileUtils.read(codeFile);
if (needToUpdateVersionFiles(verName, codeName, versionName, versionCode)) {
writeVersionFiles(nameFile, codeFile, versionName, versionCode);
clearCache(dexPath);
Expand Down Expand Up @@ -269,32 +270,32 @@ private static List<AnnotatedElement> getDexKitBridge(@NotNull String tag, boole
callTAG = getCallName(Thread.currentThread().getStackTrace());
DexKitBridge dexKitBridge = getDexKitBridge();
String dexFile = getFile(callTAG);
if (noCache)
return getElement(dexKitBridge, iDexKit, iDexKitList);
if (!isMkdir)
return getElement(dexKitBridge, iDexKit, iDexKitList);
if (!touchIfNeed(dexFile))

if (noCache || !isMkdir || !touchIfNeed(dexFile)) {
return getElement(dexKitBridge, iDexKit, iDexKitList);
}

return run(tag, dexFile, dexKitBridge, dexKit.loadPackageParam.classLoader, iDexKit, iDexKitList);
}

// 执行缓存或读取
private static List<AnnotatedElement> run(@NonNull String tag, String dexFile, DexKitBridge dexKitBridge,
ClassLoader classLoader, IDexKit iDexKit, IDexKitList iDexKitList) {
ArrayList<DexKitData> cacheData = getCacheMapOrReadFile(dexFile);
if (!haveCache(tag, cacheData))
if (!haveCache(tag, cacheData)) {
return getElementAndWriteCache(tag, iDexKit, iDexKitList, dexKitBridge, cacheData, dexFile);
else
} else {
return getFileCache(tag, classLoader, cacheData);
}
}

// 获取结果并写入缓存
private static List<AnnotatedElement> getElementAndWriteCache(String tag, IDexKit iDexKit, IDexKitList iDexKitList,
DexKitBridge dexKitBridge, ArrayList<DexKitData> dadaList, String dexFile) {
DexKitBridge dexKitBridge, ArrayList<DexKitData> cacheDataList, String dexFile) {
ArrayList<AnnotatedElement> elements = new ArrayList<>(getElement(dexKitBridge, iDexKit, iDexKitList));
dadaList.addAll(createJsonList(tag, elements));
FileUtils.write(dexFile, gson.toJson(dadaList));
cacheMap.put(dexFile, dadaList);
cacheDataList.addAll(createJsonList(tag, elements));
FileUtils.write(dexFile, gson.toJson(cacheDataList));
cacheMap.put(dexFile, cacheDataList);
return elements;
}

Expand Down Expand Up @@ -423,7 +424,7 @@ private static String getCallName(StackTraceElement[] stackTrace) {
private static Class<?> getClass(@Nullable String name, ClassLoader classLoader) {
if (name == null) throwRuntime("str is null, cant get class!!");
try {
Class<?> c = null;
Class<?> c;
String old = name;
name = name.replace("[", "");
int i = old.length() - name.length();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ object NotificationWeather : BaseHook() {
} else {
oldNotificationWeather()
}

loadClass("com.android.systemui.qs.MiuiNotificationHeaderView").methodFinder()
.filterByName("updateLayout")
.single().createHook {
after {
val viewGroup = it.thisObject as ViewGroup
val mOrientation = viewGroup.getObjectField("mOrientation") as Int

mWeatherView?.visibility = if (mOrientation == 1) {
View.VISIBLE
} else {
View.GONE
}
}
}
}

private fun newNotificationWeather() {
Expand Down Expand Up @@ -163,21 +178,6 @@ object NotificationWeather : BaseHook() {
setWeatherViewOnClinkListener(context)
}
}

loadClass("com.android.systemui.qs.MiuiNotificationHeaderView").methodFinder()
.filterByName("updateLayout")
.single().createHook {
after {
val viewGroup = it.thisObject as ViewGroup
val mOrientation = viewGroup.getObjectField("mOrientation") as Int

mWeatherView?.visibility = if (mOrientation == 1) {
View.VISIBLE
} else {
View.GONE
}
}
}
}

private fun addWeatherViewAfterOf(dateTimeView : View) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

package com.sevtinge.hyperceiler.module.hook.systemui.statusbar.model

import android.annotation.*
import android.graphics.*
import android.telephony.*
import android.view.*
import android.widget.*
import com.github.kyuubiran.ezxhelper.*
import com.github.kyuubiran.ezxhelper.ClassUtils.loadClass
import com.github.kyuubiran.ezxhelper.HookFactory.`-Static`.createHook
import com.github.kyuubiran.ezxhelper.finders.MethodFinder.`-Static`.methodFinder
Expand All @@ -45,6 +47,8 @@ import com.sevtinge.hyperceiler.module.hook.systemui.statusbar.model.public.Mobi
import com.sevtinge.hyperceiler.module.hook.systemui.statusbar.model.public.MobilePrefs.verticalOffset
import com.sevtinge.hyperceiler.utils.*
import com.sevtinge.hyperceiler.utils.StateFlowHelper.newReadonlyStateFlow
import com.sevtinge.hyperceiler.utils.api.ProjectApi.*
import com.sevtinge.hyperceiler.utils.devicesdk.*
import com.sevtinge.hyperceiler.utils.devicesdk.DisplayUtils.*
import java.lang.reflect.*
import java.util.function.*
Expand All @@ -59,7 +63,6 @@ object MobileTypeSingle2Hook : BaseHook() {
private var get1: Int = 0
private var get2: Int = 0
private val simDataConnected = booleanArrayOf(false, false)
private val mobileSignalViewMap = HashMap<Int, MutableSet<View>>()

override fun init() {
if (mobileNetworkType != 0) {
Expand All @@ -76,6 +79,7 @@ object MobileTypeSingle2Hook : BaseHook() {
MutableCollection::class.java,
View::class.java
)

try {
method2 = DarkIconDispatcherClass.getMethod(
"getTint",
Expand Down Expand Up @@ -118,11 +122,6 @@ object MobileTypeSingle2Hook : BaseHook() {
val textView: TextView =
getView.findViewByIdName("mobile_type_single") as TextView

// 切换深色模式时请调用此逻辑,否则无法即时更新
if ((!hideIndicator && (showMobileType || mobileNetworkType == 3)) || mobileNetworkType == 4) {
setOnDataChangedListener()
}

if (getBoolean) {
method2?.invoke(null, it.args[0], textView, num)?.let { it1 ->
textView.setTextColor(it1.hashCode())
Expand Down Expand Up @@ -151,26 +150,19 @@ object MobileTypeSingle2Hook : BaseHook() {
.filterByParamCount(5)
.single().createHook {
after { param ->
// logI(TAG, lpparam.packageName, "${param.args.contentToString()}")
val viewModel = param.args[4]
val rootView = param.result as ViewGroup
val subId = rootView.getIntField("subId")

val mobileGroup = rootView.findViewByIdName("mobile_group") as LinearLayout
val mobileGroupParent = mobileGroup.parent as ViewGroup
val containerLeft =
mobileGroup.findViewByIdName("mobile_container_left") as ViewGroup
val containerRight =
mobileGroup.findViewByIdName("mobile_container_right") as ViewGroup
val mobileType = containerLeft.findViewByIdName("mobile_type") as? ImageView?

if (mobileSignalViewMap[subId] == null) {
mobileSignalViewMap[subId] = mutableSetOf()
}
mobileSignalViewMap[subId]?.add(mobileGroupParent)

// 添加大 5G 并设置样式
if (showMobileType) {
val mobileType = containerLeft.findViewByIdName("mobile_type") as? ImageView?
val textView =
mobileGroup.findViewByIdName("mobile_type_single") as TextView
if (!getLocation) {
Expand Down Expand Up @@ -199,7 +191,7 @@ object MobileTypeSingle2Hook : BaseHook() {
// 调整初始样式
val dataConnected = simDataConnected[SubscriptionManager.getSlotIndex(subId)]
if (mobileNetworkType == 3 || mobileNetworkType == 4 || showMobileType) {
val paddingLeft = if (dataConnected && !(showMobileType || hideIndicator)) {
val paddingLeft = if (dataConnected && !(showMobileType && hideIndicator)) {
0
} else {
20
Expand Down Expand Up @@ -261,6 +253,7 @@ object MobileTypeSingle2Hook : BaseHook() {
}
}

@SuppressLint("NewApi")
private fun setOnDataChangedListener() {
val javaAdapter = Dependency.mMiuiLegacyDependency
?.getObjectField("mCentralSurfaces")
Expand All @@ -280,8 +273,9 @@ object MobileTypeSingle2Hook : BaseHook() {
"alwaysCollectFlow",
dataConnected,
Consumer<BooleanArray> {
if (isDebug()) logD(TAG, lpparam.packageName, "MobileDataConnected -> ${it.contentToString()}")

val simCount = it.size
logI(TAG, lpparam.packageName, "${it.contentToString()}")
val isNoDataConnected = when (simCount) {
1 -> {
simDataConnected[0] = it[0]
Expand All @@ -300,42 +294,41 @@ object MobileTypeSingle2Hook : BaseHook() {
false
}
}
val subId = SubscriptionManager.getDefaultDataSubscriptionId()
mobileSignalViewMap[subId]?.forEach { view ->
val containerLeft = view.findViewByIdName("mobile_container_left") as ViewGroup
val containerRight =
view.findViewByIdName("mobile_container_right") as ViewGroup
SubscriptionManagerProvider(EzXHelper.appContext).getActiveSubscriptionIdList(true)
.forEach { subId ->
getMobileViewBySubId(subId) { view ->
val containerLeft =
view.findViewByIdName("mobile_container_left") as ViewGroup
val containerRight =
view.findViewByIdName("mobile_container_right") as ViewGroup

if (!showMobileType && mobileNetworkType == 4) {
val mobileType = view.findViewByIdName("mobile_type") as ImageView
mobileType.visibility = if (isNoDataConnected || showMobileType) {
View.GONE
} else {
View.VISIBLE
}
}
val paddingLeft = if (isNoDataConnected || (showMobileType && hideIndicator)) {
20
} else {
0
}
containerLeft.setPadding(paddingLeft, 0, 0, 0)
containerRight.setPadding(paddingLeft, 0, 0, 0)
}
if (mobileSignalViewMap.size == simCount && !isEnableDouble) {
mobileSignalViewMap[(mobileSignalViewMap.keys - subId).single()]?.forEach { view ->
val containerLeft =
view.findViewByIdName("mobile_container_left") as ViewGroup
val containerRight =
view.findViewByIdName("mobile_container_right") as ViewGroup
if (!showMobileType && mobileNetworkType == 4) {
val mobileType = view.findViewByIdName("mobile_type") as ImageView
mobileType.visibility = View.GONE
val b = (!showMobileType && mobileNetworkType == 4)
if (subId == SubscriptionManager.getDefaultDataSubscriptionId()) {
if (b) {
val mobileType = view.findViewByIdName("mobile_type") as ImageView
mobileType.visibility = if (isNoDataConnected || showMobileType) {
View.GONE
} else {
View.VISIBLE
}
}
val paddingLeft = if (isNoDataConnected || (showMobileType && hideIndicator)) {
20
} else {
0
}
containerLeft.setPadding(paddingLeft, 0, 0, 0)
containerRight.setPadding(paddingLeft, 0, 0, 0)
} else if (!isEnableDouble) {
if (b) {
val mobileType = view.findViewByIdName("mobile_type") as ImageView
mobileType.visibility = View.GONE
}
containerLeft.setPadding(20, 0, 0, 0)
containerRight.setPadding(20, 0, 0, 0)
}
}
containerLeft.setPadding(20, 0, 0, 0)
containerRight.setPadding(20, 0, 0, 0)
}
}
}
)
}
Expand All @@ -356,10 +349,37 @@ object MobileTypeSingle2Hook : BaseHook() {
}

private fun setViewVisibility(getId: String, visibility: Int) {
mobileSignalViewMap.forEach { (_, v) ->
v.forEach {
val mMobileType = it.findViewByIdName(getId) as View
mMobileType.visibility = visibility
SubscriptionManagerProvider(EzXHelper.appContext).getActiveSubscriptionIdList(true)
.forEach { subId ->
getMobileViewBySubId(subId) { view: View ->
val mMobileType = view.findViewByIdName(getId) as View
mMobileType.visibility = visibility
}
}
}

private fun getMobileViewBySubId(subId: Int, callback: (View) -> Unit) {
val statusBarIconController = Dependency.mMiuiLegacyDependency
?.getObjectField("mStatusBarIconController")
?.callMethod("get")

if (statusBarIconController == null) {
return
}

val iconGroups = statusBarIconController.getObjectFieldAs<Map<Any, *>>("mIconGroups")
val iconList = statusBarIconController.getObjectFieldAs<Any>("mStatusBarIconList")

val viewIndex = iconList.callMethodAs<Int>("getViewIndex", subId, "mobile")

iconGroups.forEach { (iconManager, _) ->
val child = iconManager.getObjectFieldAs<ViewGroup>("mGroup").getChildAt(viewIndex)

if (child is View &&
"ModernStatusBarMobileView" == child::class.java.simpleName &&
"mobile" == child.getObjectField("slot")
) {
callback(child)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.sevtinge.hyperceiler.utils.devicesdk;

import android.content.Context;

import com.sevtinge.hyperceiler.utils.InvokeUtils;

public class SubscriptionManagerProvider {
private static final String CLASS = "android.telephony.SubscriptionManager";

private final Object subscriptionManager;

public SubscriptionManagerProvider(Context context) {
subscriptionManager = context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
}

public int[] getActiveSubscriptionIdList(boolean visibleOnly) {
return InvokeUtils.callMethod(CLASS, subscriptionManager, "getActiveSubscriptionIdList", new Class[]{boolean.class}, visibleOnly);
}
}

0 comments on commit be515fe

Please sign in to comment.