manager: Add the ability to get a list of active managers
This commit is contained in:
@@ -394,4 +394,43 @@ NativeBridgeNP(clearDynamicSign, jboolean) {
|
||||
bool result = clear_dynamic_sign();
|
||||
LogDebug("clearDynamicSign: result=%d", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
NativeBridgeNP(getManagersList, jobject) {
|
||||
struct manager_list_info info;
|
||||
bool result = get_managers_list(&info);
|
||||
|
||||
if (!result) {
|
||||
LogDebug("getManagersList: failed to get managers list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jclass cls = GetEnvironment()->FindClass(env, "com/sukisu/ultra/Natives$ManagersList");
|
||||
jmethodID constructor = GetEnvironment()->GetMethodID(env, cls, "<init>", "()V");
|
||||
jobject obj = GetEnvironment()->NewObject(env, cls, constructor);
|
||||
|
||||
jfieldID countField = GetEnvironment()->GetFieldID(env, cls, "count", "I");
|
||||
jfieldID managersField = GetEnvironment()->GetFieldID(env, cls, "managers", "Ljava/util/List;");
|
||||
|
||||
GetEnvironment()->SetIntField(env, obj, countField, (jint)info.count);
|
||||
|
||||
jclass arrayListCls = GetEnvironment()->FindClass(env, "java/util/ArrayList");
|
||||
jmethodID arrayListConstructor = GetEnvironment()->GetMethodID(env, arrayListCls, "<init>", "()V");
|
||||
jobject managersList = GetEnvironment()->NewObject(env, arrayListCls, arrayListConstructor);
|
||||
jmethodID addMethod = GetEnvironment()->GetMethodID(env, arrayListCls, "add", "(Ljava/lang/Object;)Z");
|
||||
|
||||
jclass managerInfoCls = GetEnvironment()->FindClass(env, "com/sukisu/ultra/Natives$ManagerInfo");
|
||||
jmethodID managerInfoConstructor = GetEnvironment()->GetMethodID(env, managerInfoCls, "<init>", "(II)V");
|
||||
|
||||
for (int i = 0; i < info.count; i++) {
|
||||
jobject managerInfo = GetEnvironment()->NewObject(env, managerInfoCls, managerInfoConstructor,
|
||||
(jint)info.managers[i].uid,
|
||||
(jint)info.managers[i].signature_index);
|
||||
GetEnvironment()->CallBooleanMethod(env, managersList, addMethod, managerInfo);
|
||||
}
|
||||
|
||||
GetEnvironment()->SetObjectField(env, obj, managersField, managersList);
|
||||
|
||||
LogDebug("getManagersList: count=%d", info.count);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define CMD_HOOK_TYPE 101
|
||||
#define CMD_GET_SUSFS_FEATURE_STATUS 102
|
||||
#define CMD_DYNAMIC_SIGN 103
|
||||
#define CMD_GET_MANAGERS 104
|
||||
|
||||
#define DYNAMIC_SIGN_OP_SET 0
|
||||
#define DYNAMIC_SIGN_OP_GET 1
|
||||
@@ -173,4 +174,12 @@ bool clear_dynamic_sign() {
|
||||
struct dynamic_sign_user_config config;
|
||||
config.operation = DYNAMIC_SIGN_OP_CLEAR;
|
||||
return ksuctl(CMD_DYNAMIC_SIGN, &config, NULL);
|
||||
}
|
||||
|
||||
bool get_managers_list(struct manager_list_info* info) {
|
||||
if (info == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ksuctl(CMD_GET_MANAGERS, info, NULL);
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "prelude.h"
|
||||
#include <linux/capability.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
bool become_manager(const char *);
|
||||
|
||||
@@ -105,6 +106,14 @@ struct app_profile {
|
||||
};
|
||||
};
|
||||
|
||||
struct manager_list_info {
|
||||
int count;
|
||||
struct {
|
||||
uid_t uid;
|
||||
int signature_index;
|
||||
} managers[2];
|
||||
};
|
||||
|
||||
bool set_app_profile(const struct app_profile* profile);
|
||||
|
||||
bool get_app_profile(char* key, struct app_profile* profile);
|
||||
@@ -125,4 +134,6 @@ bool get_dynamic_sign(struct dynamic_sign_user_config* config);
|
||||
|
||||
bool clear_dynamic_sign();
|
||||
|
||||
bool get_managers_list(struct manager_list_info* info);
|
||||
|
||||
#endif //KERNELSU_KSU_H
|
||||
@@ -118,6 +118,12 @@ object Natives {
|
||||
*/
|
||||
external fun clearDynamicSign(): Boolean
|
||||
|
||||
/**
|
||||
* Get active managers list when dynamic sign is enabled
|
||||
* @return ManagersList object containing active managers, or null if failed or not enabled
|
||||
*/
|
||||
external fun getManagersList(): ManagersList?
|
||||
|
||||
private const val NON_ROOT_DEFAULT_PROFILE_KEY = "$"
|
||||
private const val NOBODY_UID = 9999
|
||||
|
||||
@@ -177,7 +183,6 @@ object Natives {
|
||||
val size: Int = 0,
|
||||
val hash: String = ""
|
||||
) : Parcelable {
|
||||
constructor() : this(0, "")
|
||||
|
||||
fun isValid(): Boolean {
|
||||
return size > 0 && hash.length == 64 && hash.all {
|
||||
@@ -186,6 +191,22 @@ object Natives {
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@Parcelize
|
||||
@Keep
|
||||
data class ManagersList(
|
||||
val count: Int = 0,
|
||||
val managers: List<ManagerInfo> = emptyList()
|
||||
) : Parcelable
|
||||
|
||||
@Immutable
|
||||
@Parcelize
|
||||
@Keep
|
||||
data class ManagerInfo(
|
||||
val uid: Int = 0,
|
||||
val signatureIndex: Int = 0
|
||||
) : Parcelable
|
||||
|
||||
@Immutable
|
||||
@Parcelize
|
||||
@Keep
|
||||
|
||||
@@ -719,6 +719,32 @@ private fun InfoCard(
|
||||
icon = Icons.Default.SettingsSuggest,
|
||||
)
|
||||
|
||||
// 活跃管理器
|
||||
if (systemInfo.isDynamicSignEnabled && systemInfo.managersList != null) {
|
||||
val signatureMap = systemInfo.managersList.managers.groupBy { it.signatureIndex }
|
||||
|
||||
val managersText = buildString {
|
||||
signatureMap.toSortedMap().forEach { (signatureIndex, managers) ->
|
||||
append(managers.joinToString(", ") { "UID:${it.uid}" })
|
||||
append(" ")
|
||||
append(
|
||||
when (signatureIndex) {
|
||||
1 -> "(${stringResource(R.string.default_signature)})"
|
||||
2 -> "(${stringResource(R.string.dynamic_signature)})"
|
||||
else -> if (signatureIndex >= 0) "(${stringResource(R.string.signature_index, signatureIndex)})" else "(${stringResource(R.string.unknown_signature)})"
|
||||
}
|
||||
)
|
||||
append("; ")
|
||||
}
|
||||
}.trimEnd(' ', ';')
|
||||
|
||||
InfoCardItem(
|
||||
stringResource(R.string.multi_manager_list),
|
||||
managersText.ifEmpty { stringResource(R.string.no_active_manager) },
|
||||
icon = Icons.Default.Group,
|
||||
)
|
||||
}
|
||||
|
||||
InfoCardItem(
|
||||
stringResource(R.string.home_selinux_status),
|
||||
systemInfo.seLinuxStatus,
|
||||
|
||||
@@ -60,7 +60,9 @@ class HomeViewModel : ViewModel() {
|
||||
val susSUMode: String = "",
|
||||
val superuserCount: Int = 0,
|
||||
val moduleCount: Int = 0,
|
||||
val kpmModuleCount: Int = 0
|
||||
val kpmModuleCount: Int = 0,
|
||||
val managersList: Natives.ManagersList? = null,
|
||||
val isDynamicSignEnabled: Boolean = false
|
||||
)
|
||||
|
||||
private val gson = Gson()
|
||||
@@ -242,6 +244,26 @@ class HomeViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取动态签名状态和管理器列表
|
||||
val dynamicSignConfig = try {
|
||||
Natives.getDynamicSign()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Failed to get dynamic sign config", e)
|
||||
null
|
||||
}
|
||||
|
||||
val isDynamicSignEnabled = dynamicSignConfig?.isValid() == true
|
||||
val managersList = if (isDynamicSignEnabled) {
|
||||
try {
|
||||
Natives.getManagersList()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Failed to get managers list", e)
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
systemInfo = SystemInfo(
|
||||
kernelRelease = uname.release,
|
||||
androidVersion = Build.VERSION.RELEASE,
|
||||
@@ -256,7 +278,9 @@ class HomeViewModel : ViewModel() {
|
||||
susSUMode = susSUMode,
|
||||
superuserCount = getSuperuserCount(),
|
||||
moduleCount = getModuleCount(),
|
||||
kpmModuleCount = getKpmModuleCount()
|
||||
kpmModuleCount = getKpmModuleCount(),
|
||||
managersList = managersList,
|
||||
isDynamicSignEnabled = isDynamicSignEnabled
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error fetching system info", e)
|
||||
|
||||
@@ -578,4 +578,9 @@
|
||||
<string name="invalid_sign_config">无效的签名配置</string>
|
||||
<string name="dynamic_sign_disabled_success">动态签名已禁用</string>
|
||||
<string name="dynamic_sign_clear_failed">清除动态签名错误</string>
|
||||
<string name="dynamic_signature">动态</string>
|
||||
<string name="signature_index">签名%1$d</string>
|
||||
<string name="unknown_signature">未知</string>
|
||||
<string name="multi_manager_list">活跃管理器</string>
|
||||
<string name="no_active_manager">无活跃管理器</string>
|
||||
</resources>
|
||||
|
||||
@@ -580,4 +580,10 @@
|
||||
<string name="invalid_sign_config">Invalid signature configuration</string>
|
||||
<string name="dynamic_sign_disabled_success">Dynamic signature disabled</string>
|
||||
<string name="dynamic_sign_clear_failed">Failed to clear dynamic signature</string>
|
||||
<string name="dynamic_signature">Dynamic</string>
|
||||
<string name="signature_index">Signature %1$d</string>
|
||||
<string name="unknown_signature">Unknown</string>
|
||||
<string name="multi_manager_list">Active Manager</string>
|
||||
<string name="no_active_manager">No active manager</string>
|
||||
<string name="default_signature">SukiSU</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user