Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修复移动数据的重复监听 #1016

Merged
merged 10 commits into from
Dec 3, 2024
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);
}
}
Loading