diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 759e517dba6..f09dae4e94e 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -1,7 +1,6 @@
name: Bug report/反馈 Bug
description: Report errors or unexpected behavior./反馈错误或异常行为。
labels: [bug]
-title: "[Bug] "
body:
- type: markdown
attributes:
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index 92f5c21e173..b21432d17be 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -2,7 +2,6 @@
name: Feature request/新特性请求
description: Suggest an idea./提出建议
labels: [enhancement]
-title: "[Feature Request] "
body:
- type: textarea
attributes:
diff --git a/.gitmodules b/.gitmodules
index 9dc2c72534e..10165e6a0ac 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,3 @@
-[submodule "external/cxx"]
- path = external/cxx
- url = https://github.com/LSPosed/libcxx.git
[submodule "external/lsplant"]
path = external/lsplant
url = https://github.com/LSPosed/LSPlant.git
@@ -10,3 +7,6 @@
[submodule "external/fmt"]
path = external/fmt
url = https://github.com/fmtlib/fmt.git
+[submodule "external/cxx"]
+ path = external/cxx
+ url = https://github.com/topjohnwu/libcxx.git
diff --git a/README.md b/README.md
index 01c5fcdf960..9f9c44e6228 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ A Riru / Zygisk module trying to provide an ART hooking framework which delivers
## Supported Versions
-Android 8.1 ~ 13
+Android 8.1 ~ 14
## Install
diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/HomeFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/HomeFragment.java
index 579fdfea9d1..64b2acf3254 100644
--- a/app/src/main/java/org/lsposed/manager/ui/fragment/HomeFragment.java
+++ b/app/src/main/java/org/lsposed/manager/ui/fragment/HomeFragment.java
@@ -23,6 +23,9 @@
import android.app.Dialog;
import android.os.Build;
import android.os.Bundle;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -51,8 +54,12 @@
import org.lsposed.manager.util.UpdateUtil;
import org.lsposed.manager.util.chrome.LinkTransformationMethod;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
import rikka.core.util.ClipboardUtils;
import rikka.material.app.LocaleDelegate;
@@ -146,6 +153,7 @@ private void updateStates(Activity activity, boolean binderAlive, boolean needUp
}
binding.statusSummary.setText(String.format(LocaleDelegate.getDefaultLocale(), "%s (%d) - %s",
ConfigManager.getXposedVersionName(), ConfigManager.getXposedVersionCode(), ConfigManager.getApi()));
+ binding.developerWarningCard.setVisibility(isDeveloper() ? View.VISIBLE : View.GONE);
} else {
boolean isMagiskInstalled = ConfigManager.isMagiskInstalled();
if (isMagiskInstalled) {
@@ -254,6 +262,27 @@ private String getDevice() {
return manufacturer;
}
+ private boolean isDeveloper() {
+ var developer = new AtomicBoolean(false);
+ var pids = Paths.get("/data/local/tmp/.studio/ipids");
+ try (var dir = Files.list(pids)) {
+ dir.findFirst().ifPresent(name -> {
+ var pid = Integer.parseInt(name.getFileName().toString());
+ try {
+ Os.kill(pid, 0);
+ developer.set(true);
+ } catch (ErrnoException e) {
+ if (e.errno != OsConstants.ESRCH) {
+ developer.set(true);
+ }
+ }
+ });
+ } catch (IOException e) {
+ return false;
+ }
+ return developer.get();
+ }
+
public static class AboutDialog extends DialogFragment {
@NonNull
@Override
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index 652bc07fbe2..09fe189b984 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -215,6 +215,38 @@
+
+
+
+
+
+
+
+
+
+
+
يرجى تثبيت أحدث إصدار من LSPosed
إصدار API
إصدار إطار العمل
- اسم حزمة المدير
+ Lاسم حزمة المديرo
إصدار النظام
الجهاز
نظام ABI
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index ae39fc93f61..9569e2424fa 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -55,6 +55,8 @@ JJ108
Module können gelegentlich außer Kraft gesetzt werden.]]>
Aktualisierung erforderlich
Bitte installieren Sie die neueste Version von LSPosed
+ Tipps für Modulentwickler
+ Bitte deaktiviere Deploy-Optimierungen in Android Studio oder benutze den `gradlew installDebug` Befehl zum Installieren. Andernfalls wird die Modul-Apk nicht aktualisiert.
API Version
Framework Version
Name des Managerpakets
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index 4840cd0192b..2cb42fa635a 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -25,7 +25,7 @@
- %d ماژول فعال شده
- %d ماژول فعال شده
- سیاهه
+ گزارش ها
تنظیمات
بازخورد یا پیشنهاد
درباره
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index ef44a0f64f8..b81c7c0e836 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -20,7 +20,7 @@
Aperçu
- Module
+ Modules
- %d module actif
- %d modules actifs
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 26262ed12ea..206a4e4ca55 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -64,7 +64,7 @@
Didukung
Tidak didukung
Versi Android tidak tersedia
- Crash
+ Rusak
Mount gagal
SELinux permisif
SELinux policy salah
@@ -75,7 +75,7 @@
Selamat datang di LSPosed
Anda menggunakan manajer parasit, yang dapat membuat pintasan atau dapat terbuka dari notifikasi.
Anda menggunakan manajer parasit, yang dapat dibuka dari notifikasi.
- Buat shortcut
+ Buat pintasan
Jangan pernah tampilkan
Manajer Parasit Direkomendasikan
LSPosed sekarang mendukung parasitisasi sistem untuk menghindari deteksi, Anda dapat membuka manajer parasit dari pemberitahuan. Disarankan untuk menghapus aplikasi saat ini.
@@ -83,7 +83,7 @@
Simpan
Log Verbose
Log Modul
- Saving log, please wait
+ Menyimpan log, harap tunggu
Log disimpan
Gagal menyimpan:\n%s
Hapus log sekarang
@@ -134,7 +134,7 @@
Anda tidak memilih aplikasi apa pun. Lanjutkan?
Permainan
Modul
- Denylist
+ Daftar penolakan
Gagal menyimpan ke daftar cakupan
Versi: %1$s
Direkomendasikan
@@ -154,8 +154,8 @@
Mulai ulang diperlukan agar perubahan ini dapat diterapkan
Mulai ulang
Sembunyikan
- %s berada di denylist. Ini mungkin tidak akan berpengaruh.
- Berada di denylist
+ %s ada dalam daftar penolakan. Ini mungkin tidak berpengaruh.
+ Berada di daftar tolak
Lihat di aplikasi lain
Informasi aplikasi
@@ -200,7 +200,7 @@
Proteksi panggilan API Xposed
Blokir kode modul yang dimuat secara dinamis untuk menggunakan Xposed API, ini mungkin mengganggu beberapa modul namun lebih aman
- Readme
+ Baca aku
Rilis
Informasi
Beranda
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 4b41bcb5a41..db1e8c9911c 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -54,9 +54,11 @@
In alcuni casi i moduli potrebbero non funzionare.]]>
Aggiornamento richiesto
Installa la versione più recente di LSPosed
+ Suggerimenti per lo sviluppatore del modulo
+ Disattivare le ottimizzazioni di distribuzione su Android Studio, o utilizzare il comando `gradlew installDebug` per eseguire l\'installazione. Altrimenti l\'apk del modulo non verrà aggiornato.
Versione API
Versione del framework
- Nome del pacchetto manager
+ Nome pacchetto del manager
Versione del sistema
Dispositivo
ABI del sistema
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 6668f1e8833..59be53f2fb9 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -52,6 +52,8 @@
모듈은 가끔 무효화될 수 있습니다.]]>
업데이트가 필요합니다
최신 버전으로 LSPosed를 설치해 주세요
+ 모듈 개발자를 위한 팁
+ Android Studio 에서 배포 최적화를 비활성화 하거나, 설치할때 \'gradlew installDebug\' 명령어를 사용해주세요. 그렇지 않으면 모듈 APK 가 업데이트되지 않을 것입니다.
API 버전
Framework 버전
관리자 패키지 이름
diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml
index 7642672a5a4..dcf58d61d22 100644
--- a/app/src/main/res/values-ku/strings.xml
+++ b/app/src/main/res/values-ku/strings.xml
@@ -26,7 +26,7 @@
- %d مۆدیول چالاک کراوە
لۆگەکان
- رێکخستن
+ ڕێکخستنەکان
فیدباک یان پێشنیار
دەربارە
پرسی ڕاپۆرت
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 7cc77af4d05..56c7af64031 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -56,7 +56,7 @@
Por favor, instale a versão mais recente do LSPosed
Versão da API
Versão do Framework
- Nome do pacote do gestor
+ Nome do pacote do gerenciador
Versão do Sistema
Aparelho
Interfaces Binárias do Sistema
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 1c101b0a2f5..1a9106ff1ec 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -36,7 +36,7 @@
Publicat la %s
Actualizat la %s
- - %d module actualizabile.
+ - %d module actualizabil
- %d module actualizabile
- %d module actualizabile.
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index db54c37cc2a..69f016313f7 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -58,6 +58,8 @@
Некоторые системные настройки нужные для работы удалены или изменены.
Модули могут не работать должным образом]]>
Требуется обновление
Установите последнюю версию LSPosed!
+ Советы разработчику модулей
+ Пожалуйста, отключите оптимизацию развертывания в Android Studio или используйте для установки команду `gradlew installDebug`. Иначе модуль не обновится
Версия API
Версия фреймворк
Имя пакета менеджера
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 78525d8b6ec..33dce858edd 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -52,6 +52,8 @@
模块可能会随机失效。]]>
需要更新
请安装新版 LSPosed
+ 给模块开发者的提示
+ 请在 Android Studio 上禁用部署优化,或使用 `gradlew installDebug` 命令进行安装,否则无法更新模块。
API 版本
框架版本
管理器包名
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 55108b26404..9b125ba6fdd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -55,6 +55,8 @@
Modules may invalidate occasionally.]]>
Need to update
Please install the latest version of LSPosed
+ Tips for module developer
+ Please disable deploy optimizations on Android Studio, or use `gradlew installDebug` command to install. Otherwise the module apk will not be updated.
API version
Framework version
Manager package name
diff --git a/build.gradle.kts b/build.gradle.kts
index e78ee814bfe..dedfc8c2373 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -70,7 +70,7 @@ val androidTargetSdkVersion by extra(34)
val androidMinSdkVersion by extra(27)
val androidBuildToolsVersion by extra("34.0.0")
val androidCompileSdkVersion by extra(34)
-val androidCompileNdkVersion by extra("25.2.9519653")
+val androidCompileNdkVersion by extra("26.0.10792818")
val androidSourceCompatibility by extra(JavaVersion.VERSION_17)
val androidTargetCompatibility by extra(JavaVersion.VERSION_17)
diff --git a/core/src/main/java/org/lsposed/lspd/core/Startup.java b/core/src/main/java/org/lsposed/lspd/core/Startup.java
index 2bd4ff7a5d0..e4d08b96d8c 100644
--- a/core/src/main/java/org/lsposed/lspd/core/Startup.java
+++ b/core/src/main/java/org/lsposed/lspd/core/Startup.java
@@ -32,13 +32,15 @@
import org.lsposed.lspd.hooker.CrashDumpHooker;
import org.lsposed.lspd.hooker.HandleSystemServerProcessHooker;
import org.lsposed.lspd.hooker.LoadedApkCtorHooker;
-import org.lsposed.lspd.hooker.LoadedApkGetCLHooker;
+import org.lsposed.lspd.hooker.LoadedApkCreateCLHooker;
import org.lsposed.lspd.hooker.OpenDexFileHooker;
import org.lsposed.lspd.impl.LSPosedContext;
import org.lsposed.lspd.impl.LSPosedHelper;
import org.lsposed.lspd.service.ILSPApplicationService;
import org.lsposed.lspd.util.Utils;
+import java.util.List;
+
import dalvik.system.DexFile;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedInit;
@@ -57,7 +59,7 @@ private static void startBootstrapHook(boolean isSystem) {
LSPosedHelper.hookConstructor(LoadedApkCtorHooker.class, LoadedApk.class,
ActivityThread.class, ApplicationInfo.class, CompatibilityInfo.class,
ClassLoader.class, boolean.class, boolean.class, boolean.class);
- LSPosedHelper.hookMethod(LoadedApkGetCLHooker.class, LoadedApk.class, "getClassLoader");
+ LSPosedHelper.hookMethod(LoadedApkCreateCLHooker.class, LoadedApk.class, "createOrUpdateClassLoaderLocked", List.class);
LSPosedHelper.hookAllMethods(AttachHooker.class, ActivityThread.class, "attach");
}
diff --git a/core/src/main/java/org/lsposed/lspd/deopt/InlinedMethodCallers.java b/core/src/main/java/org/lsposed/lspd/deopt/InlinedMethodCallers.java
index 5d46d40206f..9c0425312a7 100644
--- a/core/src/main/java/org/lsposed/lspd/deopt/InlinedMethodCallers.java
+++ b/core/src/main/java/org/lsposed/lspd/deopt/InlinedMethodCallers.java
@@ -57,6 +57,7 @@ public class InlinedMethodCallers {
// callers of Application#attach(Context)
{"android.app.Instrumentation", "newApplication", ClassLoader.class, String.class, Context.class},
{"android.app.Instrumentation", "newApplication", ClassLoader.class, Context.class},
+ {"android.app.ContextImpl", "getSharedPreferencesPath", String.class}
};
// TODO deprecate this
diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkGetCLHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java
similarity index 93%
rename from core/src/main/java/org/lsposed/lspd/hooker/LoadedApkGetCLHooker.java
rename to core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java
index f36f8644bfb..161c730eba3 100644
--- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkGetCLHooker.java
+++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCreateCLHooker.java
@@ -56,7 +56,7 @@
@SuppressLint("BlockedPrivateApi")
@XposedHooker
-public class LoadedApkGetCLHooker implements XposedInterface.Hooker {
+public class LoadedApkCreateCLHooker implements XposedInterface.Hooker {
private final static Field defaultClassLoaderField;
private final static Set loadedApks = ConcurrentHashMap.newKeySet();
@@ -81,12 +81,12 @@ static void addLoadedApk(LoadedApk loadedApk) {
public static void afterHookedMethod(XposedInterface.AfterHookCallback callback) {
LoadedApk loadedApk = (LoadedApk) callback.getThisObject();
- if (!loadedApks.contains(loadedApk)) {
+ if (callback.getArgs()[0] != null || !loadedApks.contains(loadedApk)) {
return;
}
try {
- Hookers.logD("LoadedApk#getClassLoader starts");
+ Hookers.logD("LoadedApk#createClassLoader starts");
String packageName = ActivityThread.currentPackageName();
String processName = ActivityThread.currentProcessName();
@@ -99,8 +99,8 @@ public static void afterHookedMethod(XposedInterface.AfterHookCallback callback)
}
Object mAppDir = XposedHelpers.getObjectField(loadedApk, "mAppDir");
- ClassLoader classLoader = (ClassLoader) callback.getResult();
- Hookers.logD("LoadedApk#getClassLoader ends: " + mAppDir + " -> " + classLoader);
+ ClassLoader classLoader = (ClassLoader) XposedHelpers.getObjectField(loadedApk, "mClassLoader");
+ Hookers.logD("LoadedApk#createClassLoader ends: " + mAppDir + " -> " + classLoader);
if (classLoader == null) {
return;
@@ -165,7 +165,7 @@ public boolean isFirstPackage() {
}
});
} catch (Throwable t) {
- Hookers.logE("error when hooking LoadedApk#getClassLoader", t);
+ Hookers.logE("error when hooking LoadedApk#createClassLoader", t);
} finally {
loadedApks.remove(loadedApk);
}
@@ -188,7 +188,7 @@ private static void hookNewXSP(XC_LoadPackage.LoadPackageParam lpparam) {
}
if (xposedminversion > 92 || xposedsharedprefs) {
- Utils.logW("New modules detected, hook preferences");
+ Utils.logI("New modules detected, hook preferences");
XposedHelpers.findAndHookMethod("android.app.ContextImpl", lpparam.classLoader, "checkMode", int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
diff --git a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java
index 00f1f7cedbc..2ddbff32a87 100644
--- a/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java
+++ b/core/src/main/java/org/lsposed/lspd/hooker/LoadedApkCtorHooker.java
@@ -72,7 +72,7 @@ public static void afterHookedMethod(XposedInterface.AfterHookCallback callback)
return;
}
- LoadedApkGetCLHooker.addLoadedApk(loadedApk);
+ LoadedApkCreateCLHooker.addLoadedApk(loadedApk);
} catch (Throwable t) {
Hookers.logE("error when hooking LoadedApk.", t);
}
diff --git a/core/src/main/java/org/lsposed/lspd/impl/LSPosedRemotePreferences.java b/core/src/main/java/org/lsposed/lspd/impl/LSPosedRemotePreferences.java
index 4bbe9395762..5c5d3fa37e0 100644
--- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedRemotePreferences.java
+++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedRemotePreferences.java
@@ -10,10 +10,10 @@
import org.lsposed.lspd.service.ILSPInjectedModuleService;
import org.lsposed.lspd.service.IRemotePreferenceCallback;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("unchecked")
@@ -21,8 +21,7 @@ public class LSPosedRemotePreferences implements SharedPreferences {
private final Map mMap = new ConcurrentHashMap<>();
- private static final Object CONTENT = new Object();
- final WeakHashMap mListeners = new WeakHashMap<>();
+ final HashSet mListeners = new HashSet<>();
IRemotePreferenceCallback callback = new IRemotePreferenceCallback.Stub() {
@Override
@@ -42,7 +41,7 @@ synchronized public void onUpdate(Bundle bundle) {
}
synchronized (mListeners) {
for (var key : changes) {
- mListeners.keySet().forEach(listener -> listener.onSharedPreferenceChanged(LSPosedRemotePreferences.this, key));
+ mListeners.forEach(listener -> listener.onSharedPreferenceChanged(LSPosedRemotePreferences.this, key));
}
}
}
@@ -117,7 +116,7 @@ public Editor edit() {
@Override
public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
synchronized (mListeners) {
- mListeners.put(listener, CONTENT);
+ mListeners.add(listener);
}
}
diff --git a/core/src/main/jni/include/config_bridge.h b/core/src/main/jni/include/config_bridge.h
index 0ac540b94e8..b24d4fec2af 100644
--- a/core/src/main/jni/include/config_bridge.h
+++ b/core/src/main/jni/include/config_bridge.h
@@ -16,32 +16,30 @@
*
* Copyright (C) 2022 LSPosed Contributors
*/
+#pragma once
-//
-// Created by Kotori0 on 2022/4/14.
-//
-
-#ifndef LSPOSED_CONFIGBRIDGE_H
-#define LSPOSED_CONFIGBRIDGE_H
#include