Skip to content

Commit d28506e

Browse files
committed
opt codes && fix some error (#1464)
- opt reshook - opt new XposedSharedPrefs load - opt dexkit check - fix ui error - fix dual-row signal load failed on Android 15
1 parent b8902a5 commit d28506e

9 files changed

Lines changed: 92 additions & 75 deletions

File tree

app/src/main/java/com/sevtinge/hyperceiler/main/page/main/HomeFragment.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,15 @@ private void processPreferenceHeader(String key, String summary, SharedPreferenc
132132
private void setIconAndTitle(PreferenceHeader header, String packageName) {
133133
if (header == null || packageName == null) return;
134134
PackageManager pm = requireContext().getPackageManager();
135+
136+
try {
137+
pm.getPackageInfo(packageName, 0);
138+
} catch (PackageManager.NameNotFoundException e) {
139+
return;
140+
}
141+
135142
ApplicationInfo appInfo = AppInfoCache.getInstance(getContext()).getAppInfo(packageName);
136-
if (appInfo == null || pm == null) return;
143+
if (appInfo == null) return;
137144

138145
mAppsList.setVisible(false);
139146
Runnable loadAndApply = () -> {

app/src/main/java/com/sevtinge/hyperceiler/main/page/settings/helper/HomepageEntrance.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,17 @@ private void processSwitchPreferenceHeader(String key, String summary) {
105105

106106
private void setIconAndTitle(SwitchPreference header, String packageName) {
107107
if (header == null || packageName == null) return;
108-
// 根据包名获取
109108
PackageManager pm = requireContext().getPackageManager();
109+
110+
try {
111+
pm.getPackageInfo(packageName, 0);
112+
} catch (PackageManager.NameNotFoundException e) {
113+
return;
114+
}
115+
110116
ApplicationInfo appInfo = AppInfoCache.getInstance(getContext()).getAppInfo(packageName);
111117
if (appInfo == null) return;
112118

113-
// 将耗时的 loadIcon/loadLabel 移到后台线程,避免阻塞 UI 线程
114119
if (Looper.myLooper() == Looper.getMainLooper()) {
115120
new Thread(() -> {
116121
final Drawable icon = appInfo.loadIcon(pm);

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ core = "1.17.0"
99
coreKtx = "1.17.0"
1010
fragment = "1.8.9"
1111
lunarcalendar = "latest.release"
12-
miuix = "1.0.10.4"
12+
miuix = "1.0.10.5"
1313
expansions = "1.0.0"
1414
recyclerview = "1.4.0"
1515
coordinatorlayout = "1.3.0"

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/XposedInit.java

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import com.sevtinge.hyperceiler.hook.utils.prefs.PrefsUtils;
4848
import com.sevtinge.hyperceiler.module.base.DataBase;
4949

50-
import java.io.File;
5150
import java.lang.reflect.InvocationTargetException;
5251
import java.util.HashMap;
5352
import java.util.Map;
@@ -72,7 +71,7 @@ public class XposedInit implements IXposedHookZygoteInit, IXposedHookLoadPackage
7271
public final VariousThirdApps mVariousThirdApps = new VariousThirdApps();
7372

7473
@Override
75-
public void initZygote(StartupParam startupParam) throws Throwable {
74+
public void initZygote(StartupParam startupParam) {
7675
// load New XSPrefs
7776
setXSharedPrefs();
7877
if (!mPrefsMap.getBoolean("allow_hook")) return;
@@ -143,34 +142,37 @@ public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Th
143142
}
144143

145144
private void setXSharedPrefs() {
146-
if (mPrefsMap.isEmpty()) {
147-
try {
148-
XSharedPreferences mXSharedPreferences = new XSharedPreferences(ProjectApi.mAppModulePkg, PrefsUtils.mPrefsName);
149-
mXSharedPreferences.makeWorldReadable();
150-
Map<String, ?> allPrefs = mXSharedPreferences.getAll();
151-
152-
if (allPrefs == null || allPrefs.isEmpty()) {
153-
mXSharedPreferences = new XSharedPreferences(new File(PrefsUtils.mPrefsFile));
145+
synchronized (this) {
146+
if (mPrefsMap.isEmpty()) {
147+
try {
148+
XSharedPreferences mXSharedPreferences = new XSharedPreferences(ProjectApi.mAppModulePkg, PrefsUtils.mPrefsName);
154149
mXSharedPreferences.makeWorldReadable();
155-
allPrefs = mXSharedPreferences.getAll();
156-
}
157150

158-
if (allPrefs != null && !allPrefs.isEmpty()) {
159-
mPrefsMap.clear();
160-
mPrefsMap.putAll(allPrefs);
161-
} else {
162-
logE("UID" + Process.myUid(), "Cannot read SharedPreferences, some mods might not work!");
151+
// 检查文件是否可读
152+
if (!mXSharedPreferences.getFile().canRead()) {
153+
logE("setXSharedPrefs", "Cannot read SharedPreferences file! File: " + mXSharedPreferences.getFile().getAbsolutePath());
154+
logE("UID" + Process.myUid(), "Cannot read SharedPreferences, some mods might not work!");
155+
return;
156+
}
157+
158+
Map<String, ?> allPrefs = mXSharedPreferences.getAll();
159+
160+
if (allPrefs != null && !allPrefs.isEmpty()) {
161+
mPrefsMap.clear();
162+
mPrefsMap.putAll(allPrefs);
163+
} else {
164+
logE("UID" + Process.myUid(), "SharedPreferences is empty, some mods might not work!");
165+
}
166+
} catch (Throwable t) {
167+
logE("setXSharedPrefs", t);
163168
}
164-
} catch (Throwable t) {
165-
logE("setXSharedPrefs", t);
166169
}
167170
}
168171
}
169172

170173
private void invokeInit(XC_LoadPackage.LoadPackageParam lpparam) {
171174
String mPkgName = lpparam.packageName;
172175
if (mPkgName == null) return;
173-
if (isOtherRestrictions(mPkgName)) return;
174176

175177
HashMap<String, DataBase> dataMap = DataBase.get();
176178
if (dataMap.values().stream().noneMatch(dataBase -> dataBase.mTargetPackage.equals(mPkgName))) {
@@ -220,18 +222,6 @@ private void androidCrashEventHook(XC_LoadPackage.LoadPackageParam lpparam) {
220222
}
221223
}
222224

223-
private boolean isOtherRestrictions(String pkg) {
224-
switch (pkg) {
225-
case "com.google.android.webview", "com.miui.contentcatcher",
226-
"com.miui.catcherpatch" -> {
227-
return true;
228-
}
229-
default -> {
230-
return false;
231-
}
232-
}
233-
}
234-
235225
public void moduleActiveHook(XC_LoadPackage.LoadPackageParam lpparam) {
236226
Class<?> AppsTool = XposedHelpers.findClassIfExists(ProjectApi.mAppModulePkg + ".utils.XposedActivateHelper", lpparam.classLoader);
237227

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/module/base/dexkit/DexKit.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
public class DexKit {
6565
private static String TAG = "DexKit";
6666
private static volatile boolean isInit = false;
67-
private static final int mVersion = 5;
67+
private static final int mVersion = 6;
6868
private static final String MMKV_PATH = "/files/hyperceiler/mmkv";
6969
private static XC_LoadPackage.LoadPackageParam mParam;
7070
private static final String TYPE_METHOD = "METHOD";
@@ -108,8 +108,8 @@ public static synchronized DexKitBridge initDexkitBridge() {
108108
boolean hasPkgVersion = !Objects.equals(pkgVersionName, "null") && pkgVersionCode != -1;
109109
String pkgVersion = hasPkgVersion ? pkgVersionName + "(" + pkgVersionCode + ")" : null;
110110

111-
if (mMMKV.containsKey("version")) {
112-
int version = Integer.parseInt(mMMKV.getString("version", "0"));
111+
if (mMMKV.containsKey(mParam.packageName + "_version")) {
112+
int version = Integer.parseInt(mMMKV.getString(mParam.packageName + "_version", "0"));
113113
if (version != mVersion) {
114114
XposedLogUtils.logD(TAG, "DexKit version changed, clear all cache: " + version + " -> " + mVersion);
115115
needClear = true;
@@ -146,7 +146,7 @@ public static synchronized DexKitBridge initDexkitBridge() {
146146
}
147147

148148
// 保证必要键存在并写入最新值(覆盖写入可保持一致性)
149-
mMMKV.putString("version", String.valueOf(mVersion));
149+
mMMKV.putString(mParam.packageName + "_version", String.valueOf(mVersion));
150150
if (hasPkgVersion) {
151151
mMMKV.putString("pkgVersion", pkgVersion);
152152
}

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/module/base/tool/AppsTool.java

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
package com.sevtinge.hyperceiler.hook.module.base.tool;
2020

2121
import static com.sevtinge.hyperceiler.hook.utils.log.XposedLogUtils.logE;
22-
import static com.sevtinge.hyperceiler.hook.utils.log.XposedLogUtils.logI;
22+
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
2323

2424
import android.annotation.SuppressLint;
2525
import android.app.backup.BackupManager;
@@ -115,29 +115,24 @@ public static void fixPermissionsAsync(Context context) {
115115
executor.execute(() -> {
116116
try {
117117
Thread.sleep(500);
118-
} catch (Throwable ignore) {
119-
}
120-
File pkgFolder = context.getDataDir();
121-
if (pkgFolder.exists()) {
122-
pkgFolder.setExecutable(true, false);
123-
pkgFolder.setReadable(true, false);
124-
pkgFolder.setWritable(true, false);
125-
}
126-
File sharedPrefsFolder = new File(PrefsUtils.getSharedPrefsPath());
127-
if (sharedPrefsFolder.exists()) {
128-
sharedPrefsFolder.setExecutable(true, false);
129-
sharedPrefsFolder.setReadable(true, false);
130-
sharedPrefsFolder.setWritable(true, false);
131-
}
132-
File sharedPrefsFile = new File(PrefsUtils.getSharedPrefsFile());
133-
if (sharedPrefsFile.exists()) {
134-
sharedPrefsFile.setReadable(true, false);
135-
sharedPrefsFile.setExecutable(true, false);
136-
sharedPrefsFile.setWritable(true, false);
118+
} catch (InterruptedException e) {
119+
Thread.currentThread().interrupt();
137120
}
121+
122+
setFilePermissions(context.getDataDir());
123+
setFilePermissions(new File(PrefsUtils.getSharedPrefsPath()));
124+
setFilePermissions(new File(PrefsUtils.getSharedPrefsFile()));
138125
});
139126
}
140127

128+
private static void setFilePermissions(File file) {
129+
if (file != null && file.exists()) {
130+
file.setExecutable(true, false);
131+
file.setReadable(true, false);
132+
file.setWritable(true, false);
133+
}
134+
}
135+
141136
public static void registerFileObserver(Context context) {
142137
try {
143138
FileObserver mFileObserver = new FileObserver(new File(PrefsUtils.getSharedPrefsPath()), FileObserver.CLOSE_WRITE) {
@@ -192,7 +187,7 @@ public static String getPackageVersionName(XC_LoadPackage.LoadPackageParam lppar
192187
Object parser = parserCls.getDeclaredConstructor().newInstance();
193188
File apkPath = new File(lpparam.appInfo.sourceDir);
194189
if (apkPath.toString().contains("com.miui.securecenter")) {
195-
XposedHelpers.findAndHookMethod(parserCls, "setMaxAspectRatio", float.class, new XC_MethodHook() {
190+
findAndHookMethod(parserCls, "setMaxAspectRatio", float.class, new XC_MethodHook() {
196191
@Override
197192
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
198193
Object arg0 = param.args[0];

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/module/base/tool/ResourcesTool.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@
5656
*/
5757
public class ResourcesTool {
5858
private static final String TAG = "ResourcesTool";
59-
private static ResourcesTool sInstance = null;
59+
private static volatile ResourcesTool sInstance = null;
6060

6161
private final String mModulePath;
62-
private boolean hooksApplied = false;
63-
private boolean isInit = false;
62+
private volatile boolean hooksApplied = false;
63+
private volatile boolean isInit = false;
6464
private Handler mHandler = null;
6565
private volatile ResourcesLoader resourcesLoader;
6666

@@ -96,9 +96,13 @@ private ResourcesTool(String modulePath) {
9696
/**
9797
* 获取单例实例,首次调用时必须提供模块路径
9898
*/
99-
public static synchronized ResourcesTool getInstance(String modulePath) {
99+
public static ResourcesTool getInstance(String modulePath) {
100100
if (sInstance == null) {
101-
sInstance = new ResourcesTool(modulePath);
101+
synchronized (ResourcesTool.class) {
102+
if (sInstance == null) {
103+
sInstance = new ResourcesTool(modulePath);
104+
}
105+
}
102106
}
103107
return sInstance;
104108
}
@@ -311,9 +315,12 @@ protected void before(MethodHookParam param) {
311315
@Override
312316
protected void before(MethodHookParam param) {
313317
if (resourcesArrayList.isEmpty()) {
314-
Resources resources = loadModuleRes(ContextUtils.getContextNoError(ContextUtils.FLAG_CURRENT_APP));
315-
if (resources != null) {
316-
resourcesArrayList.add(resources); // 重新加载 res
318+
Context context = ContextUtils.getContextNoError(ContextUtils.FLAG_CURRENT_APP);
319+
if (context != null) {
320+
Resources resources = loadModuleRes(context);
321+
if (resources != null) {
322+
resourcesArrayList.add(resources); // 重新加载 res
323+
}
317324
}
318325
}
319326
int reqId = (int) param.args[0];

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/module/rules/systemui/statusbar/model/MobilePublicHookV.kt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,25 @@ package com.sevtinge.hyperceiler.hook.module.rules.systemui.statusbar.model
2020

2121
import android.telephony.SubscriptionManager
2222
import com.sevtinge.hyperceiler.hook.module.base.BaseHook
23+
import com.sevtinge.hyperceiler.hook.module.rules.systemui.base.api.Dependency
24+
import com.sevtinge.hyperceiler.hook.module.rules.systemui.base.api.MiuiStub
2325
import com.sevtinge.hyperceiler.hook.module.rules.systemui.base.statusbar.icon.MobileClass.miuiCellularIconVM
2426
import com.sevtinge.hyperceiler.hook.module.rules.systemui.base.statusbar.icon.MobilePrefs.card1
2527
import com.sevtinge.hyperceiler.hook.module.rules.systemui.base.statusbar.icon.MobilePrefs.card2
2628
import com.sevtinge.hyperceiler.hook.module.rules.systemui.base.statusbar.icon.MobilePrefs.hideIndicator
2729
import com.sevtinge.hyperceiler.hook.module.rules.systemui.base.statusbar.icon.MobilePrefs.hideRoaming
30+
import com.sevtinge.hyperceiler.hook.module.rules.systemui.base.statusbar.icon.MobilePrefs.isEnableDouble
2831
import com.sevtinge.hyperceiler.hook.utils.MethodHookParam
2932
import com.sevtinge.hyperceiler.hook.utils.StateFlowHelper.newReadonlyStateFlow
33+
import com.sevtinge.hyperceiler.hook.utils.StateFlowHelper.setStateFlowValue
34+
import com.sevtinge.hyperceiler.hook.utils.callMethod
3035
import com.sevtinge.hyperceiler.hook.utils.devicesdk.isMoreAndroidVersion
3136
import com.sevtinge.hyperceiler.hook.utils.devicesdk.isMoreSmallVersion
37+
import com.sevtinge.hyperceiler.hook.utils.getObjectField
3238
import com.sevtinge.hyperceiler.hook.utils.getObjectFieldAs
3339
import com.sevtinge.hyperceiler.hook.utils.setObjectField
3440
import io.github.kyuubiran.ezxhelper.core.util.ClassUtil.loadClass
41+
import java.util.function.Consumer
3542

3643
class MobilePublicHookV : BaseHook() {
3744
override fun init() {
@@ -46,15 +53,16 @@ class MobilePublicHookV : BaseHook() {
4653
val subId = mobileIconInteractor.getObjectFieldAs<Int>("subId")
4754

4855
// 双排信号
49-
/*if (isEnableDouble) {
56+
if (isEnableDouble && !isMoreAndroidVersion(36)) {
5057
val isVisible = if (isMoreAndroidVersion(36)) {
5158
val pair = loadClass("kotlin.Pair")
5259
.getConstructor(Object::class.java, Object::class.java)
5360
.newInstance(false, false)
54-
cellularIcon.setObjectField("isVisible", newReadonlyStateFlow(pair))
61+
newReadonlyStateFlow(pair)
5562
} else {
56-
cellularIcon.setObjectField("isVisible", newReadonlyStateFlow(false))
63+
newReadonlyStateFlow(false)
5764
}
65+
cellularIcon.setObjectField("isVisible", isVisible)
5866
if (!hideRoaming) {
5967
cellularIcon.setObjectField("smallRoamVisible", newReadonlyStateFlow(false))
6068
}
@@ -72,7 +80,7 @@ class MobilePublicHookV : BaseHook() {
7280
}
7381
)
7482
}
75-
} else {*/
83+
} else {
7684
val getSlotIndex = SubscriptionManager.getSlotIndex(subId)
7785
if ((card1 && getSlotIndex == 0) || (card2 && getSlotIndex == 1)) {
7886
if (isMoreAndroidVersion(36)) {
@@ -84,7 +92,7 @@ class MobilePublicHookV : BaseHook() {
8492
cellularIcon.setObjectField("isVisible", newReadonlyStateFlow(false))
8593
}
8694
}
87-
/*}*/
95+
}
8896

8997
if (hideIndicator) {
9098
cellularIcon.setObjectField("inOutVisible", newReadonlyStateFlow(false))

library/hook/src/main/java/com/sevtinge/hyperceiler/hook/utils/pkg/CheckModifyUtils.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ object CheckModifyUtils {
6767

6868
val signatures = try {
6969
val pm = context.packageManager
70-
val pi = pm.getPackageArchiveInfo(apkFilePath, PackageManager.GET_SIGNING_CERTIFICATES)
70+
val pi = try {
71+
pm.getPackageArchiveInfo(apkFilePath, PackageManager.GET_SIGNING_CERTIFICATES)
72+
} catch (_: ClassCastException) {
73+
// 忽略某些 APK 解析时的系统内部错误
74+
null
75+
}
7176
// 某些 Android 版本需要设置以下两项以正确解析签名
7277
pi?.applicationInfo?.sourceDir = apkFilePath
7378
pi?.applicationInfo?.publicSourceDir = apkFilePath

0 commit comments

Comments
 (0)