Compare commits

...

197 Commits

Author SHA1 Message Date
Rifat Azad
1de68a8ed2 Revert "userspace: implement OSS ksuinit"
This reverts commit edb99a2c1a.
2025-08-10 13:48:18 +06:00
Rifat Azad
e0c461322b kernel: nest ksun switch manager support under CONFIG_KSU_SWITCH_MANAGER config default as disabled 2025-08-10 12:28:34 +06:00
tiann
edb99a2c1a userspace: implement OSS ksuinit 2025-08-10 10:48:13 +06:00
James McConnell
eaab98b7ec ci(workflows): add artifact caching to build-manager-ci and build-manager-spoofed workflows (#702)
* ci(workflows): add artifact caching to build-manager-ci workflow

Add cache check, save and restore steps to avoid rebuilding artifacts when source files haven't changed. The workflow now checks for cached artifacts first and only rebuilds if cache is invalid or missing.

* ci(workflows): add artifact caching to build-manager-spoofed workflow
Add cache check, save and restore steps to avoid rebuilding artifacts when source files haven't changed. The workflow now checks for cached artifacts first and only rebuilds if cache is invalid or missing.
2025-08-05 09:47:24 +06:00
Rifat Azad
aa37bcc368 New Crowdin updates (#660)
* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr-rTR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es-rEM/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ar-rSA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn-rBD/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bg-rBG/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fr-rFR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de-rDE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hi-rIN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hu-rHU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ja-rJP/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ko-rKR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fa-rIR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es-rEM/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-sv-rSE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-th-rTH/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr-rTR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk-rUA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk-rUA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr-rTR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)
2025-08-01 16:44:29 +06:00
Rifat Azad
107cd4add0 Update README.md 2025-07-28 19:37:12 +06:00
Rifat Azad
94c4b41ea3 README: updated 2025-07-28 19:36:30 +06:00
Rifat Azad
0bde9047b9 manager: add -spoof string to apk output 2025-07-27 22:42:36 +06:00
Fahrez256Bit
bc9927b9b6 POC: load icon app via ksu://icon/[packageName] (#674)
* manager: load app icons from package name using AppIconUti

Trying basic icon rendering from package via WebView ksu:// scheme.
Includes cache and bitmap scaling.
Still subject to refinement.

* Update WebUIActivity.kt

This proof-of-concept intercepts custom URLs of the form:
  ksu://icon/com.example.app

It fetches the app icon using PackageManager via AppIconUtil,
converts it to PNG, and returns it as a WebResourceResponse.

Used inside shouldInterceptRequest() for early experimentation
with dynamic WebView asset routing.

Fallbacks to WebViewAssetLoader for all other requests.

Notes:
- Icon size currently fixed at 512px
- No error icon or fallback image yet
- No caching headers or mime sniffing implemented

* POC: Handle ksu://icon/[packageName] to serve app icon via WebView

This proof-of-concept intercepts custom URLs of the form:
  ksu://icon/com.example.app

It fetches the app icon using PackageManager via AppIconUtil,
converts it to PNG, and returns it as a WebResourceResponse.

Used inside shouldInterceptRequest() for early experimentation
with dynamic WebView asset routing.

Fallbacks to WebViewAssetLoader for all other requests.

Notes:
- Icon size currently fixed at 512px
- No error icon or fallback image yet
- No caching headers or mime sniffing implemented
2025-07-25 21:23:29 +06:00
James McConnell
d4f4c0a0cc Syscall Hooks (#686)
* Update gki-kernel.yml: Add Syscall Hooks

* Update gki-kernel.yml: Fuzz is needed?

* workflows: apply syscall hook patches and configs only for NON-LKM build

---------

Co-authored-by: Rifat Azad <33044977+rifsxd@users.noreply.github.com>
2025-07-25 19:35:29 +06:00
Rifat Azad
0aaae919c0 userspace/su: add ndk compatible su from kernelnosu
Co-authored-by: nampud <nampud@users.noreply.github.com>
2025-07-25 06:40:48 +06:00
Rifat Azad
3f4c23a34f kernel: allow only perms for /{system | vendor | product | system_ext}/bin/su path
kernel: guard kernelnosu perms if not using KSU_KPROBES_HOOK
2025-07-24 06:44:10 +06:00
Rifat Azad
d69a72c658 src: build script for a full featured manager 2025-07-23 23:02:37 +06:00
Rifat Azad
adbff41a22 ksud: decide best partition to direct flash LKM 2025-07-23 23:02:28 +06:00
Rifat Azad
512f84504e ksud: create our own new ramdisk when no compatible ramdisk found 2025-07-22 07:23:07 +06:00
Rifat Azad
c44f48c8a4 Update README.md 2025-07-21 15:36:05 +06:00
Rifat Azad
5c6c3870a0 ksud_magic: fix rust fmt 2025-07-21 06:59:34 +06:00
Alessandro Paluzzi
c6b5440682 manager | ksud: Add toggle for global mount namespace (#99)
* This is untested, if you facing any issues, open a new issue or comments at our group
* and also, this changes maybe reverted if didn't meet the target.

Taken from Apatch's implementations:
8de6b9d676
57d527a846
f093d6a633

Critics are welcome!

Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
2025-07-21 06:34:11 +06:00
Rifat Azad
a917314e84 manager: fixed sus_su features
susfsd: added `sus_su support` command
2025-07-21 06:19:50 +06:00
nampud
948975ba35 kernel: core_hook: add support for KernelNoSU
reorder ksu_handle_prctl checks a bit to allow non-manager to use CMD 15
this allows us to piggyback a small su to KernelSU's permission system after
disabling kernel sucompat

from:
Relax prctl perm check
- 95125c32f9
Allow prctl only for root or manager or su binary
- fa7af67d94
Refine prctl access check, allow /product/bin/su
- dd466dc1b6
Refine prctl check a little bit more
- e7c5b24efa

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-07-21 06:19:34 +06:00
Rifat Azad
45ad73e9dd kernel: guard syscall hook types
- for kernel syscall hooks we need to pass additional guards for ksun (#ifdef CONFIG_KSU -> #if defined(CONFIG_KSU) && !defined(CONFIG_KSU_KPROBES_HOOK)) or else it will fail to build because of undefined symbol

- reference https://github.com/KernelSU-Next/kernel_patches/blob/main/syscall_hook/min_scope_syscall_hooks_v1.4.patch
2025-07-21 02:10:36 +06:00
Rifat Azad
892a62afdf manager: bump MINIMAL_SUPPORTED_KERNEL to 12797 2025-07-19 23:36:00 +06:00
Rifat Azad
d61de07c21 kernel: implement v2_signature size/hash override from userspace through kernel module parameter
- /sys/module/kernelsu/parameters/expected_manager_*
2025-07-19 23:10:48 +06:00
Rifat Azad
4382dca515 ksud: do backup for vendor_boot partition 2025-07-17 23:24:32 +06:00
Rifat Azad
2c9078e038 kernel: use ksu_strncpy_from_user_retry when kprobes hook sucompat pagefaults 2025-07-16 21:06:59 +06:00
Edrick Sinsuan
81f4f09d0c ksud: Address pagefault in ksu_handle_execveat_ksud (#662)
* ksud: Address pagefault in ksu_handle_execveat_ksud

As pointed out by @backslashxx, when strncpy pagefaults, it causes
the first_arg to be completely NULL in some systems. This causes
second_stage initialization to fail hence causing SU to be
non-functional.

This patch copies ksu_strncpy_from_user_retry from @backslashxx's
commit:
e2fe25e485

This adds a fallback to perform a normal strncpy_from_user when nofault
fails which allows us to get the first_arg in such cases.

Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: Edrick Sinsuan <evcsinsuan@gmail.com>

* Revert "ksud: Add second_stage init variant (#653)"

This reverts commit c6b60a24e8.

---------

Signed-off-by: Edrick Sinsuan <evcsinsuan@gmail.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-07-15 21:24:20 +06:00
Rifat Azad
2241696498 ksud: fix rust fmt 2025-07-15 04:02:34 +06:00
Rifat Azad
514c5458ed manager: append 'spoofed' tag to the app version name 2025-07-15 03:58:11 +06:00
Rifat Azad
d30bb33a9c ksud: removed banner 2025-07-15 03:36:11 +06:00
Rifat Azad
ec7fe6b039 manager: minor improvement to flash screen topbar status 2025-07-15 03:35:58 +06:00
Rifat Azad
3fd61e0ee5 New Crowdin updates (#646)
* New translations manager/app/src/main/res/values-hi-rIN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de-rDE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de-rDE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk-rUA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ar-rSA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn-rBD/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bg-rBG/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fr-rFR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de-rDE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hi-rIN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hu-rHU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ja-rJP/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ko-rKR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fa-rIR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es-rEM/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-sv-rSE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-th-rTH/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr-rTR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk-rUA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)
2025-07-15 01:10:58 +06:00
Rifat Azad
8fc85993f1 ksud: fix clippy errors 2025-07-14 22:55:22 +06:00
Rifat Azad
df07860e44 ksud: fix rust fmt errors 2025-07-14 20:22:31 +06:00
Rifat Azad
bd03c296a1 kernel/Makefile: remove redundant get_cred_rcu backports 2025-07-14 20:11:13 +06:00
Rifat Azad
14b7861f44 template: add feature request template 2025-07-14 19:59:38 +06:00
Rifat Azad
3c421b1362 manager: added more module list sort options ( enabled, action and webui) 2025-07-13 20:59:33 +06:00
Edrick Sinsuan
c6b60a24e8 ksud: Add second_stage init variant (#653)
There are some ROMs based on AOSP that calls on second stage init
with argc: 2 but with first_arg: "". This causes KSU to not work
properly on those systems.

Signed-off-by: Edrick Sinsuan <evcsinsuan@gmail.com>
2025-07-13 05:26:10 +06:00
Rifat Azad
1baedd89b7 manager: add eruda console (v3.4.3) to webui-next 2025-07-12 23:18:26 +06:00
Rifat Azad
b567e9b275 kernel: add better error message if CMD_GET_MANAGWR_UID fails to fetch manager_uid 2025-07-11 04:11:17 +06:00
Rifat Azad
3ba5b028d4 manager: fix hook mode status showing blank when Natives.getHookMode() is null 2025-07-10 18:10:14 +06:00
Tashfin Shakeer Rhythm
4d633a1e0e kernel: selinux: rules: Fix illegal RCU lock usage in apply_kernelsu_rules() (#2646)
When kernel is compiled with CONFIG_DEBUG_ATOMIC_SLEEP enabled, it
prints the following splat in dmesg during post boot:

[ 6.739169] init: Opening SELinux policy
[ 6.751520] init: Loading SELinux policy
[ 6.894684] SELinux: policy capability network_peer_controls=1 [
6.894688] SELinux: policy capability open_perms=1 [ 6.894690] SELinux:
policy capability extended_socket_class=1 [ 6.894691] SELinux: policy
capability always_check_network=0 [ 6.894693] SELinux: policy capability
cgroup_seclabel=0 [ 6.894695] SELinux: policy capability
nnp_nosuid_transition=1 [ 7.214323] selinux: SELinux: Loaded file
context from: [ 7.214332] selinux:
/system/etc/selinux/plat_file_contexts [ 7.214339] selinux:
/system_ext/etc/selinux/system_ext_file_contexts [ 7.214345] selinux:
/product/etc/selinux/product_file_contexts [ 7.214350] selinux:
/vendor/etc/selinux/vendor_file_contexts [ 7.214356] selinux:
/odm/etc/selinux/odm_file_contexts [ 7.216398] KernelSU:
/system/bin/init argc: 2
[ 7.216401] KernelSU: /system/bin/init first arg: second_stage [
7.216403] KernelSU: /system/bin/init second_stage executed [ 7.216506]
BUG: sleeping function called from invalid context at
security/selinux/ss/hashtab.c:47 [ 7.216512] in_atomic(): 0,
irqs_disabled(): 0, non_block: 0, pid: 1, name: init [ 7.216516]
preempt_count: 0, expected: 0
[ 7.216518] RCU nest depth: 1, expected: 0
[ 7.216524] CPU: 6 PID: 1 Comm: init Not tainted
5.4.289-Scarlet-v2.0-beta3 #1 [ 7.216526] Hardware name: redwood based
Qualcomm Technologies, Inc. SM7325 (DT) [ 7.216528] Call trace:
[ 7.216536] dump_backtrace+0x0/0x210
[ 7.216539] show_stack+0x14/0x20
[ 7.216544] dump_stack+0x9c/0xec
[ 7.216548] __might_resched+0x1f0/0x210
[ 7.216552] hashtab_insert+0x38/0x230
[ 7.216557] add_type+0xd4/0x2e0
[ 7.216559] ksu_type+0x24/0x60
[ 7.216562] apply_kernelsu_rules+0xa8/0x650
[ 7.216565] ksu_handle_execveat_ksud+0x2a8/0x460
[ 7.216568] ksu_handle_execveat+0x2c/0x60
[ 7.216571] __arm64_sys_execve+0xe8/0xf0
[ 7.216574] el0_svc_common+0xf4/0x1a0
[ 7.216577] do_el0_svc+0x2c/0x40
[ 7.216579] el0_sync_handler+0x18c/0x200
[ 7.216582] el0_sync+0x140/0x180

This is because apply_kernelsu_rules() uses rcu_read_lock() to protect
SELinux policy modifications. However, cond_resched() from
hashtab_insert() at security/selinux/ss/hashtab.c is internally called
and it sleeps which is illegal under an RCU read-side critical section.

While replacing it with a spinlock would suppress the warning, this is
fundamentally incorrect because sleeping is illegal while holding a
spinlock and spinlock would turn off preemption which isn't an ideal
solution since it intentionally turns off rescheduling, and can lead to
deadlocks.

Instead, replace the RCU lock with a mutex lock. Mutex lock allows
sleeping when necessary, which is appropriate here because
apply_kernelsu_rules() runs in process context, not in atomic or
interrupt context. As apply_kernelsu_rules() is invoked only once during
post boot (SYSTEM_RUNNING), the mutex lock does not introduce any major
runtime performance regression and provides correct synchronization.

Fixes: https://github.com/tiann/KernelSU/issues/2637

Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
2025-07-10 17:50:14 +06:00
Rifat Azad
f08fcec777 kernel: changed constant value for CMD_HOOK_MODE to 0xC0DEAD1A and CMD_GET_MANAGER_UID to 16, to avoid future conflitcs with upstream 2025-07-10 00:50:45 +06:00
Rifat Azad
afe6ad7261 docs: add crowdin localization progress 2025-07-10 00:04:22 +06:00
Rifat Azad
54b26fd32c New Crowdin updates (#644)
* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de-rDE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hi-rIN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)
2025-07-08 22:00:14 +06:00
Berserkr2k
4b56b14a4f docs: Add Spanish README (#628)
Add the README_ES.md file to provide documentation for Spanish-speaking users.
2025-07-08 00:39:25 +06:00
Rifat Azad
9b4c6057a0 New Crowdin updates (#634)
* New translations manager/app/src/main/res/values-ar-rSA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn-rBD/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bg-rBG/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rCN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh-rTW/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fr-rFR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de-rDE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hi-rIN/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hu-rHU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-in-rID/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it-rIT/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ja-rJP/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ko-rKR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fa-rIR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl-rPL/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt-rBR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru-rRU/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es-rEM/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-sv-rSE/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-th-rTH/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr-rTR/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk-rUA/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi-rVN/strings.xml (bundle: 8)
2025-07-07 17:27:03 +06:00
Rifat Azad
873740ef1c docs: added Crowdin Translators credits to README 2025-07-07 17:25:53 +06:00
Rifat Azad
ad80c1ea77 manager: remove current locale format to fix locale format to android_code 2025-07-07 17:12:03 +06:00
Rifat Azad
d5c6f0affb New Crowdin updates (#629)
* New translations manager/app/src/main/res/values-de/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es/strings.xml (bundle: 8)
2025-07-07 13:10:09 +06:00
Rifat Azad
162056f9ff New Crowdin updates (#627)
* New translations manager/app/src/main/res/values-ar/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bg/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fr/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hi/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hu/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-id/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ja/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ko/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fa/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-sv/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-th/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ar/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-id/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ja/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fa/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi/strings.xml (bundle: 8)
2025-07-07 04:20:04 +06:00
Eren
3af1d0354d docs: Update README_TR.md (#598) 2025-07-06 13:52:41 +06:00
kam821
6adb2eaf51 Update Polish README (#624)
- Moved to the new README format
- Added missing languages in the header
- Updated README_UA.md link title.
2025-07-06 13:46:43 +06:00
Rifat Azad
ce91e4fedb New Crowdin updates (#623)
* New translations manager/app/src/main/res/values-ar/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bg/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fr/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hi/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hu/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-id/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ja/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ko/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fa/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-sv/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-th/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ar/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bg/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-id/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ja/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ar/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-hi/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-id/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-ru/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-fr/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-id/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-it/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pl/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-es/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-tr/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-uk/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-zh/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-de/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-pt/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-vi/strings.xml (bundle: 8)

* New translations manager/app/src/main/res/values-bn/strings.xml (bundle: 8)
2025-07-06 13:45:36 +06:00
Rifat Azad
a36390ea03 Update Crowdin configuration file 2025-07-05 21:47:41 +06:00
Rifat Azad
e31e0271cb manager: clean translations 2025-07-05 21:37:48 +06:00
Rifat Azad
b97fc2bec2 Revert "kernel/Makefile: check kernelsu driver version from online git repo first, if fails then check local .git and if that also fails then use hardcoded fallback"
This reverts commit a37f398cc7.

- this is a very flawed logic for when we try to build with release tags or specific commit hashes instead of latest commit, the online logic will always append latest version instead of the actual version of code (i.e release tags or commit hashes)
2025-07-05 17:35:25 +06:00
Rifat Azad
10875ee190 manager: refactor home module/superuser plural/singular strings 2025-07-04 23:52:20 +06:00
Rifat Azad
fdb01c918a docs: add webui-next api documentation 2025-07-04 21:38:41 +06:00
Rifat Azad
6afa86d2ae manager/webui: let getPackagesIcons generate icon and store in cache as well when called 2025-07-04 01:22:53 +06:00
Rifat Azad
25fa6b7b9b manager: webui-next is now amoled mode compliant 2025-07-03 22:27:18 +06:00
Rifat Azad
a361fa3272 manager: implement getPackagesIcons and cacheAllPackageIcons api to webui-next 2025-07-03 22:03:13 +06:00
Rifat Azad
4a9733c078 manager: sort a-z order for webui-next list packages api 2025-07-03 20:12:21 +06:00
Rifat Azad
31aa571bc2 susfsd: refactored show features & support to match ksu_susfs standards (ref https://gitlab.com/simonpunk/susfs4ksu/-/commit/ad56926) 2025-07-03 19:30:06 +06:00
Rifat Azad
58167a4289 manager: introduce app package info API for webui-next 2025-07-03 15:54:31 +06:00
Rifat Azad
a8bfd1cc7d manager:added more dynamic color vars to webui-next 2025-07-02 16:20:28 +06:00
Rifat Azad
58aeb2697a manager: add monet colors support to webui (webui-next)
- colors are served to /internal/colors.css

the current vars are :

primary
onPrimary
background
onSurface
onSurfaceVariant
tonalSurface
surfaceBright
outlineVariant
error
2025-07-02 14:36:43 +06:00
Rifat Azad
7f68766dc4 manager: move module/allowlist backup directory back to /data/adb/ksu/backup dir since /sdcarf/.ksunext is futile and easily can be used as a detection 2025-07-02 02:30:59 +06:00
Rifat Azad
310c0573c6 manager: fix empty gap shown when zygisk is unavailable (fix #594) 2025-07-02 02:08:54 +06:00
Rifat Azad
d1aad01df3 manager: new zygisk detection method implemented and deprecated old method
Currently only supports ReZygisk and soon ZygiskNext will hopefully follow (ZN users will have issues detecting zygisk injections until then)
2025-07-01 22:21:40 +06:00
Hinata Saine
9733b92d30 Do not translate SELinux status in Japanese (#590) 2025-07-01 15:28:25 +06:00
Pedro.js
aaf776f421 manager: fix integer underflow in get_manager_uid (#591)
This commit fixes the issue where the "uid_t" type variable, typedef'd from unsigned int, was being assigned -1, causing an integer underflow.
2025-06-30 22:17:15 +06:00
Rifat Azad
5e33aee99f manager: fix pull to refresh handling in ModuleList 2025-06-30 19:08:14 +06:00
Rifat Azad
4e3f06d405 kernel: added new prctl CMD_GET_MANAGER_UID to get the uid of the crowned manager
manager: show crowned manager uid in infocard when developer options is enabled
2025-06-30 14:22:19 +06:00
роизен
98b9863041 Update README_UA.md (#577)
Co-authored-by: Rifat Azad <33044977+rifsxd@users.noreply.github.com>
2025-06-30 13:22:45 +06:00
luigimak
29ae76d1fb Update and fix Italian translation (#583) 2025-06-30 13:21:13 +06:00
igor
2c3841558e Update translations (#580) 2025-06-30 13:20:55 +06:00
Juno Bủh
c8b357e31b Update Vietnamese Translation (#578)
* Update Vietnamese Translation

* Update Vietnamese Translation

* Update Vietnamese Strings

* Update Vietnamese Translation
2025-06-30 13:20:43 +06:00
AxelPLN(Axel Yinjia Huang)
3ad02ff50b fix: update translation for zh-rCH & zh-rTW (#575)
* docs: sync README_CN & README_TW with en

* fix: update manager translation for zh-rCN & zh-rTW

* docs: fixed some text issue

* fix: update translation about su compatibility
2025-06-30 13:20:23 +06:00
mr_vokintos
6a54b30a9d Update Russian (#574)
* Update Russian

again

* Update strings.xml
2025-06-30 13:20:06 +06:00
роизен
b0cb3bb4c2 Update Ukranian (#573)
* Update Uk

* Update strings.xml
2025-06-30 13:19:47 +06:00
Rifat Azad
7f957be99b manager: fix ListItem title size 2025-06-29 20:10:31 +06:00
Rifat Azad
a54c319d55 manager: improve padding 2025-06-29 18:50:04 +06:00
Rifat Azad
2c71531533 manager: UI overhaul 2025-06-29 15:31:17 +06:00
Rifat Azad
5c61a70e5a manager: fix disable back instance if flashing.status is flashing 2025-06-29 00:05:51 +06:00
Rifat Azad
fdf1d61735 manager: remove unused lib of mmrl and pro guard rules 2025-06-28 20:21:14 +06:00
Rifat Azad
93dc61e113 manager: change FAB visibility with scrolling gestures on module screen list 2025-06-28 19:45:32 +06:00
Rifat Azad
d80a3ebcda manager: removed deprecated webuix and allow superuser and module management capabilities even with su compat disabled 2025-06-28 17:17:49 +06:00
igor
4270fd8b1e update translations in docs and manager (#571)
Co-authored-by: Rifat Azad <33044977+rifsxd@users.noreply.github.com>
2025-06-27 22:51:05 +06:00
роизен
764dbc3782 Improve README_UA (#569)
* Improve README_UA

* Update README_UA.md
2025-06-27 22:48:49 +06:00
роизен
080ab9a952 Update Uk (#566) 2025-06-27 22:48:32 +06:00
AxelPLN(Axel Yinjia Huang)
a9cab5ccfd fix: complete the text of the module labels (#558)
- replace the string Resource ID of uninstalled & those can be updated modules
2025-06-27 22:48:18 +06:00
Rifat Azad
3d44602537 manager: check additional zygisk 64 libs instead of only 32 bit lib for zygisk detection 2025-06-27 21:13:25 +06:00
Eren
88eb2a2723 Improve README (#562)
* Improve README

* Update README.md
2025-06-27 18:39:33 +06:00
NkBe
e272e557b0 manger: fix lkm detection (#2654)
原因请看
https://github.com/SukiSU-Ultra/SukiSU-Ultra/pull/217#issuecomment-3004461174

文中介绍的是lkm的问题 但实测下来gki也有这样的问题 但修复方法通用
2025-06-27 18:02:42 +06:00
Rifat Azad
2a4794e422 manager: implemented zygisk required label for module card 2025-06-27 18:02:34 +06:00
mr_vokintos
818bdbead6 Update Russian (#557) 2025-06-27 14:37:54 +06:00
Nhật Minh
76249fa67d Update strings.xml (#553) 2025-06-27 14:37:39 +06:00
AxelPLN(Axel Yinjia Huang)
ed50b57b57 fix: update manager translation for zh-rCN & zh-rTW (#556)
* docs: complete text for README_CN & README_TW

* fix: update manager translation for zh-rCN & zh-rTW

also complete some text for module label and language switching functionality
2025-06-27 14:37:10 +06:00
Rifat Azad
f05f776a08 manager: fix Condition is always 'true' 2025-06-27 12:02:16 +06:00
Axel Yinjia Huang
c9b79c3016 manager: add basic language switching functionality 2025-06-27 11:37:12 +06:00
Rifat Azad
3ff10d6622 susfsd: remove deprecated CONFIG_KSU_SUSFS_SUS_OVERLAYFS and add CONFIG_KSU_SUSFS_HAS_MAGIC_MOUNT 2025-06-26 23:55:29 +06:00
Rifat Azad
b95d2b69b6 manager: add vendor_boot suggestion for LKM patch 2025-06-26 23:44:46 +06:00
Rifat Azad
2cd8453877 Revert "manager: move the wx platform init to the Application class so it starts as soon as the app process launches"
This reverts commit d5c4f85d73.
2025-06-26 23:25:37 +06:00
роизен
b7300b0525 Update translation for UK (#552) 2025-06-26 22:02:09 +06:00
kam821
3a278d560f Update Polish translation (#521)
* Update Polish translation

- Improve cosmetics / context-sensitive lines

* Update Polish translation - backup/restore

- Cosmetics, worth considering changing it in the future to keep option name in one line.

* Update Polish translation - homepage

- Shortened translation to work around broken formatting
2025-06-26 20:01:55 +06:00
igor
03fa2eddb2 Update portuguese translation (#518) 2025-06-26 17:43:27 +06:00
Rifat Azad
b74e953ad2 ksud: implement patching LKM vendor_ramdisk/ramdisk.cpio for compatibily needed for some pixel devices 2025-06-26 10:33:58 +06:00
Rifat Azad
39717b0a3f Revert "ksud: rust FMT"
This reverts commit 78eb3b0b22.
2025-06-25 17:58:52 +06:00
Rifat Azad
7f0eccd3d5 ksud: handle errors and non compatible ramdisk 2025-06-25 17:43:59 +06:00
Rifat Azad
78eb3b0b22 ksud: rust FMT 2025-06-25 13:25:28 +06:00
Rifat Azad
39f20bf573 manager: fix uneven spacing for empty label for superuser app section with DEFAULT label (fix #547) 2025-06-25 12:54:13 +06:00
Rifat Azad
092eb1b23d manager: use busybox for tar and du commands as not all devices has it most likely and if module size is 0 bytes then show null 2025-06-24 17:56:50 +06:00
Rifat Azad
30e2ed5db5 ksud: third test properly check if vendor is already patched or not for lkm restoration and also handle magisk patched vendor boot 2025-06-24 16:47:44 +06:00
Rifat Azad
dc7ae2db5f manager: fix status card startActivity intent fallback to not allow lkm install on non gki 2025-06-24 09:53:20 +06:00
Rifat Azad
b3b7ef1cb3 manager: dont show developer options and banner toggle when ksuversion is null 2025-06-24 09:26:14 +06:00
Rifat Azad
4de4d1e091 ksud: second test of vendor_boot patching now handling vendor_boot partition and restore partition 2025-06-24 09:17:24 +06:00
Rifat Azad
0beea57ab7 ksud: test vendor_boot patching for some newer devices 2025-06-23 18:17:46 +06:00
Rifat Azad
49aee1ff4c manager: remove susfs info from status card and merge it to info card 2025-06-21 17:01:21 +06:00
Rifat Azad
f7a3699fe3 manager: show module update count as badge in bottom bar instead of status card 2025-06-21 12:44:29 +06:00
5ec1cff
66d42de599 app: persist show system app settings 2025-06-20 00:54:23 +06:00
Kaorun
d562594ae1 Update Module.kt 2025-06-19 13:35:05 +06:00
Rifat Azad
02afc6710c manager: show sucmpat when both sucompat is disabled and sus_su enabled 2025-06-18 20:23:35 +06:00
Caner Karaca
9d9f9ed5d5 Update 2025-06-16 06:00:17 +06:00
kam821
b3b6320946 Update Polish translation
- Added missing strings
2025-06-16 05:56:46 +06:00
Rifat Azad
d43b8320ad manager: minor improvements 2025-06-16 05:55:14 +06:00
dependabot[bot]
a2260ae330 build(deps): bump the crates group across 1 directory with 27 updates
Bumps the crates group with 22 updates in the /userspace/ksud_overlayfs directory:

| Package | From | To |
| --- | --- | --- |
| [clap](https://github.com/clap-rs/clap) | `4.5.38` | `4.5.40` |
| [which](https://github.com/harryfei/which-rs) | `7.0.3` | `8.0.0` |
| [getopts](https://github.com/rust-lang/getopts) | `0.2.21` | `0.2.23` |
| [adler2](https://github.com/oyvindln/adler2) | `2.0.0` | `2.0.1` |
| [anstream](https://github.com/rust-cli/anstyle) | `0.6.18` | `0.6.19` |
| [anstyle](https://github.com/rust-cli/anstyle) | `1.0.10` | `1.0.11` |
| [anstyle-parse](https://github.com/rust-cli/anstyle) | `0.2.6` | `0.2.7` |
| [anstyle-query](https://github.com/rust-cli/anstyle) | `1.1.2` | `1.1.3` |
| [anstyle-wincon](https://github.com/rust-cli/anstyle) | `3.0.8` | `3.0.9` |
| [bumpalo](https://github.com/fitzgen/bumpalo) | `3.17.0` | `3.18.1` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.23` | `1.2.26` |
| [clap_lex](https://github.com/clap-rs/clap) | `0.7.4` | `0.7.5` |
| [colorchoice](https://github.com/rust-cli/anstyle) | `1.0.3` | `1.0.4` |
| [flate2](https://github.com/rust-lang/flate2-rs) | `1.1.1` | `1.1.2` |
| [memchr](https://github.com/BurntSushi/memchr) | `2.7.4` | `2.7.5` |
| [miniz_oxide](https://github.com/Frommi/miniz_oxide) | `0.8.8` | `0.8.9` |
| [once_cell_polyfill](https://github.com/polyfill-rs/once_cell_polyfill) | `1.70.0` | `1.70.1` |
| [rustc-demangle](https://github.com/rust-lang/rustc-demangle) | `0.1.24` | `0.1.25` |
| [rustversion](https://github.com/dtolnay/rustversion) | `1.0.20` | `1.0.21` |
| [syn](https://github.com/dtolnay/syn) | `2.0.101` | `2.0.102` |
| [tokio](https://github.com/tokio-rs/tokio) | `1.45.0` | `1.45.1` |
| [windows-link](https://github.com/microsoft/windows-rs) | `0.1.1` | `0.1.2` |



Updates `clap` from 4.5.38 to 4.5.40
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.38...clap_complete-v4.5.40)

Updates `which` from 7.0.3 to 8.0.0
- [Release notes](https://github.com/harryfei/which-rs/releases)
- [Changelog](https://github.com/harryfei/which-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/harryfei/which-rs/compare/7.0.3...8.0.0)

Updates `getopts` from 0.2.21 to 0.2.23
- [Release notes](https://github.com/rust-lang/getopts/releases)
- [Changelog](https://github.com/rust-lang/getopts/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/getopts/compare/v0.2.21...v0.2.23)

Updates `adler2` from 2.0.0 to 2.0.1
- [Changelog](https://github.com/oyvindln/adler2/blob/main/CHANGELOG.md)
- [Commits](https://github.com/oyvindln/adler2/commits)

Updates `anstream` from 0.6.18 to 0.6.19
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.18...anstream-v0.6.19)

Updates `anstyle` from 1.0.10 to 1.0.11
- [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.10...v1.0.11)

Updates `anstyle-parse` from 0.2.6 to 0.2.7
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-parse-v0.2.6...anstyle-parse-v0.2.7)

Updates `anstyle-query` from 1.1.2 to 1.1.3
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-query-v1.1.2...anstyle-query-v1.1.3)

Updates `anstyle-wincon` from 3.0.8 to 3.0.9
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-wincon-v3.0.8...anstyle-wincon-v3.0.9)

Updates `bumpalo` from 3.17.0 to 3.18.1
- [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fitzgen/bumpalo/compare/3.17.0...v3.18.1)

Updates `cc` from 1.2.23 to 1.2.26
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.23...cc-v1.2.26)

Updates `clap_builder` from 4.5.38 to 4.5.40
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.38...v4.5.40)

Updates `clap_derive` from 4.5.32 to 4.5.40
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.32...v4.5.40)

Updates `clap_lex` from 0.7.4 to 0.7.5
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_lex-v0.7.4...clap_lex-v0.7.5)

Updates `colorchoice` from 1.0.3 to 1.0.4
- [Commits](https://github.com/rust-cli/anstyle/compare/colorchoice-v1.0.3...colorchoice-v1.0.4)

Updates `flate2` from 1.1.1 to 1.1.2
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.1.1...1.1.2)

Updates `libz-rs-sys` from 0.5.0 to 0.5.1
- [Release notes](https://github.com/trifectatechfoundation/zlib-rs/releases)
- [Changelog](https://github.com/trifectatechfoundation/zlib-rs/blob/main/docs/release.md)
- [Commits](https://github.com/trifectatechfoundation/zlib-rs/compare/v0.5.0...v0.5.1)

Updates `memchr` from 2.7.4 to 2.7.5
- [Commits](https://github.com/BurntSushi/memchr/compare/2.7.4...2.7.5)

Updates `miniz_oxide` from 0.8.8 to 0.8.9
- [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Frommi/miniz_oxide/commits)

Updates `once_cell_polyfill` from 1.70.0 to 1.70.1
- [Changelog](https://github.com/polyfill-rs/once_cell_polyfill/blob/v1.70.1/CHANGELOG.md)
- [Commits](https://github.com/polyfill-rs/once_cell_polyfill/compare/v1.70.0...v1.70.1)

Updates `rustc-demangle` from 0.1.24 to 0.1.25
- [Commits](https://github.com/rust-lang/rustc-demangle/commits)

Updates `rustversion` from 1.0.20 to 1.0.21
- [Release notes](https://github.com/dtolnay/rustversion/releases)
- [Commits](https://github.com/dtolnay/rustversion/compare/1.0.20...1.0.21)

Updates `syn` from 2.0.101 to 2.0.102
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.101...2.0.102)

Updates `tokio` from 1.45.0 to 1.45.1
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.45.0...tokio-1.45.1)

Updates `unicode-width` from 0.1.14 to 0.2.1
- [Commits](https://github.com/unicode-rs/unicode-width/compare/v0.1.14...v0.2.1)

Updates `windows-link` from 0.1.1 to 0.1.2
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `zlib-rs` from 0.5.0 to 0.5.1
- [Release notes](https://github.com/trifectatechfoundation/zlib-rs/releases)
- [Changelog](https://github.com/trifectatechfoundation/zlib-rs/blob/main/docs/release.md)
- [Commits](https://github.com/trifectatechfoundation/zlib-rs/compare/v0.5.0...v0.5.1)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.40
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: which
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: crates
- dependency-name: getopts
  dependency-version: 0.2.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: adler2
  dependency-version: 2.0.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstream
  dependency-version: 0.6.19
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstyle
  dependency-version: 1.0.11
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstyle-parse
  dependency-version: 0.2.7
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstyle-query
  dependency-version: 1.1.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstyle-wincon
  dependency-version: 3.0.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: bumpalo
  dependency-version: 3.18.1
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: crates
- dependency-name: cc
  dependency-version: 1.2.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: clap_builder
  dependency-version: 4.5.40
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: clap_derive
  dependency-version: 4.5.40
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: clap_lex
  dependency-version: 0.7.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: colorchoice
  dependency-version: 1.0.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: flate2
  dependency-version: 1.1.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: libz-rs-sys
  dependency-version: 0.5.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: memchr
  dependency-version: 2.7.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: miniz_oxide
  dependency-version: 0.8.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: once_cell_polyfill
  dependency-version: 1.70.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: rustc-demangle
  dependency-version: 0.1.25
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: rustversion
  dependency-version: 1.0.21
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: syn
  dependency-version: 2.0.102
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: tokio
  dependency-version: 1.45.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: unicode-width
  dependency-version: 0.2.1
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: crates
- dependency-name: windows-link
  dependency-version: 0.1.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: zlib-rs
  dependency-version: 0.5.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-15 23:31:53 +06:00
dependabot[bot]
aa221acad1 build(deps): bump the crates group across 1 directory with 28 updates
Bumps the crates group with 23 updates in the /userspace/ksud_magic directory:

| Package | From | To |
| --- | --- | --- |
| [clap](https://github.com/clap-rs/clap) | `4.5.38` | `4.5.40` |
| [which](https://github.com/harryfei/which-rs) | `7.0.3` | `8.0.0` |
| [getopts](https://github.com/rust-lang/getopts) | `0.2.21` | `0.2.23` |
| [adler2](https://github.com/oyvindln/adler2) | `2.0.0` | `2.0.1` |
| [anstream](https://github.com/rust-cli/anstyle) | `0.6.18` | `0.6.19` |
| [anstyle](https://github.com/rust-cli/anstyle) | `1.0.10` | `1.0.11` |
| [anstyle-parse](https://github.com/rust-cli/anstyle) | `0.2.6` | `0.2.7` |
| [anstyle-query](https://github.com/rust-cli/anstyle) | `1.1.2` | `1.1.3` |
| [anstyle-wincon](https://github.com/rust-cli/anstyle) | `3.0.8` | `3.0.9` |
| [bumpalo](https://github.com/fitzgen/bumpalo) | `3.17.0` | `3.18.1` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.23` | `1.2.26` |
| [cfg-if](https://github.com/rust-lang/cfg-if) | `1.0.0` | `1.0.1` |
| [clap_lex](https://github.com/clap-rs/clap) | `0.7.4` | `0.7.5` |
| [colorchoice](https://github.com/rust-cli/anstyle) | `1.0.3` | `1.0.4` |
| [flate2](https://github.com/rust-lang/flate2-rs) | `1.1.1` | `1.1.2` |
| [memchr](https://github.com/BurntSushi/memchr) | `2.7.4` | `2.7.5` |
| [miniz_oxide](https://github.com/Frommi/miniz_oxide) | `0.8.8` | `0.8.9` |
| [once_cell_polyfill](https://github.com/polyfill-rs/once_cell_polyfill) | `1.70.0` | `1.70.1` |
| [rustc-demangle](https://github.com/rust-lang/rustc-demangle) | `0.1.24` | `0.1.25` |
| [rustversion](https://github.com/dtolnay/rustversion) | `1.0.20` | `1.0.21` |
| [syn](https://github.com/dtolnay/syn) | `2.0.101` | `2.0.102` |
| [tokio](https://github.com/tokio-rs/tokio) | `1.45.0` | `1.45.1` |
| [windows-link](https://github.com/microsoft/windows-rs) | `0.1.1` | `0.1.2` |



Updates `clap` from 4.5.38 to 4.5.40
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.38...clap_complete-v4.5.40)

Updates `which` from 7.0.3 to 8.0.0
- [Release notes](https://github.com/harryfei/which-rs/releases)
- [Changelog](https://github.com/harryfei/which-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/harryfei/which-rs/compare/7.0.3...8.0.0)

Updates `getopts` from 0.2.21 to 0.2.23
- [Release notes](https://github.com/rust-lang/getopts/releases)
- [Changelog](https://github.com/rust-lang/getopts/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/getopts/compare/v0.2.21...v0.2.23)

Updates `adler2` from 2.0.0 to 2.0.1
- [Changelog](https://github.com/oyvindln/adler2/blob/main/CHANGELOG.md)
- [Commits](https://github.com/oyvindln/adler2/commits)

Updates `anstream` from 0.6.18 to 0.6.19
- [Commits](https://github.com/rust-cli/anstyle/compare/anstream-v0.6.18...anstream-v0.6.19)

Updates `anstyle` from 1.0.10 to 1.0.11
- [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.10...v1.0.11)

Updates `anstyle-parse` from 0.2.6 to 0.2.7
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-parse-v0.2.6...anstyle-parse-v0.2.7)

Updates `anstyle-query` from 1.1.2 to 1.1.3
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-query-v1.1.2...anstyle-query-v1.1.3)

Updates `anstyle-wincon` from 3.0.8 to 3.0.9
- [Commits](https://github.com/rust-cli/anstyle/compare/anstyle-wincon-v3.0.8...anstyle-wincon-v3.0.9)

Updates `bumpalo` from 3.17.0 to 3.18.1
- [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fitzgen/bumpalo/compare/3.17.0...v3.18.1)

Updates `cc` from 1.2.23 to 1.2.26
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.23...cc-v1.2.26)

Updates `cfg-if` from 1.0.0 to 1.0.1
- [Release notes](https://github.com/rust-lang/cfg-if/releases)
- [Changelog](https://github.com/rust-lang/cfg-if/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cfg-if/compare/1.0.0...v1.0.1)

Updates `clap_builder` from 4.5.38 to 4.5.40
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.38...v4.5.40)

Updates `clap_derive` from 4.5.32 to 4.5.40
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.32...v4.5.40)

Updates `clap_lex` from 0.7.4 to 0.7.5
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_lex-v0.7.4...clap_lex-v0.7.5)

Updates `colorchoice` from 1.0.3 to 1.0.4
- [Commits](https://github.com/rust-cli/anstyle/compare/colorchoice-v1.0.3...colorchoice-v1.0.4)

Updates `flate2` from 1.1.1 to 1.1.2
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.1.1...1.1.2)

Updates `libz-rs-sys` from 0.5.0 to 0.5.1
- [Release notes](https://github.com/trifectatechfoundation/zlib-rs/releases)
- [Changelog](https://github.com/trifectatechfoundation/zlib-rs/blob/main/docs/release.md)
- [Commits](https://github.com/trifectatechfoundation/zlib-rs/compare/v0.5.0...v0.5.1)

Updates `memchr` from 2.7.4 to 2.7.5
- [Commits](https://github.com/BurntSushi/memchr/compare/2.7.4...2.7.5)

Updates `miniz_oxide` from 0.8.8 to 0.8.9
- [Changelog](https://github.com/Frommi/miniz_oxide/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Frommi/miniz_oxide/commits)

Updates `once_cell_polyfill` from 1.70.0 to 1.70.1
- [Changelog](https://github.com/polyfill-rs/once_cell_polyfill/blob/v1.70.1/CHANGELOG.md)
- [Commits](https://github.com/polyfill-rs/once_cell_polyfill/compare/v1.70.0...v1.70.1)

Updates `rustc-demangle` from 0.1.24 to 0.1.25
- [Commits](https://github.com/rust-lang/rustc-demangle/commits)

Updates `rustversion` from 1.0.20 to 1.0.21
- [Release notes](https://github.com/dtolnay/rustversion/releases)
- [Commits](https://github.com/dtolnay/rustversion/compare/1.0.20...1.0.21)

Updates `syn` from 2.0.101 to 2.0.102
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.101...2.0.102)

Updates `tokio` from 1.45.0 to 1.45.1
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.45.0...tokio-1.45.1)

Updates `unicode-width` from 0.1.14 to 0.2.1
- [Commits](https://github.com/unicode-rs/unicode-width/compare/v0.1.14...v0.2.1)

Updates `windows-link` from 0.1.1 to 0.1.2
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

Updates `zlib-rs` from 0.5.0 to 0.5.1
- [Release notes](https://github.com/trifectatechfoundation/zlib-rs/releases)
- [Changelog](https://github.com/trifectatechfoundation/zlib-rs/blob/main/docs/release.md)
- [Commits](https://github.com/trifectatechfoundation/zlib-rs/compare/v0.5.0...v0.5.1)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.40
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: which
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: crates
- dependency-name: getopts
  dependency-version: 0.2.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: adler2
  dependency-version: 2.0.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstream
  dependency-version: 0.6.19
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstyle
  dependency-version: 1.0.11
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstyle-parse
  dependency-version: 0.2.7
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstyle-query
  dependency-version: 1.1.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: anstyle-wincon
  dependency-version: 3.0.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: bumpalo
  dependency-version: 3.18.1
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: crates
- dependency-name: cc
  dependency-version: 1.2.26
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: cfg-if
  dependency-version: 1.0.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: clap_builder
  dependency-version: 4.5.40
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: clap_derive
  dependency-version: 4.5.40
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: clap_lex
  dependency-version: 0.7.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: colorchoice
  dependency-version: 1.0.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: flate2
  dependency-version: 1.1.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: libz-rs-sys
  dependency-version: 0.5.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: memchr
  dependency-version: 2.7.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: miniz_oxide
  dependency-version: 0.8.9
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: once_cell_polyfill
  dependency-version: 1.70.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: rustc-demangle
  dependency-version: 0.1.25
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: rustversion
  dependency-version: 1.0.21
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: syn
  dependency-version: 2.0.102
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: tokio
  dependency-version: 1.45.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: unicode-width
  dependency-version: 0.2.1
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: crates
- dependency-name: windows-link
  dependency-version: 0.1.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
- dependency-name: zlib-rs
  dependency-version: 0.5.1
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: crates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-15 23:31:36 +06:00
dependabot[bot]
c41d35db62 build(deps): bump the maven group across 1 directory with 9 updates
Bumps the maven group with 9 updates in the /manager directory:

| Package | From | To |
| --- | --- | --- |
| androidx.compose:compose-bom | `2025.05.01` | `2025.06.00` |
| androidx.lifecycle:lifecycle-runtime-ktx | `2.9.0` | `2.9.1` |
| androidx.lifecycle:lifecycle-runtime-compose | `2.9.0` | `2.9.1` |
| androidx.lifecycle:lifecycle-viewmodel-compose | `2.9.0` | `2.9.1` |
| androidx.webkit:webkit | `1.13.0` | `1.14.0` |
| [org.lsposed.libcxx:libcxx](https://github.com/LSPosed/prefab-libcxx) | `27.0.12077973` | `28.1.13356709` |
| com.android.application | `8.10.0` | `8.10.1` |
| com.android.library | `8.10.0` | `8.10.1` |
| [com.google.devtools.ksp](https://github.com/google/ksp) | `2.1.21-2.0.1` | `2.1.21-2.0.2` |



Updates `androidx.compose:compose-bom` from 2025.05.01 to 2025.06.00

Updates `androidx.lifecycle:lifecycle-runtime-ktx` from 2.9.0 to 2.9.1

Updates `androidx.lifecycle:lifecycle-runtime-compose` from 2.9.0 to 2.9.1

Updates `androidx.lifecycle:lifecycle-viewmodel-compose` from 2.9.0 to 2.9.1

Updates `androidx.lifecycle:lifecycle-runtime-compose` from 2.9.0 to 2.9.1

Updates `androidx.lifecycle:lifecycle-viewmodel-compose` from 2.9.0 to 2.9.1

Updates `androidx.webkit:webkit` from 1.13.0 to 1.14.0

Updates `org.lsposed.libcxx:libcxx` from 27.0.12077973 to 28.1.13356709
- [Commits](https://github.com/LSPosed/prefab-libcxx/compare/27.0.12077973...28.1.13356709)

Updates `com.android.application` from 8.10.0 to 8.10.1

Updates `com.android.library` from 8.10.0 to 8.10.1

Updates `com.android.library` from 8.10.0 to 8.10.1

Updates `com.google.devtools.ksp` from 2.1.21-2.0.1 to 2.1.21-2.0.2
- [Release notes](https://github.com/google/ksp/releases)
- [Commits](https://github.com/google/ksp/compare/2.1.21-2.0.1...2.1.21-2.0.2)

---
updated-dependencies:
- dependency-name: androidx.compose:compose-bom
  dependency-version: 2025.06.00
  dependency-type: direct:production
  dependency-group: maven
- dependency-name: androidx.lifecycle:lifecycle-runtime-ktx
  dependency-version: 2.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
- dependency-name: androidx.lifecycle:lifecycle-runtime-compose
  dependency-version: 2.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
- dependency-name: androidx.lifecycle:lifecycle-viewmodel-compose
  dependency-version: 2.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
- dependency-name: androidx.lifecycle:lifecycle-runtime-compose
  dependency-version: 2.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
- dependency-name: androidx.lifecycle:lifecycle-viewmodel-compose
  dependency-version: 2.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
- dependency-name: androidx.webkit:webkit
  dependency-version: 1.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: maven
- dependency-name: org.lsposed.libcxx:libcxx
  dependency-version: 28.1.13356709
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: maven
- dependency-name: com.android.application
  dependency-version: 8.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
- dependency-name: com.android.library
  dependency-version: 8.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
- dependency-name: com.android.library
  dependency-version: 8.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
- dependency-name: com.google.devtools.ksp
  dependency-version: 2.1.21-2.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-15 23:31:19 +06:00
luigimak
e5f0c733b8 Update italian translation
add developer translation, values-it/strings.xml
2025-06-15 23:26:29 +06:00
kam821
70b52f85e9 Update Polish translation
- Added missing strings
- Updated translations for refreshed strings
2025-06-15 23:26:17 +06:00
роизен
303b5192ec Update strings.xml 2025-06-15 23:26:05 +06:00
роизен
443d3a6abe Update strings.xml 2025-06-15 23:26:05 +06:00
роизен
a2a7383343 Update strings.xml 2025-06-15 23:26:05 +06:00
роизен
ed64f933f5 Update strings.xml 2025-06-15 23:26:05 +06:00
роизен
4c7ad8eac4 Update strings.xml 2025-06-15 23:26:05 +06:00
роизен
6a922febcd Update ukranian 2025-06-15 23:26:05 +06:00
Rifat Azad
71eba5df8b manager: disable module and superuser navigation if sucompat is disabled and also show an indicator in status card 2025-06-15 22:07:15 +06:00
Rifat Azad
f1ef0afc20 manager: finish activity after flashing module intent is completed 2025-06-15 21:09:31 +06:00
Rifat Azad
844c9f94e9 manager: fix flashing lkm duplication 2025-06-15 20:13:32 +06:00
Rifat Azad
07a4d3457c manager: add separate developer menu 2025-06-15 13:00:30 +06:00
Rifat Azad
8c9728df95 manager: fix zip not flashing from content:// uri 2025-06-15 12:09:32 +06:00
Rifat Azad
14ec1194e4 manager: add support for opening zip file and directly flash module 2025-06-15 07:09:13 +06:00
Rifat Azad
a37f398cc7 kernel/Makefile: check kernelsu driver version from online git repo first, if fails then check local .git and if that also fails then use hardcoded fallback 2025-06-14 22:52:10 +06:00
backslashxx
80bd797737 kernel: ksud: remove remove read_iter requirement
nothing uses this on old kernels, so even backporting this to file_operations
is not really needed

https://elixir.bootlin.com/linux/v3.16.85/source/include/linux/fs.h#L1487

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-14 20:14:12 +06:00
backslashxx
600d9ce5d2 kernel: throne_tracker: resolve s_magic for < 3.9
throne_tracker, cross-fs avoidance:
f_inode is f_path.dentry->d_inode
so file->f_inode->i_sb->s_magic is file->f_path.dentry->d_inode->i_sb->s_magic

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-14 20:14:03 +06:00
backslashxx
f15d9b18e9 kernel: ksud: d_is_reg to IS_REG
d_is_reg requires 4.0
 - e36cb0b89c
IS_REG is still there on 6.15 so I do NOT see any issues forcing it for all.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-14 20:13:13 +06:00
backslashxx
aa19e8c609 kernel: throne_tracker: add strscpy/strlcpy compat
strscpy requires 4.3
strscpy on this usage can be replaced with strncpy + null term.
kernel gives us an option though.
strlcpy is fast af, hotrod fast. It’s just memcpy + null term, so lets go with that.
it got dropped in 6.8 due to risk concerns, so for those, lets use og strscpy.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-14 20:13:06 +06:00
backslashxx
2b2320000c kernel: throne_tracker: remove unneeded check here
come to think of it, this part is only about folders
2025-06-14 20:12:51 +06:00
backslashxx
06135cc827 kernel: apk_sign: loop file open on is_manager_apk
lets loop on this and wait for installation to finish

this is the third race.
2025-06-14 20:12:14 +06:00
backslashxx
fc58bdf0e2 kernel: throne_tracker: harden packages.list checker further 2025-06-14 20:08:53 +06:00
backslashxx
9b5e60912d kernel: throne_tracker, apk_sign: functionify d_lock spinlock check 2025-06-14 20:08:23 +06:00
backslashxx
c108a8ed32 kernel: throne_tracker: harden track_throne_function file read
this probably wont happen, but just to make sure, we dont block the rename now
so there is really a chance that this does not exist yet when the kthread runs.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-14 20:07:24 +06:00
F-19-F
adce657583 kernel: ksud: provide is_ksu_transition check v2
context: this is known by many as `selinux hook`, `4.9 hook`

add is_ksu_transition check which allows ksud execution under nosuid.
it also eases up integration on 3.X kernels that does not have check_nnp_nosuid.

Usage:
	if (is_ksu_transition(old_tsec, new_tsec))
		return 0;

on either check_nnp_nosuid or selinux_bprm_set_creds (after execve sid reset)

reference: dfe003c9fd

taken from:
`allow init exec ksud under nosuid`
- 3df9df42a6
- https://github.com/tiann/KernelSU/pull/166#issue-1565872173

250611-edit:
- remove ksu_execveat_hook entry check
- turns out some devices needs the transition for multiple times

Reported-by: edenadversary <143865198+edenadversary@users.noreply.github.com>
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-14 20:07:16 +06:00
rsuntk
d6601e1e54 kernel: core_hook: fix refcount leaks on try_umount (#2635)
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-14 20:03:30 +06:00
backslashxx
0d4efa649f kernel: throne_tracker: avoid cross-fs traversal using s_magic check (#2633)
Skip directories that does NOT have the same magic as /data/app.
This is to avoid scanning incfs and any other stacked filesystems.

While this is way dumber, it's way cheaper.
no kern_path(), no missable path_put(), no ref handling.

This supercedes
`throne_tracker: avoid cross fs access
(https://github.com/tiann/KernelSU/pull/2626)`
- upstream
0b6998b474

Signed-off-by: backslashxx
<118538522+backslashxx@users.noreply.github.com>
2025-06-14 20:03:04 +06:00
Wang Han
85f4e6ac27 Switch to prepare_creds/commit_creds (#2631)
Update API as per kernel doc recommends, also fix setup_groups refcount
leak while at it.
2025-06-14 20:01:36 +06:00
Rifat Azad
c91f9c18ec Revert "kernel: ksud, throne_tracker: small changes for UL"
This reverts commit c4deee1e49.
2025-06-14 19:54:59 +06:00
Rifat Azad
bf35f73430 Revert "kernel: throne_tracker: move throne_tracker to kthread"
This reverts commit 6a6fc07cd4.
2025-06-14 19:54:36 +06:00
Rifat Azad
ad290a51a0 manager: fully polish and refactor module card ui 2025-06-12 23:40:14 +06:00
Rifat Azad
d218346613 manager: keep mount system preference persistent without breaking rootAvailable() checks 2025-06-12 21:50:16 +06:00
Rifat Azad
502e5599fe manager: improve module card ui 2025-06-12 21:05:40 +06:00
Rifat Azad
11fb52b929 manager: merge legacy and revamped module card ui, also tapping the card open webui when available and actions when available but if both are available then prefer webui 2025-06-12 13:03:41 +06:00
Rifat Azad
057388ccef manager: do not go at the start of the superuser list and stay where you were after app profile changes (resolves #491) 2025-06-12 10:42:53 +06:00
Rifat Azad
67759ad723 manager: update app state upon app profile changes
properly update the superuser app list state after changes have been made to app profile
2025-06-12 10:18:51 +06:00
Rifat Azad
f231cbdba7 Revert "manager: refresh superuser applist on appprofile exit"
This reverts commit fcbb02a115.
2025-06-12 08:46:38 +06:00
Suraj J Pai
7abc9bc821 [BUGFIX] manager: Fix Module Flashing fails when orientation changes (#503)
The issue is caused by re-rendering of Activity when orientation changes.
All states are reset when it is re-rendered. Using ViewModel to manage zipUri fixes the issue.

Fixes issue: https://github.com/KernelSU-Next/KernelSU-Next/issues/488
2025-06-12 04:44:45 +06:00
GMárton
e7697d86fe Update hungarian translation (#489)
* Update hungarian translation

* Fix typo

---------

Co-authored-by: Marty <marton.garamszegi@mptrdev.com>
2025-06-11 04:30:29 +06:00
1alessandro1
68394fddd5 Update doc (#485) 2025-06-11 04:30:14 +06:00
cvnertnc
90d34bf511 Manager: update values-tr/strings.xml (#469) 2025-06-11 04:29:47 +06:00
luigimak
236fbc7615 Update Italian Translation (#461)
* Update Italian Translation

values-it/strings.xml

* fix use_webuix_summary

Update values-it/strings.xml

* Update values-it/strings.xml

* Add module_size values-it/strings.xml

* Add settings_banner values-it/strings.xml

* fix settings_banner
2025-06-11 04:29:31 +06:00
mr_vokintos
6871cbdba7 Update Russian (#466)
* Update strings.xml

Update Russian

* Update strings.xml

* Update strings.xml
2025-06-11 04:29:15 +06:00
AxelPLN(Axel Yinjia Huang)
38a9949211 Update manager translations for zh-rCN & zh-rTW (#456)
* Update translations for zh-rCN &zh-rTW to 0a42dbf

* Add zh-rCN & zh-rTW translations for functions as legacyUI & module banner and so on.

Improve translations.
2025-06-11 04:27:58 +06:00
igor
9fba0faa43 Update portuguese translation (#453)
* Update portuguese translation

* Update strings.xml

* Update strings.xml

* Update README.md

* Update README_PT-BR.md

* Update strings.xml

* Update strings.xml
2025-06-11 04:26:43 +06:00
Caner Karaca
b1250b002e Workflow Updates (#481)
* Update

* Use ubuntu-22.04

* Revert some renamings

* Create renovate.json

* oops
2025-06-11 04:23:22 +06:00
Rifat Azad
10f7d5cf50 Revert "manager: keep mount system preference persistent"
This reverts commit 609926bff1.
2025-06-10 02:31:14 +06:00
rifsxd
0c883ddfd6 manager: let module banner be set locally from module dir
ex: banner=banner.png , banner=example.webp banner=temp/hello.jpg
if banner string value starts with http, https then it will try to fetch from online.

Co-authored-by: fatalcoder524 <11532648+fatalcoder524@users.noreply.github.com>
2025-06-06 04:09:16 +06:00
Paul
3921175e4c kernel: core_hook: intercept devpts via security_inode_permission LSM (#480)
`ksu handles devpts with selinux lsm hook` - aviraxp

- no, not yet, but yes we can, thats a good idea.

This change tries to do that, so instead of hooking pts_unix98_lookup or
devpts_get_priv, we just watch security_inode_permission, if its devpts,
pass it along to the original handler.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-05 06:20:53 +06:00
5ec1cff
84fdcf8bf5 throne_tracker: avoid cross fs access 2025-06-03 03:30:54 +06:00
rifsxd
886cfd5a33 manager: adjusted module banner fade opacity 2025-06-03 03:28:42 +06:00
rifsxd
aea384bdd4 manager: do dynamic fade for banner based on monet when available 2025-06-03 01:49:57 +06:00
rifsxd
84695cea71 manager: do white fade for banner when on light mode 2025-06-03 00:58:58 +06:00
rifsxd
f91afe6c46 manager: add module background banners"
module devs can add banners for their modules through module.prop config

Example:

banner=https://something.com/banner.png
2025-06-03 00:34:37 +06:00
rifsxd
3f7e731df6 manager: fix update tag attached to wrong module after using sort options (fix #473) 2025-06-02 15:34:30 +06:00
rifsxd
582662dce9 manager: fix back gestures conflicting with LKM warning window (fix #474) 2025-06-02 15:12:59 +06:00
rifsxd
f3b49723e8 manager: add sorting by size for module list 2025-06-01 21:03:04 +06:00
backslashxx
c4deee1e49 kernel: ksud, throne_tracker: small changes for UL
Safe Ultra-Legacy changes that don't deserve their own commit

d_is_reg requires 4.0
 - e36cb0b89c
IS_REG is still there on 6.15 so I do NOT see any issues forcing it for all.

strscpy requires 4.3
strscpy on this usage can be replaced with strncpy + null term.
kernel gives us an option though.
strlcpy is fast af, hotrod fast. It’s just memcpy + null term, so lets go with that.
it got dropped in 6.8 due to risk concerns, so for those, lets use og strscpy.
ref: openwrt/packages #26453

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-01 20:09:20 +06:00
Yaroslav Zviezda
6a6fc07cd4 kernel: throne_tracker: move throne_tracker to kthread
Runs throne_tracker() in kthread instead of blocking the caller.
Prevents full lockup during installation and removing the manager.

This also looks for manager UID in /data/system/packages.list, not
/data/system/packages.list.tmp

Nice additional side effect is a faster booting.

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-Authored-By: backslashxx <118538522+backslashxx@users.noreply.github.com>
2025-06-01 20:03:38 +06:00
rifsxd
d8cb7ef772 manager: fix module sorting state when module list is null initially before modules are fetched (this should fix #470) 2025-06-01 19:47:43 +06:00
rifsxd
dddf2f06a0 manager: show reboot button when flashing LKM directly and inactive slot 2025-06-01 15:46:25 +06:00
rifsxd
e7e935aeb2 manager: added module size label 2025-06-01 15:37:13 +06:00
rifsxd
cb146200aa manager: output full logs of actions and flash modules when developer option is enabled 2025-06-01 04:05:35 +06:00
rifsxd
609926bff1 manager: keep mount system preference persistent 2025-06-01 03:37:10 +06:00
rifsxd
8803058521 manager: added amoled theme for non material u devices 2025-06-01 02:33:02 +06:00
rifsxd
c74805b12b manager: autoexpand infocard when dev option is enabled 2025-06-01 01:43:08 +06:00
rifsxd
43870237fc manager: removed unused imports from backuprestore.kt 2025-06-01 01:17:44 +06:00
rifsxd
ca24085b5b manager: add a separate customization screen in settings 2025-06-01 01:17:35 +06:00
rifsxd
93191c2b8b manager: add legacy ui toggle 2025-06-01 00:20:23 +06:00
160 changed files with 11494 additions and 5687 deletions

View File

@@ -60,8 +60,9 @@ body:
value: |
- Device:
- OS Version:
- KernelSU Version:
- Kernel Version:
- KSUN Driver Version:
- KSUN Manager Version:
validations:
required: true

View File

@@ -1,5 +1 @@
blank_issues_enabled: false
contact_links:
- name: Feature Request
url: https://t.me/ksunext/578
about: "We do not accept external Feature Requests anymore, check the link for more details."
blank_issues_enabled: false

41
.github/ISSUE_TEMPLATE/request.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Feature Request
description: Suggest a new feature or improvement for KernelSU Next.
title: "[Feature] <short description>"
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to suggest a feature! Please fill out the following details.
- type: textarea
id: problem
attributes:
label: "Is your feature request related to a problem?"
description: "A clear and concise description of what the problem is. Ex: I'm always frustrated when..."
placeholder: "Describe the problem or need."
validations:
required: false
- type: textarea
id: solution
attributes:
label: "Describe the solution you'd like"
description: "A clear and concise description of what you want to happen."
placeholder: "Describe your proposed solution."
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: "Describe alternatives you've considered"
description: "A clear and concise description of any alternative solutions or features you've considered."
placeholder: "List any alternatives."
validations:
required: false
- type: textarea
id: additional
attributes:
label: "Additional context"
description: "Add any other context or screenshots about the feature request here."
placeholder: "Additional context or screenshots."
validations:
required: false

View File

@@ -37,7 +37,7 @@ on:
jobs:
build:
name: Build ${{ inputs.version_name }}
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@master

View File

@@ -7,9 +7,9 @@ jobs:
uses: ./.github/workflows/gki-kernel.yml
with:
version: android12-5.10
version_name: android12-5.10.233
tag: android12-5.10-2025-02
os_patch_level: 2025-02
version_name: android12-5.10.236
tag: android12-5.10-2025-05
os_patch_level: 2025-05
patch_path: "5.10"
debug: true
build-debug-kernel-a13:
@@ -17,11 +17,11 @@ jobs:
matrix:
include:
- version: "5.10"
sub_level: 234
os_patch_level: 2025-03
sub_level: 236
os_patch_level: 2025-05
- version: "5.15"
sub_level: 178
os_patch_level: 2025-03
sub_level: 180
os_patch_level: 2025-05
uses: ./.github/workflows/gki-kernel.yml
with:
version: android13-${{ matrix.version }}
@@ -34,11 +34,11 @@ jobs:
matrix:
include:
- version: "5.15"
sub_level: 178
os_patch_level: 2025-03
sub_level: 180
os_patch_level: 2025-05
- version: "6.1"
sub_level: 129
os_patch_level: 2025-04
sub_level: 138
os_patch_level: 2025-06
uses: ./.github/workflows/gki-kernel.yml
with:
version: android14-${{ matrix.version }}
@@ -51,8 +51,8 @@ jobs:
matrix:
include:
- version: "6.6"
sub_level: 82
os_patch_level: 2025-04
sub_level: 89
os_patch_level: 2025-06
uses: ./.github/workflows/gki-kernel.yml
with:
version: android15-${{ matrix.version }}

View File

@@ -21,14 +21,14 @@ jobs:
strategy:
matrix:
include:
- sub_level: 209
os_patch_level: 2024-05
- sub_level: 218
os_patch_level: 2024-08
- sub_level: 226
os_patch_level: 2024-11
- sub_level: 233
os_patch_level: 2025-02
- sub_level: 236
os_patch_level: 2025-05
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:
@@ -114,7 +114,7 @@ jobs:
uses: ./.github/workflows/gki-kernel.yml
with:
version: android12-5.10
version_name: android12-5.10.223
tag: android12-5.10-2024-11
os_patch_level: 2024-11
version_name: android12-5.10.236
tag: android12-5.10-2025-05
os_patch_level: 2025-05
patch_path: "5.10"

View File

@@ -21,9 +21,6 @@ jobs:
strategy:
matrix:
include:
- version: "5.10"
sub_level: 209
os_patch_level: 2024-05
- version: "5.10"
sub_level: 210
os_patch_level: 2024-06
@@ -42,9 +39,9 @@ jobs:
- version: "5.10"
sub_level: 234
os_patch_level: 2025-03
- version: "5.15"
sub_level: 148
os_patch_level: 2024-05
- version: "5.10"
sub_level: 236
os_patch_level: 2025-05
- version: "5.15"
sub_level: 149
os_patch_level: 2024-07
@@ -63,6 +60,9 @@ jobs:
- version: "5.15"
sub_level: 178
os_patch_level: 2025-03
- version: "5.15"
sub_level: 180
os_patch_level: 2025-05
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:
@@ -149,11 +149,11 @@ jobs:
matrix:
include:
- version: "5.10"
sub_level: 234
os_patch_level: 2025-03
sub_level: 236
os_patch_level: 2025-05
- version: "5.15"
sub_level: 178
os_patch_level: 2025-03
sub_level: 180
os_patch_level: 2025-05
uses: ./.github/workflows/gki-kernel.yml
with:
version: android13-${{ matrix.version }}

View File

@@ -21,9 +21,6 @@ jobs:
strategy:
matrix:
include:
- version: "5.15"
sub_level: 148
os_patch_level: 2024-05
- version: "5.15"
sub_level: 149
os_patch_level: 2024-06
@@ -45,9 +42,9 @@ jobs:
- version: "5.15"
sub_level: 178
os_patch_level: 2025-03
- version: "6.1"
sub_level: 75
os_patch_level: 2024-05
- version: "5.15"
sub_level: 180
os_patch_level: 2025-05
- version: "6.1"
sub_level: 78
os_patch_level: 2024-06
@@ -81,6 +78,12 @@ jobs:
- version: "6.1"
sub_level: 129
os_patch_level: 2025-04
- version: "6.1"
sub_level: 134
os_patch_level: 2025-05
- version: "6.1"
sub_level: 138
os_patch_level: 2025-06
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:
@@ -167,11 +170,11 @@ jobs:
matrix:
include:
- version: "5.15"
sub_level: 178
os_patch_level: 2025-03
sub_level: 180
os_patch_level: 2025-05
- version: "6.1"
sub_level: 129
os_patch_level: 2025-04
sub_level: 138
os_patch_level: 2025-06
uses: ./.github/workflows/gki-kernel.yml
with:
version: android14-${{ matrix.version }}

View File

@@ -48,6 +48,12 @@ jobs:
- version: "6.6"
sub_level: 82
os_patch_level: 2025-04
- version: "6.6"
sub_level: 87
os_patch_level: 2025-05
- version: "6.6"
sub_level: 89
os_patch_level: 2025-06
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:
@@ -134,8 +140,8 @@ jobs:
matrix:
include:
- version: "6.6"
sub_level: 82
os_patch_level: 2025-04
sub_level: 89
os_patch_level: 2025-06
uses: ./.github/workflows/gki-kernel.yml
with:
version: android15-${{ matrix.version }}

137
.github/workflows/build-kernel-arcvm.yml vendored Normal file
View File

@@ -0,0 +1,137 @@
name: Build Kernel - ChromeOS ARCVM
on:
push:
branches: ["next"]
paths:
- ".github/workflows/build-kernel-arcvm.yml"
- "kernel/**"
pull_request:
branches: ["next"]
paths:
- ".github/workflows/build-kernel-arcvm.yml"
- "kernel/**"
workflow_call:
workflow_dispatch:
env:
git_tag: chromeos-5.10-arcvm
jobs:
build:
if: github.event_name != 'pull_request' || (github.event_name == 'pull_request' && !github.event.pull_request.draft)
strategy:
matrix:
include:
- arch: x86_64
kernel_image_name: bzImage
build_config: build.config.gki.x86_64
defconfig: x86_64_arcvm_defconfig
- arch: arm64
kernel_image_name: Image
build_config: build.config.gki.aarch64
defconfig: arm64_arcvm_defconfig
name: Build ChromeOS ARCVM kernel
runs-on: ubuntu-22.04
env:
LTO: thin
ROOT_DIR: /
KERNEL_DIR: ${{ github.workspace }}/kernel
steps:
- name: Install Build Tools
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends bc \
bison build-essential ca-certificates flex git gnupg \
libelf-dev libssl-dev lsb-release software-properties-common wget \
libncurses-dev binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu nuget gzip \
rsync python3 device-tree-compiler
sudo ln -s --force python3 /usr/bin/python
export LLVM_VERSION=14
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh $LLVM_VERSION
rm ./llvm.sh
sudo ln -s --force /usr/bin/clang-$LLVM_VERSION /usr/bin/clang
sudo ln -s --force /usr/bin/ld.lld-$LLVM_VERSION /usr/bin/ld.lld
sudo ln -s --force /usr/bin/llvm-objdump-$LLVM_VERSION /usr/bin/llvm-objdump
sudo ln -s --force /usr/bin/llvm-ar-$LLVM_VERSION /usr/bin/llvm-ar
sudo ln -s --force /usr/bin/llvm-nm-$LLVM_VERSION /usr/bin/llvm-nm
sudo ln -s --force /usr/bin/llvm-strip-$LLVM_VERSION /usr/bin/llvm-strip
sudo ln -s --force /usr/bin/llvm-objcopy-$LLVM_VERSION /usr/bin/llvm-objcopy
sudo ln -s --force /usr/bin/llvm-readelf-$LLVM_VERSION /usr/bin/llvm-readelf
sudo ln -s --force /usr/bin/clang++-$LLVM_VERSION /usr/bin/clang++
- name: Checkout KernelSU-Next
uses: actions/checkout@v4
with:
path: KernelSU-Next
fetch-depth: 0
- name: Setup kernel source
run: git clone https://chromium.googlesource.com/chromiumos/third_party/kernel.git -b ${{ env.git_tag }} --depth=1
- name: Extract version from Makefile
working-directory: kernel
run: |
VERSION=$(grep -E '^VERSION = ' Makefile | awk '{print $3}')
PATCHLEVEL=$(grep -E '^PATCHLEVEL = ' Makefile | awk '{print $3}')
SUBLEVEL=$(grep -E '^SUBLEVEL = ' Makefile | awk '{print $3}')
echo "ChromeOS ARCVM Linux kernel version: $VERSION.$PATCHLEVEL.$SUBLEVEL"
echo "version=$VERSION.$PATCHLEVEL.$SUBLEVEL" >> $GITHUB_ENV
- name: Setup KernelSU-Next
working-directory: kernel
run: |
echo "[+] KernelSU-Next setup"
KERNEL_ROOT=$GITHUB_WORKSPACE/kernel
echo "[+] KERNEL_ROOT: $KERNEL_ROOT"
echo "[+] Copy KernelSU-Next driver to $KERNEL_ROOT/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU-Next/kernel $KERNEL_ROOT/drivers/kernelsu-next
echo "[+] Add KernelSU-Next driver to Makefile"
DRIVER_MAKEFILE=$KERNEL_ROOT/drivers/Makefile
DRIVER_KCONFIG=$KERNEL_ROOT/drivers/Kconfig
grep -q "kernelsu-next" "$DRIVER_MAKEFILE" || printf "\nobj-\$(CONFIG_KSU) += kernelsu-next/\n" >> "$DRIVER_MAKEFILE"
grep -q "kernelsu-next" "$DRIVER_KCONFIG" || sed -i "/endmenu/i\\source \"drivers/kernelsu-next/Kconfig\"" "$DRIVER_KCONFIG"
echo "[+] Apply KernelSU patches"
cd $KERNEL_ROOT && git apply $GITHUB_WORKSPACE/KernelSU-Next/.github/patches/5.10/*.patch || echo "[-] No patch found"
echo "[+] Patch script/setlocalversion"
sed -i 's/-dirty//g' $KERNEL_ROOT/scripts/setlocalversion
echo "[+] KernelSU-Next setup done."
cd $GITHUB_WORKSPACE/KernelSU-Next
KSU_VERSION=$(($(git rev-list --count HEAD) + 10200))
echo "KernelSU-Next version: $KSU_VERSION"
echo "kernelsu-next_version=$KSU_VERSION" >> $GITHUB_ENV
- name: Build Kernel
working-directory: kernel
env:
KERNEL_IMAGE_NAME: ${{ matrix.kernel_image_name }}
ARCH: ${{ matrix.arch }}
run: |
set -a && . ${{ matrix.build_config }}; set +a
export DEFCONFIG=${{ matrix.defconfig }}
if [ ! -z ${{ vars.EXPECTED_SIZE }} ] && [ ! -z ${{ vars.EXPECTED_HASH }} ]; then
export KSU_EXPECTED_SIZE=${{ vars.EXPECTED_SIZE }}
export KSU_EXPECTED_HASH=${{ vars.EXPECTED_HASH }}
fi
make LLVM=1 LLVM_IAS=1 DEPMOD=depmod DTC=dtc O=${PWD} mrproper
make LLVM=1 LLVM_IAS=1 DEPMOD=depmod DTC=dtc O=${PWD} ${DEFCONFIG} < /dev/null
scripts/config --file .config -e LTO_CLANG -d LTO_NONE -e LTO_CLANG_THIN -d LTO_CLANG_FULL -e THINLTO
make LLVM=1 LLVM_IAS=1 DEPMOD=depmod DTC=dtc O=${PWD} -j$(nproc) ${KERNEL_IMAGE_NAME} modules prepare-objtool
ls -l -h ${PWD}/arch/${ARCH}/boot
echo "file_path=${PWD}/arch/${ARCH}/boot/${KERNEL_IMAGE_NAME}" >> $GITHUB_ENV
- name: Upload kernel-ARCVM-${{ matrix.arch }}-${{ env.version }}
uses: actions/upload-artifact@v4
with:
name: kernel-ARCVM-${{ matrix.arch }}-${{ env.version }}
path: "${{ env.file_path }}"

39
.github/workflows/build-kernel-avd.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Build Kernel - AVD
on:
push:
branches: ["next"]
paths:
- ".github/workflows/build-kernel-avd.yml"
- ".github/workflows/avd-kernel.yml"
- "kernel/**"
pull_request:
branches: ["next"]
paths:
- ".github/workflows/build-kernel-avd.yml"
- ".github/workflows/avd-kernel.yml"
- "kernel/**"
workflow_call:
workflow_dispatch:
jobs:
build-kernel:
if: github.event_name != 'pull_request' && github.ref != 'refs/heads/checkci'
uses: ./.github/workflows/avd-kernel.yml
secrets: inherit
strategy:
matrix:
include:
- version: "android-14-avd_x86_64"
manifest: "android-14-avd_x86_64.xml"
arch: "x86_64"
- version: "android-15-avd_aarch64"
manifest: "android-15-avd_aarch64.xml"
arch: "aarch64"
- version: "android-15-avd_x86_64"
manifest: "android-15-avd_x86_64.xml"
arch: "x86_64"
with:
version_name: ${{ matrix.version }}
manifest_name: ${{ matrix.manifest }}
arch: ${{ matrix.arch }}
debug: true

View File

@@ -15,23 +15,23 @@ jobs:
matrix:
include:
- version: "android12-5.10"
sub_level: 233
os_patch_level: 2025-02
sub_level: 236
os_patch_level: 2025-05
- version: "android13-5.10"
sub_level: 234
os_patch_level: 2025-03
sub_level: 236
os_patch_level: 2025-05
- version: "android13-5.15"
sub_level: 178
os_patch_level: 2025-03
sub_level: 180
os_patch_level: 2025-05
- version: "android14-5.15"
sub_level: 178
os_patch_level: 2025-03
sub_level: 180
os_patch_level: 2025-05
- version: "android14-6.1"
sub_level: 129
os_patch_level: 2025-04
sub_level: 138
os_patch_level: 2025-06
- version: "android15-6.6"
sub_level: 82
os_patch_level: 2025-04
sub_level: 89
os_patch_level: 2025-06
uses: ./.github/workflows/gki-kernel.yml
with:
version: ${{ matrix.version }}

View File

@@ -19,12 +19,48 @@ on:
workflow_dispatch:
jobs:
check-cache:
runs-on: ubuntu-latest
outputs:
cache-hit: ${{ steps.cache-artifacts.outputs.cache-hit }}
cache-key: ${{ steps.generate-cache-key.outputs.cache-key }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate cache key from source files
id: generate-cache-key
run: |
# Calculate hash of all files except manager directory
HASH=$(find . -type f \
-not -path "./manager/*" \
-not -path "./.git/*" \
-not -path "./.github/workflows/build-manager-ci.yml" \
-exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
echo "cache-key=artifacts-$HASH" >> $GITHUB_OUTPUT
echo "Generated cache key: artifacts-$HASH"
- name: Check for cached artifacts
id: cache-artifacts
uses: actions/cache@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ steps.generate-cache-key.outputs.cache-key }}
build-lkm:
needs: check-cache
if: needs.check-cache.outputs.cache-hit != 'true'
uses: ./.github/workflows/build-lkm.yml
secrets: inherit
build-susfsd:
needs: build-lkm
needs: [check-cache, build-lkm]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
@@ -34,7 +70,8 @@ jobs:
os: ${{ matrix.os }}
build-ksud:
needs: build-susfsd
needs: [check-cache, build-susfsd]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
@@ -49,8 +86,43 @@ jobs:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
cache-artifacts:
needs: [check-cache, build-ksud]
if: needs.check-cache.outputs.cache-hit != 'true'
runs-on: ubuntu-latest
steps:
- name: Download susfsd artifacts
uses: actions/download-artifact@v4
with:
name: susfsd-linux-android
path: cached-artifacts/susfsd
- name: Download ksud_overlayfs artifacts
uses: actions/download-artifact@v4
with:
pattern: ksud_overlayfs-*
path: cached-artifacts/ksud_overlayfs
merge-multiple: true
- name: Download ksud_magic artifacts
uses: actions/download-artifact@v4
with:
pattern: ksud_magic-*
path: cached-artifacts/ksud_magic
merge-multiple: true
- name: Cache artifacts
uses: actions/cache/save@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ needs.check-cache.outputs.cache-key }}
build-manager:
needs: build-ksud
needs: [check-cache, build-ksud]
if: always() && needs.check-cache.result == 'success' && (needs.check-cache.outputs.cache-hit == 'true' || needs.build-ksud.result == 'success')
runs-on: ubuntu-latest
defaults:
run:
@@ -92,87 +164,122 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Restore cached artifacts if cache hit
- name: Restore cached artifacts
if: needs.check-cache.outputs.cache-hit == 'true'
uses: actions/cache/restore@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ needs.check-cache.outputs.cache-key }}
# Download fresh artifacts if cache miss
- name: Download susfsd
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: susfsd-linux-android
path: .
- name: Copy susfsd to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
mkdir -p app/src/main/jniLibs/armeabi-v7a
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
# Download fresh ksud artifacts if cache miss
- name: Download arm64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-aarch64-linux-android
path: ksud_overlayfs
- name: Download arm ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-armv7-linux-androideabi
path: ksud_overlayfs
- name: Download x86_64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-x86_64-linux-android
path: ksud_overlayfs
- name: Copy ksud_overlayfs to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
- name: Download arm64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-aarch64-linux-android
path: ksud_magic
- name: Download arm ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-armv7-linux-androideabi
path: ksud_magic
- name: Download x86_64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-x86_64-linux-android
path: ksud_magic
# Copy artifacts to jniLibs (works for both cached and fresh)
- name: Copy susfsd to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/susfsd/arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cp -f ../cached-artifacts/susfsd/armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
cp -f ../cached-artifacts/susfsd/x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
else
# Copy from fresh artifacts
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
fi
- name: Copy ksud_overlayfs to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../cached-artifacts/ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../cached-artifacts/ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
else
# Copy from fresh artifacts
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
fi
- name: Copy ksud_magic to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../cached-artifacts/ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../cached-artifacts/ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
else
# Copy from fresh artifacts
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
fi
- name: Build with Gradle
run: |

View File

@@ -21,12 +21,48 @@ on:
- cron: "0 12 * * *" # 6 PM UTC+6 | 12 PM UTC
jobs:
check-cache:
runs-on: ubuntu-latest
outputs:
cache-hit: ${{ steps.cache-artifacts.outputs.cache-hit }}
cache-key: ${{ steps.generate-cache-key.outputs.cache-key }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate cache key from source files
id: generate-cache-key
run: |
# Calculate hash of all files except manager directory
HASH=$(find . -type f \
-not -path "./manager/*" \
-not -path "./.git/*" \
-not -path "./.github/workflows/build-manager-spoofed.yml" \
-exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
echo "cache-key=artifacts-spoofed-$HASH" >> $GITHUB_OUTPUT
echo "Generated cache key: artifacts-spoofed-$HASH"
- name: Check for cached artifacts
id: cache-artifacts
uses: actions/cache@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ steps.generate-cache-key.outputs.cache-key }}
build-lkm:
needs: check-cache
if: needs.check-cache.outputs.cache-hit != 'true'
uses: ./.github/workflows/build-lkm.yml
secrets: inherit
build-susfsd:
needs: build-lkm
needs: [check-cache, build-lkm]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
@@ -36,7 +72,8 @@ jobs:
os: ${{ matrix.os }}
build-ksud:
needs: build-susfsd
needs: [check-cache, build-susfsd]
if: needs.check-cache.outputs.cache-hit != 'true'
strategy:
matrix:
include:
@@ -51,8 +88,43 @@ jobs:
target: ${{ matrix.target }}
os: ${{ matrix.os }}
cache-artifacts:
needs: [check-cache, build-ksud]
if: needs.check-cache.outputs.cache-hit != 'true'
runs-on: ubuntu-latest
steps:
- name: Download susfsd artifacts
uses: actions/download-artifact@v4
with:
name: susfsd-linux-android
path: cached-artifacts/susfsd
- name: Download ksud_overlayfs artifacts
uses: actions/download-artifact@v4
with:
pattern: ksud_overlayfs-*
path: cached-artifacts/ksud_overlayfs
merge-multiple: true
- name: Download ksud_magic artifacts
uses: actions/download-artifact@v4
with:
pattern: ksud_magic-*
path: cached-artifacts/ksud_magic
merge-multiple: true
- name: Cache artifacts
uses: actions/cache/save@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ needs.check-cache.outputs.cache-key }}
build-manager:
needs: build-ksud
needs: [check-cache, build-ksud]
if: always() && needs.check-cache.result == 'success' && (needs.check-cache.outputs.cache-hit == 'true' || needs.build-ksud.result == 'success')
runs-on: ubuntu-latest
defaults:
run:
@@ -99,75 +171,122 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Restore cached artifacts if cache hit
- name: Restore cached artifacts
if: needs.check-cache.outputs.cache-hit == 'true'
uses: actions/cache/restore@v4
with:
path: |
cached-artifacts/susfsd
cached-artifacts/ksud_overlayfs
cached-artifacts/ksud_magic
key: ${{ needs.check-cache.outputs.cache-key }}
# Download fresh artifacts if cache miss
- name: Download susfsd
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: susfsd-linux-android
path: .
- name: Copy susfsd to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
mkdir -p app/src/main/jniLibs/armeabi-v7a
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
# Download fresh ksud artifacts if cache miss
- name: Download arm64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-aarch64-linux-android
path: ksud_overlayfs
- name: Download arm ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-armv7-linux-androideabi
path: ksud_overlayfs
- name: Download x86_64 ksud_overlayfs
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_overlayfs-x86_64-linux-android
path: ksud_overlayfs
- name: Copy ksud_overlayfs to app jniLibs
run: |
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
- name: Download arm64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-aarch64-linux-android
path: ksud_magic
- name: Download arm ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-armv7-linux-androideabi
path: ksud_magic
- name: Download x86_64 ksud_magic
if: needs.check-cache.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: ksud_magic-x86_64-linux-android
path: ksud_magic
# Copy artifacts to jniLibs (works for both cached and fresh)
- name: Copy susfsd to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/susfsd/arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cp -f ../cached-artifacts/susfsd/armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
cp -f ../cached-artifacts/susfsd/x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
else
# Copy from fresh artifacts
cp -f ../arm64-v8a/susfsd ../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cp -f ../armeabi-v7a/susfsd ../manager/app/src/main/jniLibs/armeabi-v7a/libsusfsd.so
cp -f ../x86_64/susfsd ../manager/app/src/main/jniLibs/x86_64/libsusfsd.so
fi
- name: Copy ksud_overlayfs to app jniLibs
run: |
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../cached-artifacts/ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../cached-artifacts/ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
else
# Copy from fresh artifacts
cp -f ../ksud_overlayfs/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_overlayfs.so
cp -f ../ksud_overlayfs/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_overlayfs.so
fi
- name: Copy ksud_magic to app jniLibs
run: |
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
mkdir -p app/src/main/jniLibs/arm64-v8a
mkdir -p app/src/main/jniLibs/armeabi-v7a
mkdir -p app/src/main/jniLibs/x86_64
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
if [ "${{ needs.check-cache.outputs.cache-hit }}" == "true" ]; then
# Copy from cached artifacts
cp -f ../cached-artifacts/ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../cached-artifacts/ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../cached-artifacts/ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
else
# Copy from fresh artifacts
cp -f ../ksud_magic/aarch64-linux-android/release/ksud ../manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cp -f ../ksud_magic/armv7-linux-androideabi/release/ksud ../manager/app/src/main/jniLibs/armeabi-v7a/libksud_magic.so
cp -f ../ksud_magic/x86_64-linux-android/release/ksud ../manager/app/src/main/jniLibs/x86_64/libksud_magic.so
fi
- name: Build with Gradle
run: |

View File

@@ -3,14 +3,14 @@ name: Clippy check
on:
push:
branches:
- x86
- next
paths:
- '.github/workflows/clippy.yml'
- 'userspace/ksud_magic/**'
- 'userspace/ksud_overlayfs/**'
pull_request:
branches:
- x86
- next
paths:
- '.github/workflows/clippy.yml'
- 'userspace/ksud_magic/**'

View File

@@ -195,6 +195,18 @@ jobs:
sed -i 's/needs unknown symbol/Dont abort when unknown symbol/g' build/kernel/*.sh || echo "No unknown symbol scripts found"
fi
- name: Setup Syscall Hooks
if: ${{ inputs.build_lkm == false }}
run: |
cd $GITHUB_WORKSPACE/android-kernel/common
echo "[+] Patch Kernel"
curl -L https://github.com/KernelSU-Next/kernel_patches/raw/main/syscall_hook/min_scope_syscall_hooks_v1.4.patch | patch -p1 --fuzz=3
echo "[+] Set Config"
echo "CONFIG_KSU=y" >> ./arch/arm64/configs/gki_defconfig
echo "CONFIG_KSU_KPROBES_HOOK=n" >> ./arch/arm64/configs/gki_defconfig
echo "[+] Disable Config Check"
sed -i 's/check_defconfig//' ./build.config.gki
- name: Make working directory clean to avoid dirty
working-directory: android-kernel
run: |

View File

@@ -21,6 +21,12 @@ jobs:
build-a15-kernel:
uses: ./.github/workflows/build-kernel-a15.yml
secrets: inherit
build-wsa-kernel:
uses: ./.github/workflows/build-kernel-wsa.yml
secrets: inherit
build-arcvm-kernel:
uses: ./.github/workflows/build-kernel-arcvm.yml
secrets: inherit
release:
needs:
- build-manager
@@ -29,6 +35,7 @@ jobs:
- build-a14-kernel
- build-a15-kernel
- build-wsa-kernel
- build-arcvm-kernel
runs-on: ubuntu-latest
steps:
- name: Download artifacts
@@ -42,6 +49,24 @@ jobs:
fi
done
- name: Zip WSA kernel
run: |
for dir in kernel-WSA-*; do
if [ -d "$dir" ]; then
echo "------ Zip $dir ----------"
(cd $dir && zip -r9 "$dir".zip ./* -x .git .gitignore ./*.zip && mv *.zip ..)
fi
done
- name: Zip ChromeOS ARCVM kernel
run: |
for dir in kernel-ARCVM-*; do
if [ -d "$dir" ]; then
echo "------ Zip $dir ----------"
(cd $dir && zip -r9 "$dir".zip ./* -x .git .gitignore ./*.zip && mv *.zip ..)
fi
done
- name: Display structure of downloaded files
run: ls -R
@@ -54,6 +79,7 @@ jobs:
AnyKernel3-*.zip
boot-images-*/Image-*/*.img.gz
kernel-WSA*.zip
kernel-ARCVM*.zip
ksud_magic*.zip
ksud_overlayfs*.zip
susfsd*.zip
susfsd*.zip

View File

@@ -43,10 +43,10 @@ jobs:
ubuntu-version: "16.04"
cached: ${{ steps.cache-llvm.outputs.cache-hit }}
- name: Checkout KernelSU
- name: Checkout KernelSU-Next
uses: actions/checkout@v4
with:
path: KernelSU
path: KernelSU-Next
fetch-depth: 0
- name: Setup kernel source
@@ -63,23 +63,23 @@ jobs:
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
max-size: 2G
- name: Setup KernelSU
- name: Setup KernelSU-Next
working-directory: WSA-Linux-Kernel
run: |
echo "[+] KernelSU setup"
echo "[+] KernelSU-Next setup"
KERNEL_ROOT=$GITHUB_WORKSPACE/WSA-Linux-Kernel
echo "[+] KERNEL_ROOT: $KERNEL_ROOT"
echo "[+] Copy KernelSU driver to $KERNEL_ROOT/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU/kernel $KERNEL_ROOT/drivers/kernelsu
echo "[+] Add KernelSU driver to Makefile"
echo "[+] Copy KernelSU-Next driver to $KERNEL_ROOT/drivers"
ln -sf $GITHUB_WORKSPACE/KernelSU-Next/kernel $KERNEL_ROOT/drivers/kernelsu
echo "[+] Add KernelSU-Next driver to Makefile"
DRIVER_MAKEFILE=$KERNEL_ROOT/drivers/Makefile
DRIVER_KCONFIG=$KERNEL_ROOT/drivers/Kconfig
grep -q "kernelsu" "$DRIVER_MAKEFILE" || printf "\nobj-\$(CONFIG_KSU) += kernelsu/\n" >> "$DRIVER_MAKEFILE"
grep -q "kernelsu" "$DRIVER_KCONFIG" || sed -i "/endmenu/i\\source \"drivers/kernelsu/Kconfig\"" "$DRIVER_KCONFIG"
echo "[+] Apply KernelSU patches"
cd $KERNEL_ROOT && git apply $GITHUB_WORKSPACE/KernelSU/.github/patches/5.15/*.patch || echo "[-] No patch found"
echo "[+] KernelSU setup done."
cd $GITHUB_WORKSPACE/KernelSU
echo "[+] Apply KernelSU-Next patches"
cd $KERNEL_ROOT && git apply $GITHUB_WORKSPACE/KernelSU-Next/.github/patches/5.15/*.patch || echo "[-] No patch found"
echo "[+] KernelSU-Next setup done."
cd $GITHUB_WORKSPACE/KernelSU-Next
VERSION=$(($(git rev-list --count HEAD) + 10200))
echo "VERSION: $VERSION"
echo "kernelsu_version=$VERSION" >> $GITHUB_ENV
@@ -103,4 +103,4 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: kernel-WSA-${{ inputs.arch }}-${{ inputs.version }}
path: "${{ env.file_path }}"
path: "${{ env.file_path }}"

31
build.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/bin/bash
# This script builds the KernelSU Next manager APK.
# Ensure you have the setup Android SDK & NDK installed and necessary environment variables set and sourced.
# For LKM make sure you have imported the androidX-X.X_kernelsu.ko drivers to userspace/ksud_*/bin/aarch64 directory.
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksud_magic/Cargo.toml
cp userspace/ksud_magic/target/aarch64-linux-android/release/ksud manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksud_overlayfs/Cargo.toml
cp userspace/ksud_overlayfs/target/aarch64-linux-android/release/ksud manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
cd userspace/susfsd/jni
ndk-build
cp ../libs/arm64-v8a/susfsd ../../../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
cd ../../..
cd manager
./setup.sh
cd ..
adb install manager/app/build/outputs/apk/release/KernelSU_Next_v*.apk

2
crowdin.yml Normal file
View File

@@ -0,0 +1,2 @@
bundles:
- 8

View File

@@ -1,63 +1,91 @@
**English** | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md) | [Українська](README_UA.md)
**English** | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Українська](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md) | [Español](README_ES.md)
# KernelSU Next
---
<img src="/assets/kernelsu_next.png" style="width: 96px;" alt="logo">
<div align="center">
<img src="/assets/kernelsu_next.png" width="96" alt="KernelSU Next Logo">
A kernel-based root solution for Android devices.
<h2>KernelSU Next</h2>
<p><strong>A kernel-based root solution for Android devices.</strong></p>
[![Latest Release](https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github)](https://github.com/KernelSU-Next/KernelSU-Next/releases/latest)
[![Nightly Release](https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff)](https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu)](/LICENSE)
<p>
<a href="https://github.com/KernelSU-Next/KernelSU-Next/releases/latest">
<img src="https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github" alt="Latest Release">
</a>
<a href="https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager">
<img src="https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff" alt="Nightly Build">
</a>
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
<img src="https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu" alt="License: GPL v2">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu" alt="GitHub License">
</a>
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/kernelsu-next"><img src="https://badges.crowdin.net/kernelsu-next/localized.svg"></a>
</p>
</div>
## Features
---
1. Kernel-based `su` and root access management.
2. Module system based on dynamic mount system [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) / [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [App Profile](https://kernelsu.org/guide/app-profile.html): Lock up the root power in a cage.
## 🚀 Features
## Compatibility state
- Kernel-based `su` and root access management.
- Module system based on [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) and [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
- [App Profile](https://kernelsu.org/guide/app-profile.html): Limit root privileges per app.
KernelSU Next officially supports most Android kernels starting from 4.4 up to 6.6.
- GKI 2.0 (5.10+) kernels can run pre-built images and LKM/KMI.
- GKI 1.0 (4.19 - 5.4) kernels need to rebuilt with KernelSU driver.
- EOL (<4.14) kernels also need to be rebuilt with KernelSU driver (3.18+ is experimental and may need some function backports).
---
Currently, only the `arm64-v8a`, `armeabi-v7a` & `x86_64` architecture is supported.
## ✅ Compatibility
## Usage
KernelSU Next supports Android kernels from **4.4 up to 6.6**:
- [Installation instruction](https://ksunext.org/pages/installation.html)
| Kernel version | Support notes |
|----------------------|-------------------------------------------------------------------------|
| 5.10+ (GKI 2.0) | Supports pre-built images and LKM/KMI |
| 4.19 5.4 (GKI 1.0) | Requires KernelSU driver built-in |
| < 4.14 (EOL) | Requires KernelSU driver (3.18+ is experimental and may need backports) |
## Security
**Supported architectures:** `arm64-v8a`, `armeabi-v7a` and `x86_64`
For information on reporting security vulnerabilities in KernelSU, see [SECURITY.md](/SECURITY.md).
---
## License
## 📦 Installation
- Files under the `kernel` directory are [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- All other parts except the `kernel` directory are [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
Please refer to the [Installation](https://kernelsu-next.github.io/webpage/pages/installation.html) guide for setup instructions.
## Donations
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT BEP20 ]
## 🔐 Security
- TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh [ USDT TRC20 ]
To report security issues, please see [SECURITY.md](/SECURITY.md).
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT ERC20 ]
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ ETH ERC20 ]
## 📜 License
- Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL [ LTC ]
- **`/kernel` directory:** [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- **All other files:** [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
- 19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6 [ BTC ]
---
## Credits
## 💸 Donations
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): The KernelSU idea.
- [Magisk](https://github.com/topjohnwu/Magisk): The powerful root tool.
- [genuine](https://github.com/brevent/genuine/): APK v2 signature validation.
- [Diamorphine](https://github.com/m0nad/Diamorphine): Some rootkit skills.
- [KernelSU](https://github.com/tiann/KernelSU): Thanks to tiann, or else KernelSU Next wouldn't even exist.
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs): 💜 5ec1cff for saving KernelSU!
If youd like to support the project:
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **USDT (SOL)**: `A4wqBXYd6Ey4nK4SJ2bmjeMgGyaLKT9TwDLh8BEo8Zu6`
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
---
## 🙏 Credits
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/) Concept inspiration
- [Magisk](https://github.com/topjohnwu/Magisk) Core root implementation
- [Genuine](https://github.com/brevent/genuine/) APK v2 signature validation
- [Diamorphine](https://github.com/m0nad/Diamorphine) Rootkit techniques
- [KernelSU](https://github.com/tiann/KernelSU) The original base that made KernelSU Next possible
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) For magic mount support

View File

@@ -1,49 +1,90 @@
[English](README.md) | **简体中文** | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Український](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md)
# KernelSU Next
---
<img src="/assets/kernelsu_next.png" style="width: 96px;" alt="logo">
<div align="center">
<img src="/assets/kernelsu_next.png" width="96" alt="KernelSU Next Logo">
<h2>KernelSU Next</h2>
<p><strong>安卓设备基于内核的 Root 方案</strong></p>
安卓基于内核的 Root 方案
<p>
<a href="https://github.com/KernelSU-Next/KernelSU-Next/releases/latest">
<img src="https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github" alt="Latest Release">
</a>
<a href="https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager">
<img src="https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff" alt="Nightly Build">
</a>
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
<img src="https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu" alt="License: GPL v2">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu" alt="GitHub License">
</a>
</p>
</div>
[![Latest Release](https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github)](https://github.com/KernelSU-Next/KernelSU-Next/releases/latest)
[![Nightly Release](https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff)](https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu)](/LICENSE)
---
## 特性
## 🚀 特性
1. 基于内核的 `SU` 和权限管理
2. 基于动态挂载系统 [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) / [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS) 的模块系统。
3. [App Profile](https://kernelsu.org/zh_CN/guide/app-profile.html):把 Root 权限关进笼子里
- 基于内核的 `su`超级用户权限管理
- 动态挂载系统基于 **[Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount)** 以及 **[OverlayFS](https://en.wikipedia.org/wiki/OverlayFS)**
- [App Profile](https://kernelsu.org/zh_CN/guide/app-profile.html):把 Root 权限关进笼子里
## 兼容状态
---
KernelSU Next 支持从 4.4 到 6.6 的大多数安卓内核
- GKI 2.05.10+)内核可运行预置镜像和 LKM/KMI
- GKI 1.04.19 - 5.4)内核需要使用 KernelSU 内核驱动重新编译
- EOL (<4.14) 内核也需要使用 KernelSU 内核驱动重新编译 (3.18+ 的版本处于试验阶段可能需要移植一些功能)
## ✅ 兼容性
目前只支持 `arm64-v8a`, `armeabi-v7a` & `x86_64` 架构
KernelSU Next 支持从 **4.4 到 6.6** 的大多数安卓内核
## 用法
| 内核版本 | 支持情况 |
|----------------|---------------|
| 5.10+ (GKI 2.0) | 可运行预置镜像和 LKM/KMI |
| 4.19 5.4 (GKI 1.0) | 需要使用 KernelSU 内核驱动重新编译 |
| <4.14 (EOL) | 需要使用 KernelSU 内核驱动重新编译3.18+ 的版本处于试验阶段可能需要进行回溯移植 |
- [安装说明](https://ksunext.org/pages/installation.html)
**支持的架构:**
`arm64-v8a``armeabi-v7a``x86_64`
## 安全性
---
## 📦 安装
请遵循该[安装说明](https://kernelsu-next.github.io/webpage/zh_CN/pages/installation.html)进行操作
---
## 🔐 安全性
有关报告 KernelSU Next 漏洞的信息请参阅 [SECURITY.md](/SECURITY.md).
## 许可证
---
- 目录 `kernel` 下所有文件为 [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- `kernel` 目录以外的其他部分均为 [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)
## 📜 许可
## 鸣谢
- **目录 `/kernel` 下所有文件** [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- **`/kernel` 目录以外的其他部分**均为 [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): KernelSU 的灵感.
- [Magisk](https://github.com/topjohnwu/Magisk): 强大的 Root 工具.
- [genuine](https://github.com/brevent/genuine/): APK v2 签名验证
- [Diamorphine](https://github.com/m0nad/Diamorphine): 一些 Rootkit 技巧
- [KernelSU](https://github.com/tiann/KernelSU): 感谢 tiann否则 KernelSU Next 根本不会存在
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs): 💜 5ec1cff 為了拯救 KernelSU
---
## 💸 捐赠
如果你喜欢这个项目还请支持
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
---
## 🙏 鸣谢
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU 的灵感.
- [Magisk](https://github.com/topjohnwu/Magisk)强大的 Root 工具.
- [genuine](https://github.com/brevent/genuine/)APK v2 签名验证
- [Diamorphine](https://github.com/m0nad/Diamorphine)一些 Rootkit 技巧
- [KernelSU](https://github.com/tiann/KernelSU)感谢 tiann否则 KernelSU Next 根本不会存在
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs):💜 5ec1cff 为了拯救 KernelSU

89
docs/README_ES.md Normal file
View File

@@ -0,0 +1,89 @@
**English** | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Українська](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md) | [Español](README_ES.md)
---
<div align="center">
<img src="/assets/kernelsu_next.png" width="96" alt="KernelSU Next Logo">
<h2>KernelSU Next</h2>
<p><strong>Una solución de root basada en el kernel para tus dispositivos Android.</strong></p>
<p>
<a href="https://github.com/KernelSU-Next/KernelSU-Next/releases/latest">
<img src="https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github" alt="Latest Release">
</a>
<a href="https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager">
<img src="https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff" alt="Nightly Build">
</a>
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
<img src="https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu" alt="License: GPL v2">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu" alt="GitHub License">
</a>
</p>
</div>
---
## 🚀 Características
- `su` y gestión de acceso root basados en el kernel.
- Sistema de módulos basado en [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) y [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
- [Perfil de Aplicación](https://kernelsu.org/guide/app-profile.html): Limita los privilegios de root por aplicación.
---
## ✅ Compatibilidad
KernelSU Next es compatible con kernels de Android desde la versión **4.4 hasta la 6.6**:
| Kernel version | Support notes |
|----------------------|-----------------------------------------------------------------------------------|
| 5.10+ (GKI 2.0) | Admite imágenes precompiladas y LKM/KMI |
| 4.19 5.4 (GKI 1.0) | Requiere que el driver de KernelSU esté integrado |
| < 4.14 (EOL) | Requiere el driver de KernelSU (3.18+ es experimental y puede necesitar backports |
**Arquitecturas compatibles: ** `arm64-v8a`, `armeabi-v7a` y `x86_64`
---
## 📦 Instalación
Por favor, consulta la guía de [Instalación](https://kernelsu-next.github.io/webpage/pages/installation.html) para ver las instrucciones de configuración.
---
## 🔐 Seguridad
Para informar sobre problemas de seguridad, por favor, consulta [SECURITY.md](/SECURITY.md).
---
## 📜 Licencia
- **Directorio `/kernel`:** [Solo-GPL-2.0](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- **Todos los demás archivos:** [GPL-3.0-o-superior](https://www.gnu.org/licenses/gpl-3.0.html).
---
## 💸 Donaciones
Si te gustaría apoyar el proyecto:
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
---
## 🙏 Créditos
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/) Inspiración para el concepto
- [Magisk](https://github.com/topjohnwu/Magisk) Implementación principal del root
- [Genuine](https://github.com/brevent/genuine/) Validación de la firma v2 de los APK
- [Diamorphine](https://github.com/m0nad/Diamorphine) Técnicas de rootkit
- [KernelSU](https://github.com/tiann/KernelSU) La base original que hizo posible KernelSU Next
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) 💜 a 5ec1cff por mantener vivo KernelSU

View File

@@ -1,63 +1,89 @@
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Український](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | **Polski** | [Български](README_BG.md) | [日本語](README_JA.md)
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Українська](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | **Polski** | [Български](README_BG.md) | [日本語](README_JA.md)
# KernelSU Next
---
<img src="/assets/kernelsu_next.png" style="width: 96px;" alt="logo">
<div align="center">
<img src="/assets/kernelsu_next.png" width="96" alt="KernelSU Next Logo">
Bazujące na jądrze rozwiązanie root dla urządzeń z Androidem.
<h2>KernelSU Next</h2>
<p><strong>Bazujące na jądrze rozwiązanie root dla urządzeń z Androidem.</strong></p>
[![Latest Release](https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github)](https://github.com/KernelSU-Next/KernelSU-Next/releases/latest)
[![Nightly Release](https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff)](https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu)](/LICENSE)
<p>
<a href="https://github.com/KernelSU-Next/KernelSU-Next/releases/latest">
<img src="https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github" alt="Latest Release">
</a>
<a href="https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager">
<img src="https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff" alt="Nightly Build">
</a>
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
<img src="https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu" alt="License: GPL v2">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu" alt="GitHub License">
</a>
</p>
</div>
## Funkcjonalności
---
1. Oparte na jądrze `su` i zarządzanie dostępem do roota.
2. System modułów oparty na dynamicznym systemie montowania [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) / [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [Profil aplikacji](https://kernelsu.org/guide/app-profile.html): Ujarzmij moc roota poprzez możliwość nakładania ograniczeń na uprawnienia roota dla poszczególnych aplikacji.
## 🚀 Funkcjonalności
## Stan zgodności
- Oparte na jądrze `su` i zarządzanie dostępem do roota.
- System modułów oparty na [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) i [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
- [Profil aplikacji](https://kernelsu.org/guide/app-profile.html): Ograniczaj uprawnienia roota dla poszczególnych aplikacji.
KernelSU Next oficjalnie obsługuje większość jąder Androida od wersji 4.4 do 6.6.
- Jądra GKI 2.0 (5.10+) mogą uruchamiać wstępnie przygotowane obrazy i LKM/KMI.
- Jądra GKI 1.0 (4.19 - 5.4) muszą zostać zrekompilowane z dodatkiem sterownika KernelSU.
- Jądra EOL (<4.14) również muszą zostać zrekompilowane z dodatkiem sterownika KernelSU (obsługa 3.18+ jest eksperymentalna i może wymagać backportu pewnych funkcji).
---
Obecnie obsługiwana jest tylko architektura `arm64-v8a`, `armeabi-v7a` & `x86_64`
## ✅ Kompatybilność
## Użycie
KernelSU Next obsługuje jądra Androida od wersji **4.4 do 6.6**:
- [Instrukcja instalacji](https://ksunext.org/pages/installation.html)
| Wersja jądra | Informacje techniczne |
|----------------------|-------------------------------------------------------------------------------------------|
| 5.10+ (GKI 2.0) | Obsługuje wstępnie skompilowane obrazy i LKM/KMI |
| 4.19 5.4 (GKI 1.0) | Wymaga wbudowania sterownika KernelSU |
| < 4.14 (EOL) | Wymaga sterownika KernelSU (obsługa 3.18+ jest eksperymentalna i może wymagać backportów) |
## Bezpieczeństwo
**Obsługiwane architektury:** `arm64-v8a`, `armeabi-v7a` i `x86_64`
Informacje na temat zgłaszania luk bezpieczeństwa w KernelSU znajdziesz w [SECURITY.md](/SECURITY.md).
---
## Licencje
## 📦 Instalacja
- Pliki w katalogu `kernel` dostępne na licencji [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Wszystkie inne elementy, z wyjątkiem katalogu `kernel`, dostępne na licencji [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
Instrukcje dotyczące instalacji można znaleźć w przewodniku [Instalacja](https://kernelsu-next.github.io/webpage/pages/installation.html).
## Darowizny
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT BEP20 ]
## 🔐 Bezpieczeństwo
- TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh [ USDT TRC20 ]
Aby zgłosić problemy związane z bezpieczeństwem, zapoznaj się z [SECURITY.md](/SECURITY.md).
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT ERC20 ]
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ ETH ERC20 ]
## 📜 Licencje
- Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL [ LTC ]
- **katalog `/kernel`:** [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- **Wszystkie pozostałe pliki:** [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
- 19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6 [ BTC ]
---
## Podziękowania
## 💸 Darowizny
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): Idea, na której opiera się KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): Potężne narzędzie do rootowania.
- [genuine](https://github.com/brevent/genuine/): Walidacja podpisu APK v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): Część zdolności rootkitowych.
- [KernelSU](https://github.com/tiann/KernelSU): Dzięki tiann, bez ciebie KernelSU Next w ogóle by nie istniał.
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs): 💜 5ec1cff za uratowanie KernelSU!
Jeśli chciałbyś wesprzeć projekt:
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
---
## 🙏 Podziękowania
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/) Inspiracja konceptem
- [Magisk](https://github.com/topjohnwu/Magisk) Bazowa implementacja roota
- [Genuine](https://github.com/brevent/genuine/) Walidacja podpisu APK v2
- [Diamorphine](https://github.com/m0nad/Diamorphine) Techniki rootkit
- [KernelSU](https://github.com/tiann/KernelSU) Oryginalna baza, która umożliwiła powstanie KernelSU Next
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) 💜 dla 5ec1cff za utrzymanie KernelSU przy życiu

View File

@@ -1,63 +1,89 @@
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | **Português (Brasil)** | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Український](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md)
# KernelSU Next
---
<img src="/assets/kernelsu_next.png" style="width: 96px;" alt="logo">
<div align="center">
<img src="/assets/kernelsu_next.png" width="96" alt="KernelSU Next Logo">
Uma solução root baseada em kernel para dispositivos Android.
<h2>KernelSU Next</h2>
<p><strong>Uma solução root baseada em kernel para dispositivos Android.</strong></p>
[![Latest Release](https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github)](https://github.com/KernelSU-Next/KernelSU-Next/releases/latest)
[![Nightly Release](https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff)](https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu)](/LICENSE)
<p>
<a href="https://github.com/KernelSU-Next/KernelSU-Next/releases/latest">
<img src="https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github" alt="Latest Release">
</a>
<a href="https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager">
<img src="https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff" alt="Nightly Build">
</a>
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
<img src="https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu" alt="License: GPL v2">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu" alt="GitHub License">
</a>
</p>
</div>
## Características
---
1. `su` e gerenciamento de acesso root baseado em kernel.
2. Sistema de módulos baseado em sistema de montagem dinâmica [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) / [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [Perfil do Aplicativo](https://kernelsu.org/pt_BR/guide/app-profile.html): Tranque o poder root em uma gaiola.
## 🚀 Características
## Estado de compatibilidade
- `su` e gerenciamento de acesso root baseado em kernel.
- Sistema de módulos baseado em [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) e [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
- [Perfil do app](https://kernelsu.org/pt_BR/guide/app-profile.html): Limitar privilégios root por app.
KernelSU Next suporta oficialmente a maioria dos kernels Android a partir de 4.4 até 6.6.
- Os kernels GKI 2.0 (5.10+) podem executar imagens pré-construídas e LKM/KMI.
- Os kernels GKI 1.0 (4.19 - 5.4) precisam ser reconstruídos com o driver KernelSU.
- Os kernels EOL (<4.14) também precisam ser reconstruídos com o driver KernelSU (3.18+ é experimental e pode precisar portar algumas funções).
---
Atualmente, apenas a arquitetura `arm64-v8a`, `armeabi-v7a` & `x86_64` é compatível.
## ✅ Compatibilidade
## Uso
O KernelSU Next oferece suporte a kernels Android **4.4 até 6.6**:
- [Instruções de instalação](https://ksunext.org/pages/installation.html)
| Versão do kernel | Notas de suporte |
|----------------------|-------------------------------------------------------------------------------|
| 5.10+ (GKI 2.0) | Suporta imagens pré-compiladas e LKM/KMI |
| 4.19 5.4 (GKI 1.0) | Requer driver do KernelSU integrado |
| < 4.14 (EOL) | Requer driver do KernelSU (3.18+ é experimental e pode precisar de backports) |
## Segurança
**Arquiteturas suportadas:** `arm64-v8a`, `armeabi-v7a` e `x86_64`
Para obter informações sobre como relatar vulnerabilidades de segurança do KernelSU, consulte [SECURITY.md](/SECURITY.md).
---
## Licença
## 📦 Instalação
- Os arquivos no diretório `kernel` são [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Todas as outras partes, exceto o diretório `kernel` são [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
Consulte o guia de [Instalação](https://kernelsu-next.github.io/webpage/pt_BR/pages/installation.html) para obter instruções de configuração.
## Doações
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT BEP20 ]
## 🔐 Segurança
- TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh [ USDT TRC20 ]
Para relatar problemas de segurança, consulte [SECURITY.md](/SECURITY.md).
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT ERC20 ]
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ ETH ERC20 ]
## 📜 Licença
- Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL [ LTC ]
- **Diretório `/kernel`:** [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- **Todos os outros arquivos:** [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
- 19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6 [ BTC ]
---
## Créditos
## 💸 Doações
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): A ideia do KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): A poderosa ferramenta root.
- [genuine](https://github.com/brevent/genuine/): Validação de assinatura APK v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): Algumas habilidades de rootkit.
- [KernelSU](https://github.com/tiann/KernelSU): Obrigado ao tiann, ou então o KernelSU Next nem existiria.
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs): 💜 5ec1cff por salvar o KernelSU!
Se você quiser apoiar o projeto:
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
---
## 🙏 Créditos
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/) Inspiração do conceito
- [Magisk](https://github.com/topjohnwu/Magisk) Implementação root principal
- [Genuine](https://github.com/brevent/genuine/) Validação de assinatura APK v2
- [Diamorphine](https://github.com/m0nad/Diamorphine) Técnicas de rootkit
- [KernelSU](https://github.com/tiann/KernelSU) A base original que tornou o KernelSU Next possível
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) 💜 para 5ec1cff por manter o KernelSU vivo

View File

@@ -1,63 +1,89 @@
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | **Türkçe** | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Український](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md)
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | **Türkçe** | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Українська](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md)
# KernelSU Next
---
<img src="/assets/kernelsu_next.png" style="width: 96px;" alt="logo">
<div align="center">
<img src="/assets/kernelsu_next.png" width="96" alt="KernelSU Next Logosu">
Android cihazlar için çekirdek tabanlı root çözümü.
<h2>KernelSU Next</h2>
<p><strong>Android cihazlar için çekirdek tabanlı bir root çözümüdür.</strong></p>
[![Son Sürüm](https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github)](https://github.com/KernelSU-Next/KernelSU-Next/releases/latest)
[![Gece Sürümü](https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff)](https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager)
[![Lisans: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub Lisansı](https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu)](/LICENSE)
<p>
<a href="https://github.com/KernelSU-Next/KernelSU-Next/releases/latest">
<img src="https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github" alt="Latest Release">
</a>
<a href="https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager">
<img src="https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff" alt="Nightly Build">
</a>
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
<img src="https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu" alt="License: GPL v2">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu" alt="GitHub License">
</a>
</p>
</div>
## Özellikler
---
1. Çekirdek tabanlı `su` ve root erişimi yönetimi.
2. Dinamik bağlama sistemi [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) / [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS) tabanlı modül sistemi.
3. [Uygulama Profili](https://kernelsu.org/guide/app-profile.html): Root yetkisini bir kafese kilitleyin.
## 🚀 Özellikler
## Uyumluluk Durumu
- Çekirdek tabanlı `su` ve root erişim yönetimi.
- **[Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount)** ve **[OverlayFS](https://en.wikipedia.org/wiki/OverlayFS)** tabanlı modül sistemi.
- [Uygulama Profili](https://kernelsu.org/guide/app-profile.html): Uygulama başına root yetkisini sınırlandırma.
KernelSU Next, resmi olarak Android çekirdeklerinin çoğunu 4.4 sürümünden 6.6 sürümüne kadar destekler.
- GKI 2.0 (5.10+) çekirdekleri, hazır imajları ve LKM/KMI desteğini çalıştırabilir.
- GKI 1.0 (4.19 - 5.4) çekirdeklerinin KernelSU sürücüsü ile yeniden derlenmesi gerekir.
- EOL (<4.14) çekirdekler de KernelSU sürücüsüyle yeniden derlenmelidir (3.18+ deneysel olup bazı fonksiyonların geri aktarımı gerekebilir).
---
Şu anda yalnızca `arm64-v8a`, `armeabi-v7a` & `x86_64` mimarisi desteklenmektedir.
## ✅ Uyumluluk
## Kullanım
KernelSU Next, **4.4 ile 6.6** arasındaki Android çekirdeklerini destekler:
- [Kurulum Talimatları](https://ksunext.org/pages/installation.html)
| Çekirdek Sürümü | Destek Notları |
|------------------------|--------------------------------------------------------------------------|
| 5.10+ (GKI 2.0) | Hazır imajlar ve LKM/KMI desteği |
| 4.19 5.4 (GKI 1.0) | KernelSU sürücüsünün çekirdeğe gömülü olması gerekir |
| < 4.14 (EOL) | KernelSU sürücüsü gerekir (3.18+ deneysel olup yama gerektirebilir) |
## Güvenlik
**Desteklenen mimariler:** `arm64-v8a`, `armeabi-v7a`, `x86_64`
KernelSU'daki güvenlik ıklarını bildirme hakkında bilgi için bkz: [SECURITY.md](/SECURITY.md)
---
## Lisans
## 📦 Kurulum
- `kernel` dizinindeki dosyalar [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) lisanslıdır.
- `kernel` dizini dışındaki tüm diğer bölümler [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html) lisansı altındadır.
Kurulum talimatları için [Kurulum Kılavuzu](https://kernelsu-next.github.io/webpage/pages/installation.html) sayfasına bakınız.
## Bağışlar
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT BEP20 ]
## 🔐 Güvenlik
- TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh [ USDT TRC20 ]
Güvenlik ıklarını bildirmek için lütfen [SECURITY.md](/SECURITY.md) dosyasına bakınız.
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT ERC20 ]
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ ETH ERC20 ]
## 📜 Lisans
- Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL [ LTC ]
- **`/kernel` dizini:** [Yalnızca GPL-2.0](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- **Diğer tüm dosyalar:** [GPL-3.0-veya-sonrası](https://www.gnu.org/licenses/gpl-3.0.html)
- 19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6 [ BTC ]
---
## Katkıda Bulunanlar
## 💸 Bağışlar
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): KernelSU fikrinin temeli.
- [Magisk](https://github.com/topjohnwu/Magisk): Güçlü root aracı.
- [genuine](https://github.com/brevent/genuine/): APK v2 imza doğrulama.
- [Diamorphine](https://github.com/m0nad/Diamorphine): Bazı rootkit teknikleri.
- [KernelSU](https://github.com/tiann/KernelSU): tiann'a teşekkürler, KernelSU Next onun sayesinde var.
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs): 💜 KernelSU'yu kurtardığı için 5ec1cff'e teşekkürler!
Projeye destek olmak isterseniz:
- **USDT (BEP20, ERC20):** `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20):** `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **ETH (ERC20):** `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC:** `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC:** `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
---
## 🙏 Katkıda Bulunanlar
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/) KernelSU Fikrinin temeli
- [Magisk](https://github.com/topjohnwu/Magisk) Temel root altyapısı
- [Genuine](https://github.com/brevent/genuine/) APK v2 imza doğrulaması
- [Diamorphine](https://github.com/m0nad/Diamorphine) Rootkit teknikleri
- [KernelSU](https://github.com/tiann/KernelSU) KernelSU Next'in temelini oluşturan orijinal proje
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) KernelSUyu kurtardığı için 💜 5ec1cffe teşekkürler

View File

@@ -1,50 +1,88 @@
[English](README.md) | [简体中文](README_CN.md) | **繁體中文** | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [Український](README_UA.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md)
# KernelSU Next
---
<img src="/assets/kernelsu_next.png" style="width: 96px;" alt="logo">
<div align="center">
<img src="/assets/kernelsu_next.png" width="96" alt="KernelSU Next Logo">
<h2>KernelSU Next</h2>
<p><strong>基於內核的 Android 設備 Root 解決方案</strong></p>
基於內核的 Android 設備 Root 解決方案
<p>
<a href="https://github.com/KernelSU-Next/KernelSU-Next/releases/latest">
<img src="https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github" alt="Latest Release">
</a>
<a href="https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager">
<img src="https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff" alt="Nightly Build">
</a>
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
<img src="https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu" alt="License: GPL v2">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu" alt="GitHub License">
</a>
</p>
</div>
[![Latest Release](https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github)](https://github.com/KernelSU-Next/KernelSU-Next/releases/latest)
[![Nightly Release](https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff)](https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub License](https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu)](/LICENSE)
---
## 特性
## 🚀 特性
1. 基於內核的 `su` 和 Root 權限管理
2. 基於動態掛載系統 [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) / [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS) 的模塊系統。
3. [App Profile](https://kernelsu.org/zh_CN/guide/app-profile.html):把 Root 權限關進籠子裡
- 基於內核的 `su` 和 Root 權限管理
- 模塊系統基於 **[Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount)** 以及 **[OverlayFS](https://en.wikipedia.org/wiki/OverlayFS)**
- [App Profile](https://kernelsu.org/zh_CN/guide/app-profile.html):把 Root 權限關進籠子裡
## 兼容狀態
---
KernelSU Next 正式支持大多數從 4.4 到 6.6 的 Android 內核
- GKI 2.0 (5.10+) 內核可以運行預構建的映像和 LKM/KMI
- GKI 1.0 (4.19 - 5.4) 內核需要重新編譯 KernelSU 驅動程序
- EOL (<4.14) 內核也需要重新編譯 KernelSU 驅動程序3.18+ 是實驗性的可能需要移植一些功能
## ✅ 兼容狀態
目前僅支持 `arm64-v8a`, `armeabi-v7a` & `x86_64`
KernelSU Next 正式支持大多數從 **4.4 到 6.6** 的 Android 內核
## 用法
| 内核版本 | 支援狀況 |
|----------------|---------------|
| 5.10+ (GKI 2.0) | 可以運行預構建的映像和 LKM/KMI |
| 4.19 5.4 (GKI 1.0) | 需要重新編譯 KernelSU 驅動程序 |
| <4.14 (EOL) | 需要重新編譯 KernelSU 驅動程序3.18+ 是實驗性的可能需要回溯移植一些功能 |
- [安裝說明](https://ksunext.org/pages/installation.html)
**支援的架構:**
`arm64-v8a``armeabi-v7a``x86_64`
## 安全性
---
有關報告 KernelSU Next 漏洞的信息請參閱 [SECURITY.md](/SECURITY.md).
## 📦 用法
## 許可證
請遵循[安裝説明](https://kernelsu-next.github.io/webpage/pages/installation.html)進行操作
- 目錄 `kernel` 下所有文件為 [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- `kernel` 目錄以外的其他部分均為 [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)
---
## 鳴謝
## 🔐 安全性
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): KernelSU 的靈感.
- [Magisk](https://github.com/topjohnwu/Magisk): 強大的 Root 工具.
- [genuine](https://github.com/brevent/genuine/): APK v2 簽名驗證
- [Diamorphine](https://github.com/m0nad/Diamorphine): 一些 Rootkit 技巧
- [KernelSU](https://github.com/tiann/KernelSU): 感謝 tiann否則 KernelSU Next 根本不會存在
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs): 💜 5ec1cff 為了拯救 KernelSU
有關報告 KernelSU Next 漏洞的信息請參閱 [SECURITY.md](/SECURITY.md)
---
## 📜 許可證
- **目錄 `/kernel` 下所有文件** [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- **`/kernel` 目錄以外的其他部分**均為 [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)
---
## 💸 抖内
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
---
## 🙏 鳴謝
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/)KernelSU 的靈感.
- [Magisk](https://github.com/topjohnwu/Magisk)強大的 Root 工具.
- [genuine](https://github.com/brevent/genuine/)APK v2 簽名驗證
- [Diamorphine](https://github.com/m0nad/Diamorphine)一些 Rootkit 技巧
- [KernelSU](https://github.com/tiann/KernelSU)感謝 tiann否則 KernelSU Next 根本不會存在
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs):💜 5ec1cff 為了拯救 KernelSU

View File

@@ -1,63 +1,90 @@
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md) | **Українська**
**Languages**:
[English](README.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [Türkçe](README_TR.md) | [Português (Brasil)](README_PT-BR.md) | [한국어](README_KO.md) | [Français](README_FR.md) | [Bahasa Indonesia](README_ID.md) | [Русский](README_RU.md) | **Українська** | [ภาษาไทย](README_TH.md) | [Tiếng Việt](README_VI.md) | [Italiano](README_IT.md) | [Polski](README_PL.md) | [Български](README_BG.md) | [日本語](README_JA.md)
# KernelSU Next
---
<img src="/assets/kernelsu_next.png" style="width: 96px;" alt="logo">
<div align="center">
<img src="/assets/kernelsu_next.png" width="96" alt="KernelSU Next Logo">
Рут-рішення на основі ядра для пристроїв Android.
<h2>KernelSU Next</h2>
<p><strong>Рішення для root-прав на основі ядра для пристроїв Android.</strong></p>
[![Останній реліз](https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github)](https://github.com/KernelSU-Next/KernelSU-Next/releases/latest)
[![Нічний реліз (Нестабільний)](https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff)](https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager)
[![Ліцензія: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
[![GitHub Ліцензія](https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu)](/LICENSE)
<p>
<a href="https://github.com/KernelSU-Next/KernelSU-Next/releases/latest">
<img src="https://img.shields.io/github/v/release/KernelSU-Next/KernelSU-Next?label=Release&logo=github" alt="Latest Release">
</a>
<a href="https://nightly.link/KernelSU-Next/KernelSU-Next/workflows/build-manager-ci/next/Manager">
<img src="https://img.shields.io/badge/Nightly%20Release-gray?logo=hackthebox&logoColor=fff" alt="Nightly Build">
</a>
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
<img src="https://img.shields.io/badge/License-GPL%20v2-orange.svg?logo=gnu" alt="License: GPL v2">
</a>
<a href="/LICENSE">
<img src="https://img.shields.io/github/license/KernelSU-Next/KernelSU-Next?logo=gnu" alt="GitHub License">
</a>
</p>
</div>
## Можливості
---
1. `su` на основі ядра та можливість контролювати дозволи руту.
2. Module system based on dynamic mount system [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) / [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
3. [Профілі додатків](https://kernelsu.org/guide/app-profile.html): Обмеж права руту для додатків.
## 🚀 Особливості
## Compatibility state
- Керування `su` та root-доступом на основі ядра.
- Модульна система на основі [Magic Mount](https://topjohnwu.github.io/Magisk/details.html#magic-mount) та [OverlayFS](https://en.wikipedia.org/wiki/OverlayFS).
- [Профілі програм](https://kernelsu.org/guide/app-profile.html): Обмеження root-прав для кожної програми.
KernelSU Next офіційно підтримує більшість Android ядер починаючи з 4.4 і до 6.6.
- Користувачі GKI 2.0 (5.10+) ядра можуть використовувати готові образи та LKM/KMI.
- Користувачі GKI 1.0 (4.19 - 5.4) ядра мають бути перезібрані з драйвером KernelSU.
- Користувачі EOL (<4.14) ядра також мають бути перезібрані з драйвером KernelSU (Підтримка 3.18+ експерементальна і потребує бекпортів деяких функцій в ядрі).
---
На даний момент підтримується лише архітектура `arm64-v8a`, `armeabi-v7a` & `x86_64`.
## ✅ Сумісність
## Спосіб використання
KernelSU Next підтримує ядра Android від **4.4 до 6.6**:
- [Інструкція для встановлення/інтеграції](https://ksunext.org/pages/installation.html)
| Версія ядра | Примітки підтримки |
|----------------------|-------------------------------------------------------------------------------------------|
| 5.10+ (GKI 2.0) | Підтримує попередньо створені образи та LKM/KMI |
| 4.19 5.4 (GKI 1.0) | Потрібен вбудований драйвер KernelSU |
| <4.14 (EOL) | Потрібен драйвер KernelSU (версія 3.18+ є експериментальною, може знадобитися портування) |
## Безпека
**Підтримувані архітектури:** `arm64-v8a`, `armeabi-v7a`, `x86_64`
Для інформації зв'язаною з безпекою дивіться [SECURITY.md](/SECURITY.md).
---
## Ліцензія
## 📦 Встановлення
- Всі файли в директорії `kernel` мають ліцензію [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).
- Всі інші файли виключаючи директорію `kernel` мають ліцензію [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html).
Будь ласка, зверніться до [Посібника з встановлення](https://kernelsu-next.github.io/webpage/pages/installation.html) для отримання інструкцій з налаштування.
## Підтримка розробника
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT BEP20 ]
## 🔐 Безпека
- TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh [ USDT TRC20 ]
Щоб повідомити про проблеми безпеки, див [SECURITY.md](/SECURITY.md).
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ USDT ERC20 ]
---
- 0x12b5224b7aca0121c2f003240a901e1d064371c1 [ ETH ERC20 ]
## 📜 Ліцензія
- Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL [ LTC ]
- **Каталог `/kernel`:** [GPL-2.0-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
- **Усі інші файли:** [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html)
- 19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6 [ BTC ]
---
## Подяки
## 💸 Пожертви
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): Ідея KernelSU.
- [Magisk](https://github.com/topjohnwu/Magisk): Потужний засіб руту.
- [genuine](https://github.com/brevent/genuine/): Перевірка підпису APK v2.
- [Diamorphine](https://github.com/m0nad/Diamorphine): Деякі руткіт скіли.
- [KernelSU](https://github.com/tiann/KernelSU): Дякую tiann, інакше KernelSU Next ніколи б не існував.
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs): Дякую 💜 5ec1cff за збереження KernelSU!
Якщо ви хочете підтримати проєкт:
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
---
## 🙏 Подяки
- [Kernel-Assisted Superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/) Натхнення для концепції
- [Magisk](https://github.com/topjohnwu/Magisk) Топовий інструмент для root
- [Genuine](https://github.com/brevent/genuine/) Перевірка підпису APK версії 2
- [Diamorphine](https://github.com/m0nad/Diamorphine) Деякі навики RootKit
- [KernelSU](https://github.com/tiann/KernelSU) Основа для KernelSU Next
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) 💜 до 5ec1cff за збереження KernelSU

326
docs/WebUi_Next/API_DOC.md Normal file
View File

@@ -0,0 +1,326 @@
# WebUI-Next API Documentation
This document provides examples of how to use the `WebUI-Next` JavaScript APIs exposed to a module WebUI. These APIs allow code to run in the WebUI to interact with the system, execute shell commands, manage packages, control UI elements, and more coming soon.
## Table of Contents
1. [exec(cmd)](#exec-cmd)
2. [exec(cmd, callbackFunc)](#exec-cmd-callbackfunc)
3. [exec(cmd, options, callbackFunc)](#exec-cmd-options-callbackfunc)
4. [spawn(command, args, options, callbackFunc)](#spawn-command-args-options-callbackfunc)
5. [toast(msg)](#toast-msg)
6. [fullScreen(enable)](#fullscreen-enable)
7. [moduleInfo()](#moduleinfo)
8. [listSystemPackages()](#listsystempackages)
9. [listUserPackages()](#listuserpackages)
10. [listAllPackages()](#listallpackages)
11. [getPackagesInfo(packageNamesJson)](#getpackagesinfo-packagenamesjson)
12. [cacheAllPackageIcons(size)](#cacheallpackageicons-size)
13. [getPackagesIcons(packageNamesJson, size)](#getpackagesicons-packagenamesjson-size)
---
## exec(cmd)
Executes a shell command synchronously and returns the output as a string.
### Parameters
- `cmd` (String): The shell command to execute.
### Returns
- `String`: The command output (stdout).
### Example
```javascript
const output = ksu.exec("ls /system");
console.log("Output:", output);
```
---
## exec(cmd, callbackFunc)
Executes a shell command asynchronously and invokes the provided callback function with the result.
### Parameters
- `cmd` (String): The shell command to execute.
- `callbackFunc` (String): The name of the JavaScript callback function to invoke with the result.
### Callback Signature
```javascript
function callbackFunc(exitCode, stdout, stderr) {
// Handle result
}
```
### Example
```javascript
function handleResult(exitCode, stdout, stderr) {
console.log("Exit Code:", exitCode);
console.log("Stdout:", stdout);
console.log("Stderr:", stderr);
}
ksu.exec("ls /system", "handleResult");
```
---
## exec(cmd, options, callbackFunc)
Executes a shell command asynchronously with options (e.g., working directory, environment variables) and invokes the provided callback function with the result.
### Parameters
- `cmd` (String): The shell command to execute.
- `options` (String): A JSON string specifying options like `cwd` (working directory) and `env` (environment variables).
- `callbackFunc` (String): The name of the JavaScript callback function to invoke with the result.
### Options Format
```javascript
{
"cwd": "/path/to/working/directory",
"env": {
"KEY1": "VALUE1",
"KEY2": "VALUE2"
}
}
```
### Callback Signature
```javascript
function callbackFunc(exitCode, stdout, stderr) {
// Handle result
}
```
### Example
```javascript
const options = JSON.stringify({
cwd: "/system",
env: { PATH: "/system/bin" }
});
function handleResult(exitCode, stdout, stderr) {
console.log("Exit Code:", exitCode);
console.log("Stdout:", stdout);
console.log("Stderr:", stderr);
}
ksu.exec("ls", JSON.stringify(options), "handleResult");
```
---
## spawn(command, args, options, callbackFunc)
Spawns a shell command with arguments and streams output through events to a JavaScript object.
### Parameters
- `command` (String): The shell command to execute.
- `args` (String): A JSON array of command arguments.
- `options` (String): A JSON string specifying options like `cwd` and `env` (optional).
- `callbackFunc` (String): The name of the JavaScript object to receive events (`stdout`, `stderr`, `exit`, `error`).
### Callback Object
The callback object should implement methods to handle events:
- `stdout.emit('data', data)`: Emits stdout data.
- `stderr.emit('data', data)`: Emits stderr data.
- `exit(code)`: Emits the exit code.
- `error(err)`: Emits an error object with `exitCode` and `message`.
### Example
```javascript
const streamHandler = {
stdout: {
emit: (event, data) => {
if (event === "data") console.log("Stdout:", data);
}
},
stderr: {
emit: (event, data) => {
if (event === "data") console.log("Stderr:", data);
}
},
emit: (event, data) => {
if (event === "exit") console.log("Exit Code:", data);
if (event === "error") console.error("Error:", data);
}
};
const args = JSON.stringify(["-l", "/system"]);
const options = JSON.stringify({ cwd: "/system" });
ksu.spawn("ls", args, options, "streamHandler");
```
---
## toast(msg)
Displays a short Android toast message.
### Parameters
- `msg` (String): The message to display.
### Example
```javascript
ksu.toast("Hello from WebUI-Next!");
```
---
## fullScreen(enable)
Toggles full-screen mode by hiding or showing system UI (status and navigation bars).
### Parameters
- `enable` (Boolean): `true` to enable full-screen mode, `false` to disable.
### Example
```javascript
// Enable full-screen
ksu.fullScreen(true);
// Disable full-screen
ksu.fullScreen(false);
```
---
## moduleInfo()
Returns information about the current module as a JSON string.
### Returns
- `String`: A JSON string containing module information, including `moduleDir` and other module-specific details.
### Example
```javascript
const moduleInfo = JSON.parse(ksu.moduleInfo());
console.log("Module Directory:", moduleInfo.moduleDir);
console.log("Module ID:", moduleInfo.id);
```
---
## listSystemPackages()
Returns a list of system package names as a JSON array.
### Returns
- `String`: A JSON array of system package names.
### Example
```javascript
const systemPackages = JSON.parse(ksu.listSystemPackages());
console.log("System Packages:", systemPackages);
```
---
## listUserPackages()
Returns a list of user-installed package names as a JSON array.
### Returns
- `String`: A JSON array of user package names.
### Example
```javascript
const userPackages = JSON.parse(ksu.listUserPackages());
console.log("User Packages:", userPackages);
```
---
## listAllPackages()
Returns a list of all installed package names as a JSON array.
### Returns
- `String`: A JSON array of all package names.
### Example
```javascript
const allPackages = JSON.parse(ksu.listAllPackages());
console.log("All Packages:", allPackages);
```
---
## getPackagesInfo(packageNamesJson)
Returns detailed information about specified packages as a JSON array.
### Parameters
- `packageNamesJson` (String): A JSON array of package names.
### Returns
- `String`: A JSON array of objects containing package details (`packageName`, `versionName`, `versionCode`, `appLabel`, `isSystem`, `uid`) or an error object if the package is not found.
### Example
```javascript
const packageNames = JSON.stringify(["com.android.settings", "com.example.app"]);
const packageInfos = JSON.parse(ksu.getPackagesInfo(packageNames));
packageInfos.forEach(info => {
if (info.error) {
console.error(`Error for ${info.packageName}: ${info.error}`);
} else {
console.log(`Package: ${info.packageName}, Version: ${info.versionName}, System: ${info.isSystem}`);
}
});
```
---
## cacheAllPackageIcons(size)
Caches icons for all installed packages at the specified size.
### Parameters
- `size` (Number): The size (in pixels) for the square icon.
### Example
```javascript
// Cache all package icons at 48x48 pixels
ksu.cacheAllPackageIcons(48);
```
---
## getPackagesIcons(packageNamesJson, size)
Returns base64-encoded icons for specified packages as a JSON array.
### Parameters
- `packageNamesJson` (String): A JSON array of package names.
- `size` (Number): The size (in pixels) for the square icon.
### Returns
- `String`: A JSON array of objects containing `packageName` and `icon` (base64-encoded PNG or empty string if unavailable).
### Example
```javascript
const packageNames = JSON.stringify(["com.android.settings", "com.example.app"]);
const packageIcons = JSON.parse(ksu.getPackagesIcons(packageNames, 48));
packageIcons.forEach(item => {
if (item.icon) {
console.log(`Icon for ${item.packageName}: ${item.icon.substring(0, 30)}...`);
// Example: Display icon in an <img> element
const img = document.createElement("img");
img.src = item.icon;
document.body.appendChild(img);
} else {
console.log(`No icon for ${item.packageName}`);
}
});
```
---
## Notes
- **Root Access**: Methods like `exec` and `spawn` require root access and use the `libsu` library for shell execution.
- **Asynchronous Operations**: Use `WebUI.post` to ensure UI thread safety when invoking JavaScript callbacks.
- **Error Handling**: Always check for errors in callbacks (e.g., `stderr` in `exec`, `error` event in `spawn`).
- **Icon Caching**: Use `cacheAllPackageIcons` to improve performance for subsequent `getPackagesIcons` calls.
- **JSON Parsing**: Ensure valid JSON strings are passed to methods like `getPackagesInfo` and `getPackagesIcons`.

View File

@@ -40,4 +40,11 @@ config KSU_LSM_SECURITY_HOOKS
Disabling this is mostly only useful for kernel 4.1 and older.
Make sure to implement manual hooks on security/security.c.
config KSU_SWITCH_MANAGER
bool "KernelSU switch manager support"
depends on KSU
default n
help
Enable KernelSU switch manager support.
endmenu

View File

@@ -49,12 +49,12 @@ ifeq ($(shell grep "ssize_t kernel_write" $(srctree)/fs/read_write.c | grep -q "
ccflags-y += -DKSU_KERNEL_WRITE
endif
ifndef KSU_NEXT_EXPECTED_SIZE
KSU_NEXT_EXPECTED_SIZE := 0x3e6
ifndef KSU_NEXT_MANAGER_SIZE
KSU_NEXT_MANAGER_SIZE := 0x3e6
endif
ifndef KSU_NEXT_EXPECTED_HASH
KSU_NEXT_EXPECTED_HASH := 79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7
ifndef KSU_NEXT_MANAGER_HASH
KSU_NEXT_MANAGER_HASH := 79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7
endif
ifdef KSU_MANAGER_PACKAGE
@@ -62,48 +62,14 @@ ccflags-y += -DKSU_MANAGER_PACKAGE=\"$(KSU_MANAGER_PACKAGE)\"
$(info -- KernelSU-Next Manager package name: $(KSU_MANAGER_PACKAGE))
endif
$(info -- KernelSU-Next Manager signature size: $(KSU_NEXT_EXPECTED_SIZE))
$(info -- KernelSU-Next Manager signature hash: $(KSU_NEXT_EXPECTED_HASH))
$(info -- KernelSU-Next Manager signature size: $(KSU_NEXT_MANAGER_SIZE))
$(info -- KernelSU-Next Manager signature hash: $(KSU_NEXT_MANAGER_HASH))
ccflags-y += -DEXPECTED_NEXT_SIZE=$(KSU_NEXT_EXPECTED_SIZE)
ccflags-y += -DEXPECTED_NEXT_HASH=\"$(KSU_NEXT_EXPECTED_HASH)\"
ccflags-y += -DKSU_COMPAT_GET_CRED_RCU
ccflags-y += -DEXPECTED_MANAGER_SIZE=$(KSU_NEXT_MANAGER_SIZE)
ccflags-y += -DEXPECTED_MANAGER_HASH=\"$(KSU_NEXT_MANAGER_HASH)\"
ccflags-y += -DKSU_UMOUNT
# Determine the appropriate atomic function and apply patch accordingly
ifeq ($(shell grep -q "atomic_inc_not_zero" $(srctree)/kernel/cred.c; echo $$?),0)
ATOMIC_INC_FUNC = atomic_inc_not_zero
else ifeq ($(shell grep -q "atomic_long_inc_not_zero" $(srctree)/kernel/cred.c; echo $$?),0)
ATOMIC_INC_FUNC = atomic_long_inc_not_zero
else
$(info -- KSU_NEXT: Neither atomic_inc_not_zero nor atomic_long_inc_not_zero found in kernel/cred.c)
endif
# Inform which function is being patched
$(info -- KSU_NEXT: Using $(ATOMIC_INC_FUNC) in get_cred_rcu patch.)
# Add the get_cred_rcu function to cred.h if not already present
ifneq ($(shell grep -Eq "^static inline const struct cred \*get_cred_rcu" $(srctree)/include/linux/cred.h; echo $$?),0)
$(info -- KSU_NEXT: adding function 'static inline const struct cred *get_cred_rcu(const struct cred *cred);' to $(srctree)/include/linux/cred.h)
GET_CRED_RCU = static inline const struct cred *get_cred_rcu(const struct cred *cred)\n\
{\n\t\
struct cred *nonconst_cred = (struct cred *) cred;\n\t\
if (!cred)\n\t\t\
return NULL;\n\t\
if (!$(ATOMIC_INC_FUNC)(&nonconst_cred->usage))\n\t\t\
return NULL;\n\t\
validate_creds(cred);\n\t\
return cred;\n\
}\n
$(shell grep -qF "$(GET_CRED_RCU)" $(srctree)/include/linux/cred.h || sed -i '/^static inline void put_cred/i $(GET_CRED_RCU)' $(srctree)/include/linux/cred.h)
# Modify get_task_cred in cred.c
$(info -- KSU_NEXT: modifying 'get_task_cred' function in $(srctree)/kernel/cred.c)
$(shell sed -i "s/!$(ATOMIC_INC_FUNC)(&((struct cred \*)cred)->usage)/!get_cred_rcu(cred)/g" $(srctree)/kernel/cred.c)
endif
ifneq ($(shell grep -Eq "^static int can_umount" $(srctree)/fs/namespace.c; echo $$?),0)
$(info -- KSU_NEXT: adding function 'static int can_umount(const struct path *path, int flags);' to $(srctree)/fs/namespace.c)
CAN_UMOUNT = static int can_umount(const struct path *path, int flags)\n\

View File

@@ -3,10 +3,9 @@
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/version.h>
#ifdef CONFIG_KSU_DEBUG
#include <linux/moduleparam.h>
#endif
#include <crypto/hash.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
#include <crypto/sha2.h>
@@ -17,7 +16,10 @@
#include "apk_sign.h"
#include "klog.h" // IWYU pragma: keep
#include "kernel_compat.h"
#include "throne_tracker.h"
static unsigned int expected_manager_size = EXPECTED_MANAGER_SIZE;
static char expected_manager_hash[SHA256_DIGEST_SIZE * 2 + 1] = EXPECTED_MANAGER_HASH;
struct sdesc {
struct shash_desc shash;
@@ -314,7 +316,76 @@ module_param_cb(ksu_debug_manager_uid, &expected_size_ops,
#endif
#ifdef CONFIG_KSU_SWITCH_MANAGER
static int set_expected_size(const char *val, const struct kernel_param *kp)
{
int rv = param_set_uint(val, kp);
pr_info("expected_manager_size set to %u\n", expected_manager_size);
return rv;
}
static int get_expected_size(char *buf, const struct kernel_param *kp)
{
return snprintf(buf, PAGE_SIZE, "%u\n", expected_manager_size);
}
static int set_expected_hash(const char *val, const struct kernel_param *kp)
{
if (strlen(val) != SHA256_DIGEST_SIZE * 2) {
pr_err("Invalid hash length: %s\n", val);
return -EINVAL;
}
strncpy(expected_manager_hash, val, SHA256_DIGEST_SIZE * 2);
expected_manager_hash[SHA256_DIGEST_SIZE * 2] = '\0';
pr_info("expected_manager_hash set to %s\n", expected_manager_hash);
return 0;
}
static int get_expected_hash(char *buf, const struct kernel_param *kp)
{
return snprintf(buf, PAGE_SIZE, "%s\n", expected_manager_hash);
}
static struct kernel_param_ops expected_size_ops = {
.set = set_expected_size,
.get = get_expected_size,
};
static struct kernel_param_ops expected_hash_ops = {
.set = set_expected_hash,
.get = get_expected_hash,
};
module_param_cb(expected_manager_size, &expected_size_ops, &expected_manager_size, 0644);
module_param_cb(expected_manager_hash, &expected_hash_ops, &expected_manager_hash, 0644);
#endif
bool is_manager_apk(char *path)
{
return check_v2_signature(path, EXPECTED_NEXT_SIZE, EXPECTED_NEXT_HASH);
}
int tries = 0;
while (tries++ < 10) {
if (!is_lock_held(path))
break;
pr_info("%s: waiting for %s\n", __func__, path);
msleep(100);
}
// let it go, if retry fails, check_v2_signature will fail to open it anyway
if (tries == 10) {
pr_info("%s: timeout for %s\n", __func__, path);
return false;
}
// set debug info to print size and hash to kernel log
pr_info("%s: expected size: %u, expected hash: %s\n",
path, expected_manager_size, expected_manager_hash);
return check_v2_signature(path, expected_manager_size, expected_manager_hash);
}

View File

@@ -47,10 +47,6 @@
#include "throne_tracker.h"
#include "kernel_compat.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) || defined(KSU_COMPAT_GET_CRED_RCU)
#define KSU_GET_CRED_RCU
#endif
static bool ksu_module_mounted = false;
extern int handle_sepolicy(unsigned long arg3, void __user *arg4);
@@ -118,6 +114,7 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
groups_sort(group_info);
set_groups(cred, group_info);
put_group_info(group_info);
}
static void disable_seccomp(void)
@@ -142,27 +139,17 @@ void escape_to_root(void)
{
struct cred *cred;
#ifdef KSU_GET_CRED_RCU
rcu_read_lock();
do {
cred = (struct cred *)__task_cred((current));
BUG_ON(!cred);
} while (!get_cred_rcu(cred));
cred = prepare_creds();
if (!cred) {
pr_warn("prepare_creds failed!\n");
return;
}
if (cred->euid.val == 0) {
pr_warn("Already root, don't escape!\n");
rcu_read_unlock();
abort_creds(cred);
return;
}
#else
cred = (struct cred *)__task_cred(current);
if (cred->euid.val == 0) {
pr_warn("Already root, don't escape!\n");
return;
}
#endif
struct root_profile *profile = ksu_get_root_profile(cred->uid.val);
@@ -197,10 +184,8 @@ void escape_to_root(void)
sizeof(cred->cap_ambient));
setup_groups(profile, cred);
#ifdef KSU_GET_CRED_RCU
rcu_read_unlock();
#endif
commit_creds(cred);
// Refer to kernel/seccomp.c: seccomp_set_mode_strict
// When disabling Seccomp, ensure that current->sighand->siglock is held during the operation.
@@ -267,7 +252,35 @@ static void nuke_ext4_sysfs() {
}
ext4_unregister_sysfs(sb);
path_put(&path);
path_put(&path);
}
static bool is_system_bin_su(void)
{
static const char *su_paths[] = {
"/system/bin/su",
"/vendor/bin/su",
"/product/bin/su",
"/system_ext/bin/su",
"/odm/bin/su",
"/system/xbin/su",
"/system_ext/xbin/su"
};
char path_buf[256];
char *pathname;
int i;
struct mm_struct *mm = current->mm;
if (mm && mm->exe_file) {
pathname = d_path(&mm->exe_file->f_path, path_buf, sizeof(path_buf));
if (!IS_ERR(pathname)) {
for (i = 0; i < ARRAY_SIZE(su_paths); i++) {
if (strcmp(pathname, su_paths[i]) == 0)
return true;
}
}
}
return false;
}
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
@@ -292,10 +305,18 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
bool from_root = 0 == current_uid().val;
bool from_manager = is_manager();
#ifdef CONFIG_KSU_KPROBES_HOOK
if (!from_root && !from_manager
&& !(is_allow_su() && is_system_bin_su())) {
// only root or manager can access this interface
return 0;
}
#else
if (!from_root && !from_manager) {
// only root or manager can access this interface
return 0;
}
#endif
#ifdef CONFIG_KSU_DEBUG
pr_info("option: 0x%x, cmd: %ld\n", option, arg2);
@@ -339,6 +360,17 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0;
}
if (arg2 == CMD_GET_MANAGER_UID) {
uid_t manager_uid = ksu_get_manager_uid();
if (copy_to_user(arg3, &manager_uid, sizeof(manager_uid))) {
pr_err("get manager uid failed\n");
}
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %lu\n", arg2);
}
return 0;
}
if (arg2 == CMD_HOOK_MODE) {
#ifdef CONFIG_KSU_KPROBES_HOOK
const char *mode = "Kprobes";
@@ -450,6 +482,32 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0;
}
#ifdef CONFIG_KSU_KPROBES_HOOK
if (arg2 == CMD_ENABLE_SU) {
bool enabled = (arg3 != 0);
if (enabled == ksu_su_compat_enabled) {
pr_info("cmd enable su but no need to change.\n");
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {// return the reply_ok directly
pr_err("prctl reply error, cmd: %lu\n", arg2);
}
return 0;
}
if (enabled) {
ksu_sucompat_init();
} else {
ksu_sucompat_exit();
}
ksu_su_compat_enabled = enabled;
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %lu\n", arg2);
}
return 0;
}
#endif
// all other cmds are for 'root manager'
if (!from_manager) {
return 0;
@@ -503,7 +561,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
}
return 0;
}
#ifndef CONFIG_KSU_KPROBES_HOOK
if (arg2 == CMD_ENABLE_SU) {
bool enabled = (arg3 != 0);
if (enabled == ksu_su_compat_enabled) {
@@ -527,6 +585,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0;
}
#endif
return 0;
}
@@ -580,11 +640,13 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
if (path.dentry != path.mnt->mnt_root) {
// it is not root mountpoint, maybe umounted by others already.
path_put(&path);
return;
}
// we are only interest in some specific mounts
if (check_mnt && !should_umount(&path)) {
path_put(&path);
return;
}
@@ -658,7 +720,7 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
// try umount ksu temp path
try_umount("/debug_ramdisk", false, MNT_DETACH);
try_umount("/sbin", false, MNT_DETACH);
// try umount hosts file
try_umount("/system/etc/hosts", false, MNT_DETACH);
@@ -738,6 +800,19 @@ __maybe_unused int ksu_kprobe_exit(void)
return 0;
}
extern int ksu_handle_devpts(struct inode *inode); // sucompat.c
static int ksu_inode_permission(struct inode *inode, int mask)
{
if (unlikely(inode->i_sb && inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)) {
#ifdef CONFIG_KSU_DEBUG
pr_info("%s: devpts inode accessed with mask: %x\n", __func__, mask);
#endif
ksu_handle_devpts(inode);
}
return 0;
}
// kernel 4.9 and older
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
int ksu_key_permission(key_ref_t key_ref, const struct cred *cred,
@@ -781,6 +856,7 @@ static struct security_hook_list ksu_hooks[] = {
LSM_HOOK_INIT(task_prctl, ksu_task_prctl),
LSM_HOOK_INIT(inode_rename, ksu_inode_rename),
LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid),
LSM_HOOK_INIT(inode_permission, ksu_inode_permission),
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
LSM_HOOK_INIT(key_permission, ksu_key_permission)
#endif
@@ -969,7 +1045,7 @@ void __init ksu_core_init(void)
{
#ifdef CONFIG_KSU_LSM_SECURITY_HOOKS
ksu_lsm_hook_init();
#else
#else
pr_info("ksu_core_init: LSM hooks not in use.\n");
#endif
}

View File

@@ -173,3 +173,26 @@ long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
return ret;
}
#endif
static inline int ksu_access_ok(const void *addr, unsigned long size)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
return access_ok(addr, size);
#else
return access_ok(VERIFY_READ, addr, size);
#endif
}
long ksu_strncpy_from_user_retry(char *dst, const void __user *unsafe_addr,
long count)
{
long ret = ksu_strncpy_from_user_nofault(dst, unsafe_addr, count);
if (likely(ret >= 0))
return ret;
// we faulted! fallback to slow path
if (unlikely(!ksu_access_ok(unsafe_addr, count)))
return -EFAULT;
return strncpy_from_user(dst, unsafe_addr, count);
}

View File

@@ -23,6 +23,9 @@
extern long ksu_strncpy_from_user_nofault(char *dst,
const void __user *unsafe_addr,
long count);
extern long ksu_strncpy_from_user_retry(char *dst,
const void __user *unsafe_addr,
long count);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
extern struct key *init_session_keyring;

View File

@@ -23,7 +23,9 @@
#define CMD_UID_SHOULD_UMOUNT 13
#define CMD_IS_SU_ENABLED 14
#define CMD_ENABLE_SU 15
#define CMD_HOOK_MODE 16
#define CMD_GET_MANAGER_UID 16
#define CMD_HOOK_MODE 0xC0DEAD1A
#define EVENT_POST_FS_DATA 1
#define EVENT_BOOT_COMPLETED 2

View File

@@ -58,12 +58,11 @@ static void stop_input_hook();
static struct work_struct stop_vfs_read_work;
static struct work_struct stop_execve_hook_work;
static struct work_struct stop_input_hook_work;
#endif
#else
bool ksu_vfs_read_hook __read_mostly = true;
bool ksu_execveat_hook __read_mostly = true;
bool ksu_input_hook __read_mostly = true;
#endif
u32 ksu_devpts_sid;
@@ -197,7 +196,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) {
char first_arg[16];
ksu_strncpy_from_user_nofault(
ksu_strncpy_from_user_retry(
first_arg, p, sizeof(first_arg));
pr_info("/system/bin/init first arg: %s\n",
first_arg);
@@ -222,7 +221,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) {
char first_arg[16];
ksu_strncpy_from_user_nofault(
ksu_strncpy_from_user_retry(
first_arg, p, sizeof(first_arg));
pr_info("/init first arg: %s\n", first_arg);
if (!strcmp(first_arg, "--second-stage")) {
@@ -247,7 +246,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
}
char env[256];
// Reading environment variable strings from user space
if (ksu_strncpy_from_user_nofault(
if (ksu_strncpy_from_user_retry(
env, p, sizeof(env)) < 0)
continue;
// Parsing environment variable names and values
@@ -338,7 +337,7 @@ int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
return 0;
}
if (!d_is_reg(file->f_path.dentry)) {
if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) {
return 0;
}
@@ -396,10 +395,12 @@ int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
if (orig_read) {
fops_proxy.read = read_proxy;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
orig_read_iter = file->f_op->read_iter;
if (orig_read_iter) {
fops_proxy.read_iter = read_iter_proxy;
}
#endif
// replace the file_operations
file->f_op = &fops_proxy;
read_count_append = rc_count;
@@ -486,10 +487,12 @@ __maybe_unused int ksu_handle_execve_ksud(const char __user *filename_user,
struct filename filename_in, *filename_p;
char path[32];
#ifndef CONFIG_KSU_KPROBES_HOOK
// return early if disabled.
if (!ksu_execveat_hook) {
return 0;
}
#endif
if (!filename_user)
return 0;
@@ -632,6 +635,29 @@ static void do_stop_input_hook(struct work_struct *work)
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
#include "objsec.h" // task_security_struct
bool is_ksu_transition(const struct task_security_struct *old_tsec,
const struct task_security_struct *new_tsec)
{
static u32 ksu_sid;
char *secdata;
u32 seclen;
bool allowed = false;
if (!ksu_sid)
security_secctx_to_secid("u:r:su:s0", strlen("u:r:su:s0"), &ksu_sid);
if (security_secid_to_secctx(old_tsec->sid, &secdata, &seclen))
return false;
allowed = (!strcmp("u:r:init:s0", secdata) && new_tsec->sid == ksu_sid);
security_release_secctx(secdata, seclen);
return allowed;
}
#endif
static void stop_vfs_read_hook()
{
#ifdef CONFIG_KSU_KPROBES_HOOK

View File

@@ -36,14 +36,19 @@ static struct policydb *get_policydb(void)
return db;
}
static DEFINE_MUTEX(ksu_rules);
void apply_kernelsu_rules()
{
struct policydb *db;
if (!getenforce()) {
pr_info("SELinux permissive or disabled, apply rules!\n");
}
rcu_read_lock();
struct policydb *db = get_policydb();
mutex_lock(&ksu_rules);
db = get_policydb();
ksu_permissive(db, KERNEL_SU_DOMAIN);
ksu_typeattribute(db, KERNEL_SU_DOMAIN, "mlstrustedsubject");
@@ -130,11 +135,11 @@ void apply_kernelsu_rules()
// Allow all binder transactions
ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "binder", ALL);
// Allow system server kill su process
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid");
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill");
// Allow system server kill su process
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid");
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill");
rcu_read_unlock();
mutex_unlock(&ksu_rules);
}
#define MAX_SEPOL_LEN 128

View File

@@ -179,23 +179,8 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
if (unlikely(!filename_user))
return 0;
// nofault variant fails probably due to pagefault_disable
// some cpus dont really have that good speculative execution
// substitute set_fs, check if pointer is valid
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
if (!access_ok(VERIFY_READ, *filename_user, sizeof(path)))
return 0;
#else
if (!access_ok(*filename_user, sizeof(path)))
return 0;
#endif
// success = returns number of bytes and should be less than path
long len = strncpy_from_user(path, *filename_user, sizeof(path));
if (len <= 0 || len > sizeof(path))
return 0;
// strncpy_from_user_nofault does this too
path[sizeof(path) - 1] = '\0';
memset(path, 0, sizeof(path));
ksu_strncpy_from_user_retry(path, *filename_user, sizeof(path));
if (likely(memcmp(path, su, sizeof(su))))
return 0;

View File

@@ -170,7 +170,11 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
return FILLDIR_ACTOR_CONTINUE;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0)
strlcpy(data->dirpath, dirpath, DATA_PATH_LEN);
#else
strscpy(data->dirpath, dirpath, DATA_PATH_LEN);
#endif
data->depth = my_ctx->depth - 1;
list_add_tail(&data->list, my_ctx->data_path_list);
} else {
@@ -212,12 +216,53 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
return FILLDIR_ACTOR_CONTINUE;
}
/*
* small helper to check if lock is held
* false - file is stable
* true - file is being deleted/renamed
* possibly optional
*
*/
bool is_lock_held(const char *path)
{
struct path kpath;
// kern_path returns 0 on success
if (kern_path(path, 0, &kpath))
return true;
// just being defensive
if (!kpath.dentry) {
path_put(&kpath);
return true;
}
if (!spin_trylock(&kpath.dentry->d_lock)) {
pr_info("%s: lock held, bail out!\n", __func__);
path_put(&kpath);
return true;
}
// we hold it ourselves here!
spin_unlock(&kpath.dentry->d_lock);
path_put(&kpath);
return false;
}
// compat: https://elixir.bootlin.com/linux/v3.9/source/include/linux/fs.h#L771
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
#define S_MAGIC_COMPAT(x) ((x)->f_inode->i_sb->s_magic)
#else
#define S_MAGIC_COMPAT(x) ((x)->f_path.dentry->d_inode->i_sb->s_magic)
#endif
void search_manager(const char *path, int depth, struct list_head *uid_data)
{
int i, stop = 0;
struct list_head data_path_list;
INIT_LIST_HEAD(&data_path_list);
unsigned long data_app_magic = 0;
// Initialize APK cache list
struct apk_path_hash *pos, *n;
list_for_each_entry(pos, &apk_path_hash_list, list) {
@@ -226,7 +271,11 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
// First depth
struct data_path data;
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0)
strlcpy(data.dirpath, path, DATA_PATH_LEN);
#else
strscpy(data.dirpath, path, DATA_PATH_LEN);
#endif
data.depth = depth;
list_add_tail(&data.list, &data_path_list);
@@ -248,6 +297,24 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
pr_err("Failed to open directory: %s, err: %ld\n", pos->dirpath, PTR_ERR(file));
goto skip_iterate;
}
// grab magic on first folder, which is /data/app
if (!data_app_magic) {
if (S_MAGIC_COMPAT(file)) {
data_app_magic = S_MAGIC_COMPAT(file);
pr_info("%s: dir: %s got magic! 0x%lx\n", __func__, pos->dirpath, data_app_magic);
} else {
filp_close(file, NULL);
goto skip_iterate;
}
}
if (S_MAGIC_COMPAT(file) != data_app_magic) {
pr_info("%s: skip: %s magic: 0x%lx expected: 0x%lx\n", __func__, pos->dirpath,
S_MAGIC_COMPAT(file), data_app_magic);
filp_close(file, NULL);
goto skip_iterate;
}
iterate_dir(file, &ctx.ctx);
filp_close(file, NULL);
@@ -286,13 +353,25 @@ static bool is_uid_exist(uid_t uid, char *package, void *data)
void track_throne()
{
struct file *fp =
ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0);
struct file *fp;
int tries = 0;
while (tries++ < 10) {
if (!is_lock_held(SYSTEM_PACKAGES_LIST_PATH)) {
fp = ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0);
if (!IS_ERR(fp))
break;
}
pr_info("%s: waiting for %s\n", __func__, SYSTEM_PACKAGES_LIST_PATH);
msleep(100); // migth as well add a delay
};
if (IS_ERR(fp)) {
pr_err("%s: open " SYSTEM_PACKAGES_LIST_PATH " failed: %ld\n",
__func__, PTR_ERR(fp));
pr_err("%s: open " SYSTEM_PACKAGES_LIST_PATH " failed: %ld\n", __func__, PTR_ERR(fp));
return;
}
} else
pr_info("%s: %s found!\n", __func__, SYSTEM_PACKAGES_LIST_PATH);
struct list_head uid_list;
INIT_LIST_HEAD(&uid_list);

View File

@@ -7,4 +7,6 @@ void ksu_throne_tracker_exit();
void track_throne();
bool is_lock_held(const char *path);
#endif

3
manager/.gitignore vendored
View File

@@ -7,5 +7,4 @@ build
captures
.cxx
local.properties
key.jks
setup.sh
key.jks

View File

@@ -34,6 +34,7 @@ android {
}
buildFeatures {
aidl = true
buildConfig = true
compose = true
prefab = true
@@ -133,8 +134,5 @@ dependencies {
implementation(libs.lsposed.cxx)
implementation(libs.mmrl.platform)
compileOnly(libs.mmrl.hidden.api)
implementation(libs.mmrl.ui)
implementation(libs.mmrl.webui)
}

View File

@@ -36,12 +36,4 @@
-dontwarn javax.lang.model.util.SimpleTypeVisitor7
-dontwarn javax.lang.model.util.SimpleTypeVisitor8
-dontwarn javax.lang.model.util.Types
-dontwarn javax.tools.Diagnostic$Kind
# MMRL:webui reflection
-keep class com.dergoogler.mmrl.webui.model.ModId { *; }
-keep class com.dergoogler.mmrl.webui.interfaces.** { *; }
-keep class com.rifsxd.ksunext.ui.webui.WebViewInterface { *; }
-keep,allowobfuscation class * extends com.dergoogler.mmrl.platform.content.IService { *; }
-dontwarn javax.tools.Diagnostic$Kind

View File

@@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<application
android:name=".KernelSUApplication"
@@ -24,6 +25,15 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="application/zip" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:pathPattern=".*\\.zip" />
</intent-filter>
</activity>
<activity

View File

@@ -0,0 +1,9 @@
// IKsuInterface.aidl
package com.rifsxd.ksunext;
import android.content.pm.PackageInfo;
import rikka.parcelablelist.ParcelableListSlice;
interface IKsuInterface {
ParcelableListSlice<PackageInfo> getPackages(int flags);
}

File diff suppressed because one or more lines are too long

View File

@@ -25,6 +25,13 @@ Java_com_rifsxd_ksunext_Natives_getVersion(JNIEnv *env, jobject) {
return get_version();
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_rifsxd_ksunext_Natives_getManagerUid(JNIEnv *env, jobject) {
uid_t manager_uid = get_manager_uid();
return (jint)manager_uid;
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_rifsxd_ksunext_Natives_getHookMode(JNIEnv *env, jobject) {
@@ -313,3 +320,9 @@ JNIEXPORT jboolean JNICALL
Java_com_rifsxd_ksunext_Natives_setSuEnabled(JNIEnv *env, jobject thiz, jboolean enabled) {
return set_su_enabled(enabled);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_rifsxd_ksunext_Natives_isZygiskEnabled(JNIEnv *env, jobject) {
return is_zygisk_enabled();
}

View File

@@ -6,6 +6,7 @@
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "ksu.h"
@@ -29,7 +30,9 @@
#define CMD_IS_UID_SHOULD_UMOUNT 13
#define CMD_IS_SU_ENABLED 14
#define CMD_ENABLE_SU 15
#define CMD_HOOK_MODE 16
#define CMD_GET_MANAGER_UID 16
#define CMD_HOOK_MODE 0xC0DEAD1A
static bool ksuctl(int cmd, void* arg1, void* arg2) {
int32_t result = 0;
@@ -51,23 +54,31 @@ bool become_manager(const char* pkg) {
}
// cache the result to avoid unnecessary syscall
static bool is_lkm;
int get_version() {
static bool is_lkm = false;
int get_version(void) {
int32_t version = -1;
int32_t lkm = 0;
ksuctl(CMD_GET_VERSION, &version, &lkm);
if (!is_lkm && lkm != 0) {
int32_t flags = 0;
ksuctl(CMD_GET_VERSION, &version, &flags);
if (!is_lkm && (flags & 0x1)) {
is_lkm = true;
}
return version;
}
uid_t get_manager_uid() {
uid_t manager_uid = 0;
ksuctl(CMD_GET_MANAGER_UID, &manager_uid, nullptr);
return manager_uid;
}
const char* get_hook_mode() {
static char mode[16];
ksuctl(CMD_HOOK_MODE, mode, nullptr);
return mode;
}
bool get_allow_list(int *uids, int *size) {
return ksuctl(CMD_GET_SU_LIST, uids, size);
}
@@ -103,4 +114,8 @@ bool is_su_enabled() {
// if ksuctl failed, we assume su is enabled, and it cannot be disabled.
ksuctl(CMD_IS_SU_ENABLED, &enabled, nullptr);
return enabled;
}
bool is_zygisk_enabled() {
return !!getenv("ZYGISK_ENABLED");
}

View File

@@ -11,6 +11,8 @@ bool become_manager(const char *);
int get_version();
uid_t get_manager_uid();
const char* get_hook_mode();
bool get_allow_list(int *uids, int *size);
@@ -85,4 +87,6 @@ bool set_su_enabled(bool enabled);
bool is_su_enabled();
bool is_zygisk_enabled();
#endif //KERNELSU_KSU_H

View File

@@ -4,17 +4,12 @@ import android.app.Application
import android.system.Os
import coil.Coil
import coil.ImageLoader
import com.dergoogler.mmrl.platform.Platform
import me.zhanghai.android.appiconloader.coil.AppIconFetcher
import me.zhanghai.android.appiconloader.coil.AppIconKeyer
import okhttp3.Cache
import okhttp3.OkHttpClient
import java.io.File
import java.util.Locale
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import com.rifsxd.ksunext.ui.webui.initPlatform
lateinit var ksuApp: KernelSUApplication
@@ -26,11 +21,6 @@ class KernelSUApplication : Application() {
super.onCreate()
ksuApp = this
Platform.setHiddenApiExemptions()
// Pre-initialize WX Platform as early as possible
launchPlatformInit()
val context = this
val iconSize = resources.getDimensionPixelSize(android.R.dimen.app_icon_size)
Coil.setImageLoader(
@@ -61,11 +51,5 @@ class KernelSUApplication : Application() {
}.build()
}
private fun launchPlatformInit() {
// Use a coroutine to avoid blocking the main thread
GlobalScope.launch(Dispatchers.IO) {
initPlatform()
}
}
}

View File

@@ -0,0 +1,77 @@
package com.rifsxd.ksunext.ui;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import androidx.annotation.NonNull;
import com.topjohnwu.superuser.ipc.RootService;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import com.rifsxd.ksunext.IKsuInterface;
import rikka.parcelablelist.ParcelableListSlice;
/**
* @author weishu
* @date 2023/4/18.
*/
public class KsuService extends RootService {
private static final String TAG = "KsuService";
class Stub extends IKsuInterface.Stub {
@Override
public ParcelableListSlice<PackageInfo> getPackages(int flags) {
List<PackageInfo> list = getInstalledPackagesAll(flags);
Log.i(TAG, "getPackages: " + list.size());
return new ParcelableListSlice<>(list);
}
}
@Override
public IBinder onBind(@NonNull Intent intent) {
return new Stub();
}
List<Integer> getUserIds() {
List<Integer> result = new ArrayList<>();
UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
List<UserHandle> userProfiles = um.getUserProfiles();
for (UserHandle userProfile : userProfiles) {
int userId = userProfile.hashCode();
result.add(userProfile.hashCode());
}
return result;
}
ArrayList<PackageInfo> getInstalledPackagesAll(int flags) {
ArrayList<PackageInfo> packages = new ArrayList<>();
for (Integer userId : getUserIds()) {
Log.i(TAG, "getInstalledPackagesAll: " + userId);
packages.addAll(getInstalledPackagesAsUser(flags, userId));
}
return packages;
}
List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
try {
PackageManager pm = getPackageManager();
Method getInstalledPackagesAsUser = pm.getClass().getDeclaredMethod("getInstalledPackagesAsUser", int.class, int.class);
return (List<PackageInfo>) getInstalledPackagesAsUser.invoke(pm, flags, userId);
} catch (Throwable e) {
Log.e(TAG, "err", e);
}
return new ArrayList<>();
}
}

View File

@@ -16,11 +16,12 @@ object Natives {
// 10946: add capabilities
// 10977: change groups_count and groups to avoid overflow write
// 11071: Fix the issue of failing to set a custom SELinux type.
const val MINIMAL_SUPPORTED_KERNEL = 11071
// 12797: zygisk query and get manager uid.
const val MINIMAL_SUPPORTED_KERNEL = 12797
// 11640: Support query working mode, LKM or GKI
// when MINIMAL_SUPPORTED_KERNEL > 11640, we can remove this constant.
const val MINIMAL_SUPPORTED_KERNEL_LKM = 11648
const val MINIMAL_SUPPORTED_KERNEL_LKM = 12797
// 12404: Support disable sucompat mode
const val MINIMAL_SUPPORTED_SU_COMPAT = 12404
@@ -28,6 +29,9 @@ object Natives {
// 12569: support get hook mode
const val MINIMAL_SUPPORTED_HOOK_MODE = 12569
// 12750: support get manager UID
const val MINIMAL_SUPPORTED_MANAGER_UID = 12751
const val KERNEL_SU_DOMAIN = "u:r:su:s0"
const val ROOT_UID = 0
@@ -54,6 +58,12 @@ object Natives {
external fun uidShouldUmount(uid: Int): Boolean
/**
* Get the UID of the current root manager.
* @return manager UID, or 0 if unavailable.
*/
external fun getManagerUid(): Int
/**
* Get a string indicating the SU hook mode enabled in kernel.
* The return values are:
@@ -64,6 +74,11 @@ object Natives {
*/
external fun getHookMode(): String?
/**
* Check if Zygisk injection is enabled in the environment.
*/
external fun isZygiskEnabled(): Boolean
/**
* Get the profile of the given package.
* @param key usually the package name
@@ -105,6 +120,9 @@ object Natives {
return version < MINIMAL_SUPPORTED_KERNEL
}
val KSU_WORK_DIR = "/data/adb/ksu/"
val GLOBAL_NAMESPACE_FILE = KSU_WORK_DIR + ".global_mnt"
@Immutable
@Parcelize
@Keep

View File

@@ -1,5 +1,7 @@
package com.rifsxd.ksunext.ui
import android.content.Intent
import android.net.Uri
import android.content.Context
import android.os.Build
import android.os.Bundle
@@ -22,6 +24,8 @@ import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
import androidx.compose.material3.Badge
import androidx.compose.material3.BadgedBox
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
@@ -36,6 +40,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
@@ -51,12 +56,22 @@ import com.rifsxd.ksunext.Natives
import com.rifsxd.ksunext.ksuApp
import com.rifsxd.ksunext.ui.screen.BottomBarDestination
import com.rifsxd.ksunext.ui.theme.KernelSUTheme
import com.rifsxd.ksunext.ui.util.*
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
import com.rifsxd.ksunext.ui.util.LocaleHelper
import com.rifsxd.ksunext.ui.util.rootAvailable
import com.rifsxd.ksunext.ui.util.install
import com.rifsxd.ksunext.ui.util.isSuCompatDisabled
import com.rifsxd.ksunext.ui.screen.FlashIt
import com.rifsxd.ksunext.ui.viewmodel.ModuleViewModel
import com.rifsxd.ksunext.ui.viewmodel.SuperUserViewModel
class MainActivity : ComponentActivity() {
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.let { LocaleHelper.applyLanguage(it) })
}
override fun onCreate(savedInstanceState: Bundle?) {
// Enable edge to edge
@@ -70,11 +85,41 @@ class MainActivity : ComponentActivity() {
val isManager = Natives.becomeManager(ksuApp.packageName)
if (isManager) install()
val zipUri: Uri? = when (intent?.action) {
Intent.ACTION_VIEW, Intent.ACTION_SEND -> {
val uri = intent.data ?: intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
uri?.let {
val name = when (it.scheme) {
"file" -> it.lastPathSegment ?: ""
"content" -> {
contentResolver.query(it, null, null, null, null)?.use { cursor ->
val nameIndex = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME)
if (cursor.moveToFirst() && nameIndex != -1) {
cursor.getString(nameIndex)
} else {
it.lastPathSegment ?: ""
}
} ?: (it.lastPathSegment ?: "")
}
else -> it.lastPathSegment ?: ""
}
if (name.lowercase().endsWith(".zip")) it else null
}
}
else -> null
}
setContent {
// Read AMOLED mode preference
val prefs = getSharedPreferences("settings", Context.MODE_PRIVATE)
val amoledMode = prefs.getBoolean("enable_amoled", false)
val moduleViewModel: ModuleViewModel = viewModel()
val superUserViewModel: SuperUserViewModel = viewModel()
val moduleUpdateCount = moduleViewModel.moduleList.count {
moduleViewModel.checkUpdate(it).first.isNotEmpty()
}
KernelSUTheme (
amoledMode = amoledMode
) {
@@ -82,6 +127,29 @@ class MainActivity : ComponentActivity() {
val snackBarHostState = remember { SnackbarHostState() }
val currentDestination = navController.currentBackStackEntryAsState()?.value?.destination
val navigator = navController.rememberDestinationsNavigator()
LaunchedEffect(zipUri) {
if (zipUri != null) {
navigator.navigate(
FlashScreenDestination(
FlashIt.FlashModules(listOf(zipUri)),
finishIntent = true
)
)
}
}
LaunchedEffect(Unit) {
if (superUserViewModel.appList.isEmpty()) {
superUserViewModel.fetchAppList()
}
if (moduleViewModel.moduleList.isEmpty()) {
moduleViewModel.fetchModuleList()
}
}
val showBottomBar = when (currentDestination?.route) {
FlashScreenDestination.route -> false // Hide for FlashScreenDestination
ExecuteModuleActionScreenDestination.route -> false // Hide for ExecuteModuleActionScreen
@@ -95,7 +163,7 @@ class MainActivity : ComponentActivity() {
enter = slideInVertically(initialOffsetY = { it }) + fadeIn(),
exit = slideOutVertically(targetOffsetY = { it }) + fadeOut()
) {
BottomBar(navController)
BottomBar(navController, moduleUpdateCount)
}
},
contentWindowInsets = WindowInsets(0, 0, 0, 0)
@@ -122,43 +190,59 @@ class MainActivity : ComponentActivity() {
}
@Composable
private fun BottomBar(navController: NavHostController) {
private fun BottomBar(navController: NavHostController, moduleUpdateCount: Int) {
val navigator = navController.rememberDestinationsNavigator()
val isManager = Natives.becomeManager(ksuApp.packageName)
val fullFeatured = isManager && !Natives.requireNewKernel() && rootAvailable()
val suCompatDisabled = isSuCompatDisabled()
val suSFS = getSuSFS()
val susSUMode = susfsSUS_SU_Mode()
NavigationBar(
tonalElevation = 8.dp,
windowInsets = WindowInsets.systemBars.union(WindowInsets.displayCutout).only(
WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom
)
) {
BottomBarDestination.entries.forEach { destination ->
if (!fullFeatured && destination.rootRequired) return@forEach
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
NavigationBarItem(
selected = isCurrentDestOnBackStack,
onClick = {
if (isCurrentDestOnBackStack) {
navigator.popBackStack(destination.direction, false)
}
navigator.navigate(destination.direction) {
popUpTo(NavGraphs.root) {
saveState = true
BottomBarDestination.entries
.forEach { destination ->
if (!fullFeatured && destination.rootRequired) return@forEach
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
NavigationBarItem(
selected = isCurrentDestOnBackStack,
onClick = {
if (isCurrentDestOnBackStack) {
navigator.popBackStack(destination.direction, false)
}
launchSingleTop = true
restoreState = true
}
},
icon = {
if (isCurrentDestOnBackStack) {
Icon(destination.iconSelected, stringResource(destination.label))
} else {
Icon(destination.iconNotSelected, stringResource(destination.label))
}
},
label = { Text(stringResource(destination.label)) },
alwaysShowLabel = true
)
}
navigator.navigate(destination.direction) {
popUpTo(NavGraphs.root) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
},
icon = {
// Show badge for Module icon if moduleUpdateCount > 0
if (destination == BottomBarDestination.Module && moduleUpdateCount > 0) {
BadgedBox(badge = { Badge { Text(moduleUpdateCount.toString()) } }) {
if (isCurrentDestOnBackStack) {
Icon(destination.iconSelected, stringResource(destination.label))
} else {
Icon(destination.iconNotSelected, stringResource(destination.label))
}
}
} else {
if (isCurrentDestOnBackStack) {
Icon(destination.iconSelected, stringResource(destination.label))
} else {
Icon(destination.iconNotSelected, stringResource(destination.label))
}
}
},
label = { Text(stringResource(destination.label)) },
alwaysShowLabel = true
)
}
}
}

View File

@@ -31,6 +31,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.text.font.FontWeight
import com.rifsxd.ksunext.BuildConfig
import com.rifsxd.ksunext.R
@@ -83,8 +84,9 @@ private fun AboutCardContent() {
Column {
Text(
stringResource(id = R.string.app_name),
style = MaterialTheme.typography.titleSmall,
text = stringResource(id = R.string.app_name),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
fontSize = 18.sp
)
Text(

View File

@@ -17,6 +17,7 @@ import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
@@ -402,7 +403,11 @@ private fun ConfirmDialog(visuals: ConfirmDialogVisuals, confirm: () -> Unit, di
dismiss()
},
title = {
Text(text = visuals.title)
Text(
text = visuals.title,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold
)
},
text = {
if (visuals.isMarkdown) {

View File

@@ -9,8 +9,10 @@ import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.vector.ImageVector
@@ -55,6 +57,8 @@ fun SwitchItem(
Text(
modifier = Modifier.then(stateAlpha),
text = title,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
}
},

View File

@@ -37,6 +37,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -44,6 +45,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -56,6 +58,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.dropUnlessResumed
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.ramcosta.composedestinations.annotation.Destination
@@ -94,6 +97,7 @@ fun AppProfileScreen(
val snackBarHost = LocalSnackbarHost.current
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val scope = rememberCoroutineScope()
val viewModel: SuperUserViewModel = viewModel()
val failToUpdateAppProfile = stringResource(R.string.failed_to_update_app_profile).format(appInfo.label)
val failToUpdateSepolicy = stringResource(R.string.failed_to_update_sepolicy).format(appInfo.label)
val suNotAllowed = stringResource(R.string.su_not_allowed).format(appInfo.label)
@@ -160,6 +164,7 @@ fun AppProfileScreen(
snackBarHost.showSnackbar(failToUpdateAppProfile.format(appInfo.uid))
} else {
profile = it
viewModel.updateAppProfile(packageName, it)
}
}
},
@@ -183,7 +188,11 @@ private fun AppProfileInner(
Column(modifier = modifier) {
AppMenuBox(packageName) {
ListItem(
headlineContent = { Text(appLabel) },
headlineContent = { Text(
text = appLabel,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
supportingContent = { Text(packageName) },
leadingContent = appIcon,
)
@@ -269,7 +278,11 @@ private fun TopBar(
) {
TopAppBar(
title = {
Text(stringResource(R.string.profile))
Text(
text = stringResource(R.string.profile),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
)
},
navigationIcon = {
IconButton(
@@ -288,7 +301,11 @@ private fun ProfileBox(
onModeChange: (Mode) -> Unit,
) {
ListItem(
headlineContent = { Text(stringResource(R.string.profile)) },
headlineContent = { Text(
text = stringResource(R.string.profile),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
supportingContent = { Text(mode.text) },
leadingContent = { Icon(Icons.Filled.AccountCircle, null) },
)

View File

@@ -1,15 +1,8 @@
package com.rifsxd.ksunext.ui.screen
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.only
@@ -25,7 +18,6 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.Text
@@ -35,56 +27,36 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.core.content.FileProvider
import androidx.lifecycle.compose.dropUnlessResumed
import com.maxkeppeker.sheets.core.models.base.Header
import com.maxkeppeker.sheets.core.models.base.IconSource
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.list.ListDialog
import com.maxkeppeler.sheets.list.models.ListOption
import com.maxkeppeler.sheets.list.models.ListSelection
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import com.rifsxd.ksunext.BuildConfig
import com.rifsxd.ksunext.Natives
import com.rifsxd.ksunext.ksuApp
import com.rifsxd.ksunext.R
import com.rifsxd.ksunext.ui.component.AboutDialog
import com.rifsxd.ksunext.ui.component.ConfirmResult
import com.rifsxd.ksunext.ui.component.DialogHandle
import com.rifsxd.ksunext.ui.component.SwitchItem
import com.rifsxd.ksunext.ui.component.rememberConfirmDialog
import com.rifsxd.ksunext.ui.component.rememberCustomDialog
import com.rifsxd.ksunext.ui.component.rememberLoadingDialog
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
import com.rifsxd.ksunext.ui.util.getBugreportFile
import com.rifsxd.ksunext.ui.util.*
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
/**
* @author rifsxd
@@ -131,7 +103,11 @@ fun BackupRestoreScreen(navigator: DestinationsNavigator) {
if (showRebootDialog) {
AlertDialog(
onDismissRequest = { showRebootDialog = false },
title = { Text(stringResource(R.string.reboot_required)) },
title = { Text(
text = stringResource(R.string.reboot_required),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold
) },
text = { Text(stringResource(R.string.reboot_message)) },
confirmButton = {
TextButton(onClick = {
@@ -158,7 +134,11 @@ fun BackupRestoreScreen(navigator: DestinationsNavigator) {
moduleBackup
)
},
headlineContent = { Text(moduleBackup) },
headlineContent = { Text(
text = moduleBackup,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
) },
modifier = Modifier.clickable {
scope.launch {
val result = backupDialog.awaitConfirm(title = moduleBackup, content = backupMessage)
@@ -174,7 +154,11 @@ fun BackupRestoreScreen(navigator: DestinationsNavigator) {
if (showRebootDialog) {
AlertDialog(
onDismissRequest = { showRebootDialog = false },
title = { Text(stringResource(R.string.reboot_required)) },
title = { Text(
text = stringResource(R.string.reboot_required),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold
) },
text = { Text(stringResource(R.string.reboot_message)) },
confirmButton = {
TextButton(onClick = {
@@ -195,9 +179,7 @@ fun BackupRestoreScreen(navigator: DestinationsNavigator) {
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
var useOverlayFs by rememberSaveable {
mutableStateOf(
prefs.getBoolean("use_overlay_fs", false)
)
mutableStateOf(readMountSystemFile())
}
val moduleRestore = stringResource(id = R.string.module_restore)
@@ -208,13 +190,15 @@ fun BackupRestoreScreen(navigator: DestinationsNavigator) {
Icon(
Icons.Filled.Restore,
moduleRestore,
tint = if (useOverlayFs) androidx.compose.material3.MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) else androidx.compose.material3.MaterialTheme.colorScheme.onSurface
tint = if (useOverlayFs) MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) else MaterialTheme.colorScheme.onSurface
)
},
headlineContent = {
Text(
moduleRestore,
color = if (useOverlayFs) androidx.compose.material3.MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) else androidx.compose.material3.MaterialTheme.colorScheme.onSurface
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
color = if (useOverlayFs) MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) else MaterialTheme.colorScheme.onSurface
)
},
modifier = Modifier.clickable(
@@ -244,7 +228,11 @@ fun BackupRestoreScreen(navigator: DestinationsNavigator) {
allowlistBackup
)
},
headlineContent = { Text(allowlistBackup) },
headlineContent = { Text(
text = allowlistBackup,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
) },
modifier = Modifier.clickable {
scope.launch {
val result = backupDialog.awaitConfirm(title = allowlistBackup, content = allowlistbackupMessage)
@@ -266,7 +254,11 @@ fun BackupRestoreScreen(navigator: DestinationsNavigator) {
allowlistRestore
)
},
headlineContent = { Text(allowlistRestore) },
headlineContent = { Text(
text = allowlistRestore,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
) },
modifier = Modifier.clickable {
scope.launch {
val result = restoreDialog.awaitConfirm(title = allowlistRestore, content = allowlistrestoreMessage)
@@ -289,7 +281,11 @@ private fun TopBar(
scrollBehavior: TopAppBarScrollBehavior? = null
) {
TopAppBar(
title = { Text(stringResource(R.string.backup_restore)) }, navigationIcon = {
title = { Text(
text = stringResource(R.string.backup_restore),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
) }, navigationIcon = {
IconButton(
onClick = onBack
) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }

View File

@@ -0,0 +1,359 @@
package com.rifsxd.ksunext.ui.screen
import android.content.Context
import android.content.Intent
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.*
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.Text
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.compose.dropUnlessResumed
import com.maxkeppeker.sheets.core.models.base.Header
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.list.ListDialog
import com.maxkeppeler.sheets.list.models.ListOption
import com.maxkeppeler.sheets.list.models.ListSelection
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator
import com.rifsxd.ksunext.Natives
import com.rifsxd.ksunext.ksuApp
import com.rifsxd.ksunext.R
import com.rifsxd.ksunext.ui.component.rememberCustomDialog
import com.rifsxd.ksunext.ui.component.SwitchItem
import com.rifsxd.ksunext.ui.util.LocaleHelper
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
import com.rifsxd.ksunext.ui.util.*
import java.util.Locale
/**
* @author rifsxd
* @date 2025/6/1.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Destination<RootGraph>
@Composable
fun CustomizationScreen(navigator: DestinationsNavigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val snackBarHost = LocalSnackbarHost.current
val isManager = Natives.becomeManager(ksuApp.packageName)
val ksuVersion = if (isManager) Natives.version else null
Scaffold(
topBar = {
TopBar(
onBack = dropUnlessResumed {
navigator.popBackStack()
},
scrollBehavior = scrollBehavior
)
},
snackbarHost = { SnackbarHost(snackBarHost) },
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
) { paddingValues ->
Column(
modifier = Modifier
.padding(paddingValues)
.nestedScroll(scrollBehavior.nestedScrollConnection)
.verticalScroll(rememberScrollState())
) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
// Track language state with current app locale
var currentAppLocale by remember { mutableStateOf(LocaleHelper.getCurrentAppLocale(context)) }
// Listen for preference changes
LaunchedEffect(Unit) {
currentAppLocale = LocaleHelper.getCurrentAppLocale(context)
}
// Language setting with selection dialog
val languageDialog = rememberCustomDialog { dismiss ->
// Check if should use system language settings
if (LocaleHelper.useSystemLanguageSettings) {
// Android 13+ - Jump to system settings
LocaleHelper.launchSystemLanguageSettings(context)
dismiss()
} else {
// Android < 13 - Show app language selector
// Dynamically detect supported locales from resources
val supportedLocales = remember {
val locales = mutableListOf<java.util.Locale>()
// Add system default first
locales.add(java.util.Locale.ROOT) // This will represent "System Default"
// Dynamically detect available locales by checking resource directories
val resourceDirs = listOf(
"ar", "bg", "de", "fa", "fr", "hu", "in", "it",
"ja", "ko", "pl", "pt-rBR", "ru", "th", "tr",
"uk", "vi", "zh-rCN", "zh-rTW"
)
resourceDirs.forEach { dir ->
try {
val locale = when {
dir.contains("-r") -> {
val parts = dir.split("-r")
java.util.Locale.Builder()
.setLanguage(parts[0])
.setRegion(parts[1])
.build()
}
else -> java.util.Locale.Builder()
.setLanguage(dir)
.build()
}
// Test if this locale has translated resources
val config = android.content.res.Configuration()
config.setLocale(locale)
val localizedContext = context.createConfigurationContext(config)
// Try to get a translated string to verify the locale is supported
val testString = localizedContext.getString(R.string.settings_language)
val defaultString = context.getString(R.string.settings_language)
// If the string is different or it's English, it's supported
if (testString != defaultString || locale.language == "en") {
locales.add(locale)
}
} catch (e: Exception) {
// Skip unsupported locales
}
}
// Sort by display name
val sortedLocales = locales.drop(1).sortedBy { it.getDisplayName(it) }
mutableListOf<java.util.Locale>().apply {
add(locales.first()) // System default first
addAll(sortedLocales)
}
}
val allOptions = supportedLocales.map { locale ->
val tag = if (locale == java.util.Locale.ROOT) {
"system"
} else if (locale.country.isEmpty()) {
locale.language
} else {
"${locale.language}_${locale.country}"
}
val displayName = if (locale == java.util.Locale.ROOT) {
context.getString(R.string.system_default)
} else {
locale.getDisplayName(locale)
}
tag to displayName
}
val currentLocale = prefs.getString("app_locale", "system") ?: "system"
val options = allOptions.map { (tag, displayName) ->
ListOption(
titleText = displayName,
selected = currentLocale == tag
)
}
var selectedIndex by remember {
mutableIntStateOf(allOptions.indexOfFirst { (tag, _) -> currentLocale == tag })
}
ListDialog(
state = rememberUseCaseState(
visible = true,
onFinishedRequest = {
if (selectedIndex >= 0 && selectedIndex < allOptions.size) {
val newLocale = allOptions[selectedIndex].first
prefs.edit().putString("app_locale", newLocale).apply()
// Update local state immediately
currentAppLocale = LocaleHelper.getCurrentAppLocale(context)
// Apply locale change immediately for Android < 13
LocaleHelper.restartActivity(context)
}
dismiss()
},
onCloseRequest = {
dismiss()
}
),
header = Header.Default(
title = stringResource(R.string.settings_language),
),
selection = ListSelection.Single(
showRadioButtons = true,
options = options
) { index, _ ->
selectedIndex = index
}
)
}
}
val language = stringResource(id = R.string.settings_language)
// Compute display name based on current app locale (similar to the reference implementation)
val currentLanguageDisplay = remember(currentAppLocale) {
val locale = currentAppLocale
if (locale != null) {
locale.getDisplayName(locale)
} else {
context.getString(R.string.system_default)
}
}
ListItem(
leadingContent = { Icon(Icons.Filled.Translate, language) },
headlineContent = { Text(
text = language,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
) },
supportingContent = { Text(currentLanguageDisplay) },
modifier = Modifier.clickable {
languageDialog.show()
}
)
var useBanner by rememberSaveable {
mutableStateOf(
prefs.getBoolean("use_banner", true)
)
}
if (ksuVersion != null) {
SwitchItem(
icon = Icons.Filled.ViewCarousel,
title = stringResource(id = R.string.settings_banner),
summary = stringResource(id = R.string.settings_banner_summary),
checked = useBanner
) {
prefs.edit().putBoolean("use_banner", it).apply()
useBanner = it
}
}
var enableAmoled by rememberSaveable {
mutableStateOf(
prefs.getBoolean("enable_amoled", false)
)
}
var showRestartDialog by remember { mutableStateOf(false) }
if (isSystemInDarkTheme()) {
SwitchItem(
icon = Icons.Filled.Contrast,
title = stringResource(id = R.string.settings_amoled_mode),
summary = stringResource(id = R.string.settings_amoled_mode_summary),
checked = enableAmoled
) { checked ->
prefs.edit().putBoolean("enable_amoled", checked).apply()
enableAmoled = checked
showRestartDialog = true
}
if (showRestartDialog) {
AlertDialog(
onDismissRequest = { showRestartDialog = false },
title = { Text(
text = stringResource(R.string.restart_required),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold
) },
text = { Text(stringResource(R.string.restart_app_message)) },
confirmButton = {
TextButton(onClick = {
showRestartDialog = false
// Restart the app
val packageManager = context.packageManager
val intent = packageManager.getLaunchIntentForPackage(context.packageName)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
Runtime.getRuntime().exit(0)
}) {
Text(stringResource(R.string.restart_app))
}
},
dismissButton = {
TextButton(onClick = { showRestartDialog = false }) {
Text(stringResource(R.string.later))
}
}
)
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TopBar(
onBack: () -> Unit = {},
scrollBehavior: TopAppBarScrollBehavior? = null
) {
TopAppBar(
title = { Text(
text = stringResource(R.string.customization),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
) }, navigationIcon = {
IconButton(
onClick = onBack
) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }
},
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal),
scrollBehavior = scrollBehavior
)
}
@Preview
@Composable
private fun CustomizationPreview() {
CustomizationScreen(EmptyDestinationsNavigator)
}

View File

@@ -0,0 +1,152 @@
package com.rifsxd.ksunext.ui.screen
import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.*
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator
import kotlinx.coroutines.launch
import com.rifsxd.ksunext.Natives
import com.rifsxd.ksunext.ksuApp
import com.rifsxd.ksunext.R
import com.rifsxd.ksunext.ui.component.SwitchItem
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
import com.rifsxd.ksunext.ui.util.*
/**
* @author rifsxd
* @date 2025/6/15.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Destination<RootGraph>
@Composable
fun DeveloperScreen(navigator: DestinationsNavigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val snackBarHost = LocalSnackbarHost.current
val isManager = Natives.becomeManager(ksuApp.packageName)
val ksuVersion = if (isManager) Natives.version else null
Scaffold(
topBar = {
TopBar(
onBack = { navigator.popBackStack() },
scrollBehavior = scrollBehavior
)
},
snackbarHost = { SnackbarHost(snackBarHost) },
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
) { paddingValues ->
Column(
modifier = Modifier
.padding(paddingValues)
.nestedScroll(scrollBehavior.nestedScrollConnection)
.verticalScroll(rememberScrollState())
) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
// --- Developer Options Switch ---
var developerOptionsEnabled by rememberSaveable {
mutableStateOf(
prefs.getBoolean("enable_developer_options", false)
)
}
if (ksuVersion != null) {
SwitchItem(
icon = Icons.Filled.DeveloperMode,
title = stringResource(id = R.string.enable_developer_options),
summary = stringResource(id = R.string.enable_developer_options_summary),
checked = developerOptionsEnabled
) {
prefs.edit().putBoolean("enable_developer_options", it).apply()
developerOptionsEnabled = it
}
}
var enableWebDebugging by rememberSaveable {
mutableStateOf(
prefs.getBoolean("enable_web_debugging", false)
)
}
if (ksuVersion != null) {
SwitchItem(
enabled = developerOptionsEnabled,
icon = Icons.Filled.Web,
title = stringResource(id = R.string.enable_web_debugging),
summary = stringResource(id = R.string.enable_web_debugging_summary),
checked = enableWebDebugging
) {
prefs.edit().putBoolean("enable_web_debugging", it).apply()
enableWebDebugging = it
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TopBar(
onBack: () -> Unit = {},
scrollBehavior: TopAppBarScrollBehavior? = null
) {
TopAppBar(
title = { Text(
text = stringResource(R.string.developer),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
) }, navigationIcon = {
IconButton(
onClick = onBack
) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }
},
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal),
scrollBehavior = scrollBehavior
)
}
@Preview
@Composable
private fun DeveloperPreview() {
DeveloperScreen(EmptyDestinationsNavigator)
}

View File

@@ -1,5 +1,6 @@
package com.rifsxd.ksunext.ui.screen
import android.content.Context
import android.os.Environment
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Column
@@ -34,7 +35,9 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.platform.LocalView
@@ -69,6 +72,11 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
var actionResult: Boolean
var isActionRunning by rememberSaveable { mutableStateOf(true) }
val context = LocalContext.current
// Read developer options from SharedPreferences
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val developerOptionsEnabled = prefs.getBoolean("enable_developer_options", false)
val view = LocalView.current
DisposableEffect(isActionRunning) {
view.keepScreenOn = isActionRunning
@@ -158,7 +166,7 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
}
Text(
modifier = Modifier.padding(8.dp),
text = text,
text = if (developerOptionsEnabled) logContent.toString() else text,
fontSize = MaterialTheme.typography.bodySmall.fontSize,
fontFamily = FontFamily.Monospace,
lineHeight = MaterialTheme.typography.bodySmall.lineHeight,
@@ -171,7 +179,11 @@ fun ExecuteModuleActionScreen(navigator: DestinationsNavigator, moduleId: String
@Composable
private fun TopBar(isActionRunning: Boolean, onBack: () -> Unit = {}, onSave: () -> Unit = {}) {
TopAppBar(
title = { Text(stringResource(R.string.action)) },
title = { Text(
text = stringResource(R.string.action),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
) },
navigationIcon = {
IconButton(
onClick = onBack,

View File

@@ -1,5 +1,7 @@
package com.rifsxd.ksunext.ui.screen
import android.app.Activity
import android.content.Context
import android.net.Uri
import android.os.Environment
import android.os.Parcelable
@@ -40,11 +42,13 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
@@ -61,7 +65,12 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
import com.rifsxd.ksunext.R
import com.rifsxd.ksunext.ui.component.rememberConfirmDialog
import com.rifsxd.ksunext.ui.component.ConfirmResult
import com.rifsxd.ksunext.ui.component.KeyEventBlocker
import com.rifsxd.ksunext.ui.theme.ORANGE
import com.rifsxd.ksunext.ui.theme.GREEN
import com.rifsxd.ksunext.ui.theme.RED
import com.rifsxd.ksunext.ui.util.FlashResult
import com.rifsxd.ksunext.ui.util.LkmSelection
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
@@ -81,6 +90,12 @@ enum class FlashingStatus {
FAILED
}
fun Context.findActivity(): Activity? = when (this) {
is Activity -> this
is android.content.ContextWrapper -> baseContext.findActivity()
else -> null
}
// Lets you flash modules sequentially when mutiple zipUris are selected
fun flashModulesSequentially(
uris: List<Uri>,
@@ -104,7 +119,11 @@ fun flashModulesSequentially(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Destination<RootGraph>
fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
fun FlashScreen(
navigator: DestinationsNavigator,
flashIt: FlashIt,
finishIntent: Boolean = false
) {
var text by rememberSaveable { mutableStateOf("") }
var tempText: String
@@ -119,6 +138,13 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
mutableStateOf(FlashingStatus.FLASHING)
}
val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val developerOptionsEnabled = prefs.getBoolean("enable_developer_options", false)
val activity = context.findActivity()
val view = LocalView.current
DisposableEffect(flashing) {
view.keepScreenOn = flashing == FlashingStatus.FLASHING
@@ -131,12 +157,49 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
// Disable back button if flashing is running
}
LaunchedEffect(Unit) {
if (text.isNotEmpty()) {
return@LaunchedEffect
BackHandler(enabled = flashing != FlashingStatus.FLASHING) {
navigator.popBackStack()
if (finishIntent) activity?.finish()
}
val confirmDialog = rememberConfirmDialog()
var confirmed by rememberSaveable { mutableStateOf(flashIt !is FlashIt.FlashModules) }
var pendingFlashIt by rememberSaveable { mutableStateOf<FlashIt?>(null) }
var hasFlashed by rememberSaveable { mutableStateOf(false) }
LaunchedEffect(flashIt) {
if (flashIt is FlashIt.FlashModules && !confirmed) {
val uris = flashIt.uris
val moduleNames =
uris.mapIndexed { index, uri -> "\n${index + 1}. ${uri.getFileName(context)}" }
.joinToString("")
val confirmContent =
context.getString(R.string.module_install_prompt_with_name, moduleNames)
val confirmTitle = context.getString(R.string.module)
val result = confirmDialog.awaitConfirm(
title = confirmTitle,
content = confirmContent,
markdown = true
)
if (result == ConfirmResult.Confirmed) {
confirmed = true
pendingFlashIt = flashIt
} else {
// User cancelled, go back
navigator.popBackStack()
if (finishIntent) activity?.finish()
}
} else {
confirmed = true
pendingFlashIt = flashIt
}
}
LaunchedEffect(confirmed, pendingFlashIt) {
if (!confirmed || pendingFlashIt == null || text.isNotEmpty() || hasFlashed) return@LaunchedEffect
hasFlashed = true
withContext(Dispatchers.IO) {
flashIt(flashIt, onStdout = {
flashIt(pendingFlashIt!!, onStdout = {
tempText = "$it\n"
if (tempText.startsWith("")) { // clear command
text = tempText.substring(6)
@@ -165,6 +228,7 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
flashing,
onBack = dropUnlessResumed {
navigator.popBackStack()
if (finishIntent) activity?.finish()
},
onSave = {
scope.launch {
@@ -204,19 +268,49 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
icon = { Icon(Icons.Filled.Close, contentDescription = null) },
onClick = {
navigator.popBackStack()
if (finishIntent) activity?.finish()
}
)
}
if (flashIt is FlashIt.FlashBoot && (flashing == FlashingStatus.SUCCESS || flashing == FlashingStatus.FAILED)) {
// Close button for LKM flashing
ExtendedFloatingActionButton(
text = { Text(text = stringResource(R.string.close)) },
icon = { Icon(Icons.Filled.Close, contentDescription = null) },
onClick = {
navigator.popBackStack()
val isLocalPatch = flashIt.boot != null && !flashIt.ota
val isDirectOrOta = flashIt.boot == null || flashIt.ota
if (flashing == FlashingStatus.FAILED) {
// Always show close on failure
ExtendedFloatingActionButton(
text = { Text(text = stringResource(R.string.close)) },
icon = { Icon(Icons.Filled.Close, contentDescription = null) },
onClick = {
navigator.popBackStack()
}
)
} else if (flashing == FlashingStatus.SUCCESS) {
if (isLocalPatch) {
// Local patching: show only Close
ExtendedFloatingActionButton(
text = { Text(text = stringResource(R.string.close)) },
icon = { Icon(Icons.Filled.Close, contentDescription = null) },
onClick = {
navigator.popBackStack()
}
)
} else if (isDirectOrOta) {
// Direct install or OTA inactive slot: show only Reboot
ExtendedFloatingActionButton(
onClick = {
scope.launch {
withContext(Dispatchers.IO) {
reboot()
}
}
},
icon = { Icon(Icons.Filled.Refresh, contentDescription = stringResource(R.string.reboot)) },
text = { Text(text = stringResource(R.string.reboot)) }
)
}
)
}
}
},
contentWindowInsets = WindowInsets.safeDrawing,
@@ -237,7 +331,7 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
}
Text(
modifier = Modifier.padding(8.dp),
text = text,
text = if (developerOptionsEnabled) logContent.toString() else text,
fontSize = MaterialTheme.typography.bodySmall.fontSize,
fontFamily = FontFamily.Monospace,
lineHeight = MaterialTheme.typography.bodySmall.lineHeight,
@@ -246,6 +340,19 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
}
}
fun Uri.getFileName(context: Context): String {
val contentResolver = context.contentResolver
val cursor = contentResolver.query(this, null, null, null, null)
return cursor?.use {
val nameIndex = it.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME)
if (it.moveToFirst() && nameIndex != -1) {
it.getString(nameIndex)
} else {
this.lastPathSegment ?: "unknown.zip"
}
} ?: (this.lastPathSegment ?: "unknown.zip")
}
@Parcelize
sealed class FlashIt : Parcelable {
data class FlashBoot(val boot: Uri? = null, val lkm: LkmSelection, val ota: Boolean) :
@@ -299,7 +406,14 @@ private fun TopBar(
FlashingStatus.SUCCESS -> R.string.flash_success
FlashingStatus.FAILED -> R.string.flash_failed
}
)
),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
color = when (status) {
FlashingStatus.FLASHING -> ORANGE
FlashingStatus.SUCCESS -> GREEN
FlashingStatus.FAILED -> RED
}
)
},
navigationIcon = {

View File

@@ -8,8 +8,13 @@ import android.os.Looper
import android.system.Os
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.animation.*
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -29,6 +34,7 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.toUpperCase
@@ -50,8 +56,6 @@ import com.rifsxd.ksunext.R
import com.rifsxd.ksunext.ui.component.rememberConfirmDialog
import com.rifsxd.ksunext.ui.util.*
import com.rifsxd.ksunext.ui.util.module.LatestVersionInfo
import com.rifsxd.ksunext.ui.viewmodel.ModuleViewModel
import com.rifsxd.ksunext.ui.viewmodel.SuperUserViewModel
import java.util.*
@OptIn(ExperimentalMaterial3Api::class)
@@ -64,6 +68,10 @@ fun HomeScreen(navigator: DestinationsNavigator) {
val isManager = Natives.becomeManager(ksuApp.packageName)
val ksuVersion = if (isManager) Natives.version else null
val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val developerOptionsEnabled = prefs.getBoolean("enable_developer_options", false)
Scaffold(
topBar = {
TopBar(
@@ -88,28 +96,23 @@ fun HomeScreen(navigator: DestinationsNavigator) {
val lkmMode = ksuVersion?.let {
if (it >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM && kernelVersion.isGKI()) Natives.isLkmMode else null
}
val superUserViewModel: SuperUserViewModel = viewModel()
val moduleViewModel: ModuleViewModel = viewModel()
LaunchedEffect(Unit) {
if (superUserViewModel.appList.isEmpty()) {
superUserViewModel.fetchAppList()
}
if (moduleViewModel.moduleList.isEmpty()) {
moduleViewModel.fetchModuleList()
}
}
val moduleUpdateCount = moduleViewModel.moduleList.count {
moduleViewModel.checkUpdate(it).first.isNotEmpty()
}
StatusCard(kernelVersion, ksuVersion, lkmMode, moduleUpdateCount) {
StatusCard(kernelVersion, ksuVersion, lkmMode) {
navigator.navigate(InstallScreenDestination)
}
if (ksuVersion != null && rootAvailable()) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(IntrinsicSize.Min),
horizontalArrangement = Arrangement.spacedBy(14.dp)
) {
Box(modifier = Modifier.weight(1f)) { SuperuserCard() }
Box(modifier = Modifier.weight(1f)) { ModuleCard() }
}
}
if (isManager && Natives.requireNewKernel()) {
WarningCard(
stringResource(id = R.string.require_kernel_version).format(
@@ -129,7 +132,7 @@ fun HomeScreen(navigator: DestinationsNavigator) {
UpdateCard()
}
//NextCard()
InfoCard()
InfoCard(autoExpand = developerOptionsEnabled)
IssueReportCard()
//EXperimentalCard()
Spacer(Modifier)
@@ -137,6 +140,78 @@ fun HomeScreen(navigator: DestinationsNavigator) {
}
}
@Composable
private fun SuperuserCard() {
val count = getSuperuserCount()
ElevatedCard(
colors = CardDefaults.elevatedCardColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer
)
) {
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(
text = if (count <= 1) {
stringResource(R.string.home_superuser_count_singular)
} else {
stringResource(R.string.home_superuser_count_plural)
},
style = MaterialTheme.typography.bodySmall
)
Text(
text = count.toString(),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
}
}
}
}
@Composable
private fun ModuleCard() {
val count = getModuleCount()
ElevatedCard(
colors = CardDefaults.elevatedCardColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer
)
) {
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(
text = if (count <= 1) {
stringResource(R.string.home_module_count_singular)
} else {
stringResource(R.string.home_module_count_plural)
},
style = MaterialTheme.typography.bodySmall
)
Text(
text = count.toString(),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
}
}
}
}
@Composable
fun UpdateCard() {
val context = LocalContext.current
@@ -189,6 +264,19 @@ fun RebootDropdownItem(@StringRes id: Int, reason: String = "") {
})
}
@Composable
fun getSeasonalIcon(): ImageVector {
val month = Calendar.getInstance().get(Calendar.MONTH) // 0-11 for January-December
return when (month) {
Calendar.DECEMBER, Calendar.JANUARY, Calendar.FEBRUARY -> Icons.Filled.AcUnit // Winter
Calendar.MARCH, Calendar.APRIL, Calendar.MAY -> Icons.Filled.Spa // Spring
Calendar.JUNE, Calendar.JULY, Calendar.AUGUST -> Icons.Filled.WbSunny // Summer
Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER -> Icons.Filled.Forest // Fall
else -> Icons.Filled.Whatshot // Fallback icon
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TopBar(
@@ -197,8 +285,46 @@ private fun TopBar(
onInstallClick: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior? = null
) {
var isSpinning by remember { mutableStateOf(false) }
val rotation by animateFloatAsState(
targetValue = if (isSpinning) 360f else 0f,
animationSpec = tween(durationMillis = 800),
finishedListener = {
isSpinning = false
}
)
LaunchedEffect(Unit) {
isSpinning = true
}
TopAppBar(
title = { Text(stringResource(R.string.app_name)) },
title = {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
if (!isSpinning) isSpinning = true
}
) {
Icon(
imageVector = getSeasonalIcon(),
contentDescription = null,
modifier = Modifier
.padding(end = 8.dp)
.graphicsLayer {
rotationZ = rotation
}
)
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
)
}
},
actions = {
if (ksuVersion != null) {
if (kernelVersion.isGKI()) {
@@ -245,17 +371,6 @@ private fun TopBar(
)
}
@Composable
fun getSeasonalIcon(): ImageVector {
val month = Calendar.getInstance().get(Calendar.MONTH) // 0-11 for January-December
return when (month) {
Calendar.DECEMBER, Calendar.JANUARY, Calendar.FEBRUARY -> Icons.Filled.AcUnit // Winter
Calendar.MARCH, Calendar.APRIL, Calendar.MAY -> Icons.Filled.Spa // Spring
Calendar.JUNE, Calendar.JULY, Calendar.AUGUST -> Icons.Filled.WbSunny // Summer
Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER -> Icons.Filled.Forest // Fall
else -> Icons.Filled.Whatshot // Fallback icon
}
}
@Composable
private fun StatusCard(
@@ -270,7 +385,7 @@ private fun StatusCard(
ElevatedCard(
colors = CardDefaults.elevatedCardColors(containerColor = run {
if (ksuVersion != null) MaterialTheme.colorScheme.secondaryContainer
if (ksuVersion != null) MaterialTheme.colorScheme.primaryContainer
else MaterialTheme.colorScheme.errorContainer
})
) {
@@ -288,8 +403,10 @@ private fun StatusCard(
intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
if (ksuVersion != null) {
context.startActivity(intent)
} else {
} else if (kernelVersion.isGKI()) {
onClickInstall()
} else {
Toast.makeText(context, "Something weird happened... 🤔", Toast.LENGTH_SHORT).show()
}
} else if (ksuVersion == null && kernelVersion.isGKI()) {
onClickInstall()
@@ -308,7 +425,7 @@ private fun StatusCard(
}
Icon(
getSeasonalIcon(), // Use dynamic seasonal icon
imageVector = Icons.Filled.CheckCircle,
contentDescription = stringResource(R.string.home_working)
)
Column(
@@ -318,69 +435,67 @@ private fun StatusCard(
val labelStyle = LabelItemDefaults.style
TextRow(
trailingContent = {
LabelItem(
icon = if (Natives.isSafeMode) {
{
Icon(
tint = labelStyle.contentColor,
imageVector = Icons.Filled.Security,
contentDescription = null
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(6.dp)
) {
LabelItem(
icon = if (Natives.isSafeMode) {
{
Icon(
tint = labelStyle.contentColor,
imageVector = Icons.Filled.Security,
contentDescription = null
)
}
} else {
null
},
text = {
Text(
text = workingMode,
style = labelStyle.textStyle.copy(color = labelStyle.contentColor),
)
}
} else {
null
},
text = {
Text(
text = workingMode,
style = labelStyle.textStyle.copy(color = labelStyle.contentColor),
)
if (isSuCompatDisabled()) {
LabelItem(
icon = {
Icon(
tint = labelStyle.contentColor,
imageVector = Icons.Filled.Warning,
contentDescription = null
)
},
text = {
Text(
text = stringResource(R.string.sucompat_disabled),
style = labelStyle.textStyle.copy(
color = labelStyle.contentColor,
)
)
}
)
}
)
}
}
) {
Text(
text = stringResource(id = R.string.home_working),
style = MaterialTheme.typography.titleMedium
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
}
Text(
text = stringResource(R.string.home_working_version, ksuVersion),
style = MaterialTheme.typography.bodyMedium
style = MaterialTheme.typography.bodySmall
)
Text(
text = stringResource(
R.string.home_superuser_count, getSuperuserCount()
), style = MaterialTheme.typography.bodyMedium
)
Text(
text = stringResource(R.string.home_module_count, getModuleCount()),
style = MaterialTheme.typography.bodyMedium
)
if (moduleUpdateCount > 0) {
Text(
text = stringResource(R.string.home_module_update_count, moduleUpdateCount),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.primary
)
}
val suSFS = getSuSFS()
if (suSFS == "Supported") {
Text(
text = "SuSFS: " + stringResource(R.string.susfs_supported),
style = MaterialTheme.typography.bodyMedium
)
}
}
}
kernelVersion.isGKI() -> {
Icon(Icons.Filled.Report, stringResource(R.string.home_not_installed))
Icon(Icons.Filled.NewReleases, stringResource(R.string.home_not_installed))
Column(Modifier.padding(start = 20.dp)) {
Text(
text = stringResource(R.string.home_not_installed),
@@ -395,7 +510,7 @@ private fun StatusCard(
}
else -> {
Icon(Icons.Filled.Dangerous, stringResource(R.string.home_failure))
Icon(Icons.Filled.Cancel, stringResource(R.string.home_failure))
Column(Modifier.padding(start = 20.dp)) {
Text(
text = stringResource(R.string.home_failure),
@@ -436,30 +551,30 @@ fun WarningCard(
}
@Composable
private fun InfoCard() {
private fun InfoCard(autoExpand: Boolean = false) {
val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
var useOverlayFs by rememberSaveable {
mutableStateOf(prefs.getBoolean("use_overlay_fs", false))
}
val isManager = Natives.becomeManager(ksuApp.packageName)
val ksuVersion = if (isManager) Natives.version else null
LaunchedEffect(Unit) {
useOverlayFs = prefs.getBoolean("use_overlay_fs", false)
}
var expanded by rememberSaveable { mutableStateOf(false) }
val developerOptionsEnabled = prefs.getBoolean("enable_developer_options", false)
LaunchedEffect(autoExpand) {
if (autoExpand) {
expanded = true
}
}
ElevatedCard {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(start = 24.dp, top = 24.dp, end = 24.dp, bottom = 16.dp)
.padding(start = 24.dp, top = 24.dp, end = 24.dp, bottom = 24.dp)
) {
var expanded by rememberSaveable { mutableStateOf(false) }
@Composable
fun InfoCardItem(label: String, content: String, icon: Any? = null) {
Row(verticalAlignment = Alignment.CenterVertically) {
@@ -480,11 +595,12 @@ private fun InfoCard() {
Column {
Text(
text = label,
style = MaterialTheme.typography.bodyLarge
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
Text(
text = content,
style = MaterialTheme.typography.bodyMedium,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(top = 4.dp)
)
}
@@ -495,16 +611,31 @@ private fun InfoCard() {
val managerVersion = getManagerVersion(context)
InfoCardItem(
label = stringResource(R.string.home_manager_version),
content = "${managerVersion.first} (${managerVersion.second})",
content = if (
developerOptionsEnabled &&
Natives.version >= Natives.MINIMAL_SUPPORTED_MANAGER_UID
) {
"${managerVersion.first} (${managerVersion.second}) | UID: ${Natives.getManagerUid()}"
} else {
"${managerVersion.first} (${managerVersion.second})"
},
icon = painterResource(R.drawable.ic_ksu_next),
)
if (Natives.version >= Natives.MINIMAL_SUPPORTED_HOOK_MODE) {
if (ksuVersion != null &&
Natives.version >= Natives.MINIMAL_SUPPORTED_HOOK_MODE) {
val hookMode =
Natives.getHookMode()
.takeUnless { it.isNullOrBlank() }
?: stringResource(R.string.unavailable)
Spacer(Modifier.height(16.dp))
InfoCardItem(
label = stringResource(R.string.hook_mode),
content = Natives.getHookMode() ?: stringResource(R.string.unavailable),
icon = Icons.Filled.Phishing,
label = stringResource(R.string.hook_mode),
content = hookMode,
icon = Icons.Filled.Phishing,
)
}
@@ -519,7 +650,7 @@ private fun InfoCard() {
val suSFS = getSuSFS()
if (suSFS == "Supported") {
val isSUS_SU = getSuSFSFeatures() == "CONFIG_KSU_SUSFS_SUS_SU"
val isSUS_SU = hasSuSFs_SUS_SU() == "Supported"
val susSUMode = if (isSUS_SU) {
val mode = susfsSUS_SU_Mode()
val modeString =
@@ -529,14 +660,23 @@ private fun InfoCard() {
Spacer(Modifier.height(16.dp))
InfoCardItem(
label = stringResource(R.string.home_susfs_version),
content = "${getSuSFSVersion()} (${getSuSFSVariant()}) $susSUMode",
content = "${stringResource(R.string.susfs_supported)} | ${getSuSFSVersion()} (${getSuSFSVariant()}) $susSUMode",
icon = painterResource(R.drawable.ic_sus),
)
}
if (Natives.isZygiskEnabled()) {
Spacer(Modifier.height(16.dp))
InfoCardItem(
label = stringResource(R.string.zygisk_status),
content = stringResource(R.string.enabled),
icon = Icons.Filled.Vaccines
)
}
}
if (!expanded) {
Spacer(Modifier.height(12.dp))
Spacer(Modifier.height(16.dp))
Row(
modifier = Modifier
.fillMaxWidth(),
@@ -683,17 +823,18 @@ fun IssueReportCard() {
Column(modifier = Modifier.weight(1f)) {
Text(
text = stringResource(R.string.issue_report_title),
style = MaterialTheme.typography.titleSmall
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
Spacer(Modifier.height(4.dp))
Text(
text = stringResource(R.string.issue_report_body),
style = MaterialTheme.typography.bodyMedium
style = MaterialTheme.typography.bodySmall
)
Spacer(Modifier.height(4.dp))
Text(
text = stringResource(R.string.issue_report_body_2),
style = MaterialTheme.typography.bodyMedium
style = MaterialTheme.typography.bodySmall
)
}
Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {

View File

@@ -41,7 +41,9 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -79,7 +81,7 @@ import com.rifsxd.ksunext.ui.util.rootAvailable
@Destination<RootGraph>
@Composable
fun InstallScreen(navigator: DestinationsNavigator) {
var showLkmWarning by remember { mutableStateOf(true) }
var showLkmWarning by rememberSaveable { mutableStateOf(true) }
if (showLkmWarning) {
AlertDialog(
@@ -87,7 +89,11 @@ fun InstallScreen(navigator: DestinationsNavigator) {
showLkmWarning = false
navigator.popBackStack()
},
title = { Text(stringResource(R.string.warning)) },
title = { Text(
text = stringResource(R.string.warning),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold
) },
text = { Text(stringResource(R.string.lkm_warning_message)) },
confirmButton = {
TextButton(onClick = { showLkmWarning = false }) {
@@ -233,7 +239,7 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {
val rootAvailable = rootAvailable()
val isAbDevice = isAbDevice()
val selectFileTip = stringResource(
id = R.string.select_file_tip, if (isInitBoot()) "init_boot" else "boot"
id = R.string.select_file_tip, if (isInitBoot()) "init_boot/vendor_boot" else "boot"
)
val radioOptions =
mutableListOf<InstallMethod>(InstallMethod.SelectFile(summary = selectFileTip))
@@ -369,7 +375,11 @@ private fun TopBar(
scrollBehavior: TopAppBarScrollBehavior? = null
) {
TopAppBar(
title = { Text(stringResource(R.string.install)) }, navigationIcon = {
title = { Text(
text = stringResource(R.string.install),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
) }, navigationIcon = {
IconButton(
onClick = onBack
) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }

View File

@@ -35,6 +35,7 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.LaunchedEffect
@@ -43,6 +44,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@@ -54,7 +56,6 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.FileProvider
import com.dergoogler.mmrl.platform.Platform
import com.maxkeppeker.sheets.core.models.base.Header
import com.maxkeppeker.sheets.core.models.base.IconSource
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
@@ -66,6 +67,8 @@ import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.generated.destinations.AppProfileTemplateScreenDestination
import com.ramcosta.composedestinations.generated.destinations.FlashScreenDestination
import com.ramcosta.composedestinations.generated.destinations.BackupRestoreScreenDestination
import com.ramcosta.composedestinations.generated.destinations.CustomizationScreenDestination
import com.ramcosta.composedestinations.generated.destinations.DeveloperScreenDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator
import kotlinx.coroutines.Dispatchers
@@ -85,6 +88,8 @@ import com.rifsxd.ksunext.ui.component.rememberLoadingDialog
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
import com.rifsxd.ksunext.ui.util.getBugreportFile
import com.rifsxd.ksunext.ui.util.*
import com.rifsxd.ksunext.ui.util.isGlobalNamespaceEnabled
import com.rifsxd.ksunext.ui.util.setGlobalNamespaceEnabled
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
@@ -98,6 +103,8 @@ import java.time.format.DateTimeFormatter
fun SettingScreen(navigator: DestinationsNavigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val snackBarHost = LocalSnackbarHost.current
var isGlobalNamespaceEnabled by rememberSaveable { mutableStateOf(false) }
isGlobalNamespaceEnabled = isGlobalNamespaceEnabled()
val isManager = Natives.becomeManager(ksuApp.packageName)
val ksuVersion = if (isManager) Natives.version else null
@@ -147,7 +154,11 @@ fun SettingScreen(navigator: DestinationsNavigator) {
if (ksuVersion != null) {
ListItem(
leadingContent = { Icon(Icons.Filled.Fence, profileTemplate) },
headlineContent = { Text(profileTemplate) },
headlineContent = { Text(
text = profileTemplate,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
supportingContent = { Text(stringResource(id = R.string.settings_profile_template_summary)) },
modifier = Modifier.clickable {
navigator.navigate(AppProfileTemplateScreenDestination)
@@ -189,14 +200,31 @@ fun SettingScreen(navigator: DestinationsNavigator) {
}
}
}
SwitchItem(
icon = Icons.Filled.Engineering,
title = stringResource(id = R.string.settings_global_namespace_mode),
summary = stringResource(id = R.string.settings_global_namespace_mode_summary),
checked = isGlobalNamespaceEnabled,
onCheckedChange = {
setGlobalNamespaceEnabled(
if (isGlobalNamespaceEnabled) {
"0"
} else {
"1"
}
)
isGlobalNamespaceEnabled = it
}
)
}
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val suSFS = getSuSFS()
val isSUS_SU = getSuSFSFeatures()
val isSUS_SU = hasSuSFs_SUS_SU() == "Supported"
if (suSFS == "Supported") {
if (isSUS_SU == "CONFIG_KSU_SUSFS_SUS_SU") {
if (isSUS_SU) {
var isEnabled by rememberSaveable {
mutableStateOf(susfsSUS_SU_Mode() == "2")
}
@@ -223,9 +251,11 @@ fun SettingScreen(navigator: DestinationsNavigator) {
}
var useOverlayFs by rememberSaveable {
mutableStateOf(
prefs.getBoolean("use_overlay_fs", false)
)
mutableStateOf(readMountSystemFile())
}
LaunchedEffect(Unit) {
useOverlayFs = readMountSystemFile()
}
var showRebootDialog by remember { mutableStateOf(false) }
@@ -243,8 +273,10 @@ fun SettingScreen(navigator: DestinationsNavigator) {
useOverlayFs = it
if (useOverlayFs) {
moduleBackup()
updateMountSystemFile(true)
} else {
moduleMigration()
updateMountSystemFile(false)
}
if (isManager) install()
showRebootDialog = true
@@ -254,7 +286,11 @@ fun SettingScreen(navigator: DestinationsNavigator) {
if (showRebootDialog) {
AlertDialog(
onDismissRequest = { showRebootDialog = false },
title = { Text(stringResource(R.string.reboot_required)) },
title = { Text(
text = stringResource(R.string.reboot_required),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold
) },
text = { Text(stringResource(R.string.reboot_message)) },
confirmButton = {
TextButton(onClick = {
@@ -288,122 +324,6 @@ fun SettingScreen(navigator: DestinationsNavigator) {
checkUpdate = it
}
var enableWebDebugging by rememberSaveable {
mutableStateOf(
prefs.getBoolean("enable_web_debugging", false)
)
}
if (ksuVersion != null) {
SwitchItem(
icon = Icons.Filled.Web,
title = stringResource(id = R.string.enable_web_debugging),
summary = stringResource(id = R.string.enable_web_debugging_summary),
checked = enableWebDebugging
) {
prefs.edit().putBoolean("enable_web_debugging", it).apply()
enableWebDebugging = it
}
}
var developerOptionsEnabled by rememberSaveable {
mutableStateOf(
prefs.getBoolean("enable_developer_options", false)
)
}
if (ksuVersion != null) {
SwitchItem(
icon = Icons.Filled.DeveloperMode,
title = stringResource(id = R.string.enable_developer_options),
summary = stringResource(id = R.string.enable_developer_options_summary),
checked = developerOptionsEnabled
) {
prefs.edit().putBoolean("enable_developer_options", it).apply()
developerOptionsEnabled = it
}
}
var useWebUIX by rememberSaveable {
mutableStateOf(
prefs.getBoolean("use_webuix", true)
)
}
if (ksuVersion != null) {
SwitchItem(
beta = false,
enabled = Platform.isAlive,
icon = Icons.Filled.WebAsset,
title = stringResource(id = R.string.use_webuix),
summary = stringResource(id = R.string.use_webuix_summary),
checked = useWebUIX
) {
prefs.edit().putBoolean("use_webuix", it).apply()
useWebUIX = it
}
}
var useWebUIXEruda by rememberSaveable {
mutableStateOf(
prefs.getBoolean("use_webuix_eruda", false)
)
}
if (ksuVersion != null) {
SwitchItem(
beta = false,
enabled = Platform.isAlive && useWebUIX && enableWebDebugging,
icon = Icons.Filled.FormatListNumbered,
title = stringResource(id = R.string.use_webuix_eruda),
summary = stringResource(id = R.string.use_webuix_eruda_summary),
checked = useWebUIXEruda
) {
prefs.edit().putBoolean("use_webuix_eruda", it).apply()
useWebUIXEruda = it
}
}
var enableAmoled by rememberSaveable {
mutableStateOf(
prefs.getBoolean("enable_amoled", false)
)
}
var showRestartDialog by remember { mutableStateOf(false) }
if (isSystemInDarkTheme()) {
SwitchItem(
icon = Icons.Filled.Contrast,
title = stringResource(id = R.string.settings_amoled_mode),
summary = stringResource(id = R.string.settings_amoled_mode_summary),
checked = enableAmoled
) { checked ->
prefs.edit().putBoolean("enable_amoled", checked).apply()
enableAmoled = checked
showRestartDialog = true
}
if (showRestartDialog) {
AlertDialog(
onDismissRequest = { showRestartDialog = false },
title = { Text(stringResource(R.string.restart_required)) },
text = { Text(stringResource(R.string.restart_app_message)) },
confirmButton = {
TextButton(onClick = {
showRestartDialog = false
// Restart the app
val packageManager = context.packageManager
val intent = packageManager.getLaunchIntentForPackage(context.packageName)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
Runtime.getRuntime().exit(0)
}) {
Text(stringResource(R.string.restart_app))
}
},
dismissButton = {
TextButton(onClick = { showRestartDialog = false }) {
Text(stringResource(R.string.later))
}
}
)
}
}
if (isOverlayAvailable && useOverlayFs) {
val shrink = stringResource(id = R.string.shrink_sparse_image)
val shrinkMessage = stringResource(id = R.string.shrink_sparse_image_message)
@@ -414,7 +334,11 @@ fun SettingScreen(navigator: DestinationsNavigator) {
shrink
)
},
headlineContent = { Text(shrink) },
headlineContent = { Text(
text = shrink,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
modifier = Modifier.clickable {
scope.launch {
val result = shrinkDialog.awaitConfirm(title = shrink, content = shrinkMessage)
@@ -428,6 +352,24 @@ fun SettingScreen(navigator: DestinationsNavigator) {
)
}
val customization = stringResource(id = R.string.customization)
ListItem(
leadingContent = {
Icon(
Icons.Filled.Palette,
customization
)
},
headlineContent = { Text(
text = customization,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
modifier = Modifier.clickable {
navigator.navigate(CustomizationScreenDestination)
}
)
if (ksuVersion != null) {
val backupRestore = stringResource(id = R.string.backup_restore)
ListItem(
@@ -437,13 +379,37 @@ fun SettingScreen(navigator: DestinationsNavigator) {
backupRestore
)
},
headlineContent = { Text(backupRestore) },
headlineContent = { Text(
text = backupRestore,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
modifier = Modifier.clickable {
navigator.navigate(BackupRestoreScreenDestination)
}
)
}
val developer = stringResource(id = R.string.developer)
if (ksuVersion != null) {
ListItem(
leadingContent = {
Icon(
Icons.Filled.DeveloperBoard,
developer
)
},
headlineContent = { Text(
text = developer,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
modifier = Modifier.clickable {
navigator.navigate(DeveloperScreenDestination)
}
)
}
val lkmMode = Natives.version >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM && Natives.isLkmMode
if (lkmMode) {
UninstallItem(navigator) {
@@ -460,7 +426,11 @@ fun SettingScreen(navigator: DestinationsNavigator) {
stringResource(id = R.string.export_log)
)
},
headlineContent = { Text(stringResource(id = R.string.export_log)) },
headlineContent = { Text(
text = stringResource(id = R.string.export_log),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
modifier = Modifier.clickable {
showBottomsheet = true
}
@@ -568,7 +538,11 @@ fun SettingScreen(navigator: DestinationsNavigator) {
about
)
},
headlineContent = { Text(about) },
headlineContent = { Text(
text = about,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
modifier = Modifier.clickable {
aboutDialog.show()
}
@@ -618,7 +592,11 @@ fun UninstallItem(
uninstall
)
},
headlineContent = { Text(uninstall) },
headlineContent = { Text(
text = uninstall,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
) },
modifier = Modifier.clickable {
uninstallDialog.show()
}
@@ -685,7 +663,11 @@ private fun TopBar(
scrollBehavior: TopAppBarScrollBehavior? = null,
) {
TopAppBar(
title = { Text(stringResource(R.string.settings)) },
title = { Text(
text = stringResource(R.string.settings),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
) },
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal),
scrollBehavior = scrollBehavior
)

View File

@@ -22,10 +22,10 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.text.font.FontWeight
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.dergoogler.mmrl.platform.Platform
import com.dergoogler.mmrl.ui.component.LabelItem
import com.dergoogler.mmrl.ui.component.LabelItemDefaults
import com.ramcosta.composedestinations.annotation.Destination
@@ -54,23 +54,14 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
}
}
LaunchedEffect(viewModel.search) {
if (viewModel.search.isEmpty()) {
listState.scrollToItem(0)
}
}
LaunchedEffect(Unit) {
if (viewModel.refreshOnReturn) {
viewModel.fetchAppList()
viewModel.refreshOnReturn = false
}
}
Scaffold(
topBar = {
SearchAppBar(
title = { Text(stringResource(R.string.superuser)) },
title = { Text(
text = stringResource(R.string.superuser),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
) },
searchText = viewModel.search,
onSearchTextChange = { viewModel.search = it },
onClearClick = { viewModel.search = "" },
@@ -105,7 +96,7 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
}
)
}, onClick = {
viewModel.showSystemApps = !viewModel.showSystemApps
viewModel.updateShowSystemApps(!viewModel.showSystemApps)
showDropdown = false
})
}
@@ -131,7 +122,6 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
) {
items(viewModel.appList, key = { it.packageName + it.uid }) { app ->
AppItem(app) {
viewModel.refreshOnReturn = true
navigator.navigate(AppProfileScreenDestination(app))
}
}
@@ -148,10 +138,17 @@ private fun AppItem(
) {
ListItem(
modifier = Modifier.clickable(onClick = onClickListener),
headlineContent = { Text(app.label) },
headlineContent = { Text(
text = app.label,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
) },
supportingContent = {
Column {
Text(app.packageName)
Text(
text = app.packageName,
style = MaterialTheme.typography.bodySmall
)
Spacer(modifier = Modifier.height(4.dp))
@@ -177,10 +174,18 @@ private fun AppItem(
LabelItem(
text = "CUSTOM",
style = LabelItemDefaults.style.copy(
containerColor = MaterialTheme.colorScheme.onTertiary,
containerColor = MaterialTheme.colorScheme.tertiaryContainer,
contentColor = MaterialTheme.colorScheme.onTertiaryContainer,
)
)
} else if (!app.allowSu && !Natives.uidShouldUmount(app.uid)) {
LabelItem(
text = "DEFAULT",
style = LabelItemDefaults.style.copy(
containerColor = MaterialTheme.colorScheme.primaryContainer,
contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
)
)
}
}
}

View File

@@ -14,6 +14,9 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
@@ -42,6 +45,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalClipboardManager
@@ -51,6 +55,7 @@ import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.dropUnlessResumed
import androidx.lifecycle.viewmodel.compose.viewModel
import com.dergoogler.mmrl.ui.component.LabelItem
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.generated.destinations.TemplateEditorScreenDestination
@@ -62,6 +67,15 @@ import kotlinx.coroutines.launch
import com.rifsxd.ksunext.R
import com.rifsxd.ksunext.ui.viewmodel.TemplateViewModel
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.snapshotFlow
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.core.tween
/**
* @author weishu
* @date 2023/10/20.
@@ -91,6 +105,30 @@ fun AppProfileTemplateScreen(
}
}
val listState = rememberLazyListState()
var showFab by remember { mutableStateOf(true) }
LaunchedEffect(listState) {
var lastIndex = listState.firstVisibleItemIndex
var lastOffset = listState.firstVisibleItemScrollOffset
snapshotFlow { listState.firstVisibleItemIndex to listState.firstVisibleItemScrollOffset }
.collect { (currIndex, currOffset) ->
val isScrollingDown = currIndex > lastIndex ||
(currIndex == lastIndex && currOffset > lastOffset + 4)
val isScrollingUp = currIndex < lastIndex ||
(currIndex == lastIndex && currOffset < lastOffset - 4)
when {
isScrollingDown && showFab -> showFab = false
isScrollingUp && !showFab -> showFab = true
}
lastIndex = currIndex
lastOffset = currOffset
}
}
Scaffold(
topBar = {
val clipboardManager = LocalClipboardManager.current
@@ -137,18 +175,30 @@ fun AppProfileTemplateScreen(
)
},
floatingActionButton = {
ExtendedFloatingActionButton(
onClick = {
navigator.navigate(
TemplateEditorScreenDestination(
TemplateViewModel.TemplateInfo(),
false
AnimatedVisibility(
visible = showFab,
enter = scaleIn(
animationSpec = tween(200),
initialScale = 0.8f
) + fadeIn(animationSpec = tween(400)),
exit = scaleOut(
animationSpec = tween(200),
targetScale = 0.8f
) + fadeOut(animationSpec = tween(400))
) {
ExtendedFloatingActionButton(
onClick = {
navigator.navigate(
TemplateEditorScreenDestination(
TemplateViewModel.TemplateInfo(),
false
)
)
)
},
icon = { Icon(Icons.Filled.Add, null) },
text = { Text(stringResource(id = R.string.app_profile_template_create)) },
)
},
icon = { Icon(Icons.Filled.Add, null) },
text = { Text(stringResource(id = R.string.app_profile_template_create)) },
)
}
},
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
) { innerPadding ->
@@ -160,11 +210,12 @@ fun AppProfileTemplateScreen(
}
) {
LazyColumn(
state = listState,
modifier = Modifier
.fillMaxSize()
.nestedScroll(scrollBehavior.nestedScrollConnection),
contentPadding = remember {
PaddingValues(bottom = 16.dp + 56.dp + 16.dp /* Scaffold Fab Spacing + Fab container height */)
PaddingValues(bottom = 16.dp /* Scaffold Fab Spacing + Fab container height */)
}
) {
items(viewModel.templateList, key = { it.id }) { app ->
@@ -186,7 +237,11 @@ private fun TemplateItem(
.clickable {
navigator.navigate(TemplateEditorScreenDestination(template, !template.local))
},
headlineContent = { Text(template.name) },
headlineContent = { Text(
text = template.name,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
) },
supportingContent = {
Column {
Text(
@@ -195,14 +250,19 @@ private fun TemplateItem(
fontSize = MaterialTheme.typography.bodySmall.fontSize,
)
Text(template.description)
FlowRow {
LabelText(label = "UID: ${template.uid}")
LabelText(label = "GID: ${template.gid}")
LabelText(label = template.context)
Spacer(modifier = Modifier.height(4.dp))
FlowRow(
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
LabelItem(text = "UID: ${template.uid}")
LabelItem(text = "GID: ${template.gid}")
LabelItem(text = template.context)
if (template.local) {
LabelText(label = "local")
LabelItem(text = "local")
} else {
LabelText(label = "remote")
LabelItem(text = "remote")
}
}
}
@@ -221,7 +281,11 @@ private fun TopBar(
) {
TopAppBar(
title = {
Text(stringResource(R.string.settings_profile_template))
Text(
text = stringResource(R.string.settings_profile_template),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
)
},
navigationIcon = {
IconButton(

View File

@@ -35,6 +35,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -262,7 +263,11 @@ private fun TopBar(
TopAppBar(
title = {
Column {
Text(title)
Text(
text = title,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Black,
)
if (summary.isNotBlank()) {
Text(
text = summary,

View File

@@ -9,4 +9,12 @@ val SECONDARY_LIGHT = Color(0xFFA6DA95) // Catppuccin Green
val PRIMARY_DARK = Color(0xFF7DC4E4) // Catppuccin Sky
val SECONDARY_DARK = Color(0xFFF5BDE6) // Catppuccin Pink
val AMOLED_BLACK = Color(0xFF000000) // Pure black for AMOLED
val AMOLED_BLACK = Color(0xFF000000) // Pure black for AMOLED
val DARK_PURPLE = Color(0xFF6E6CB6) // Catppuccin Mauve (dark purple)
val DARK_GREY = Color(0xFF363A4F) // Catppuccin Surface (dark grey)
val GREEN = Color(0xFF4CAF50) // Green
val RED = Color(0xFFF44336) // Red
val YELLOW = Color(0xFFFFEB3B) // Yellow
val ORANGE = Color(0xFFFF9800) // Orange

View File

@@ -59,12 +59,27 @@ fun KernelSUTheme(
surfaceContainerLowest = dynamicScheme.surfaceContainerLowest.blend(AMOLED_BLACK, 0.6f),
surfaceContainerHigh = dynamicScheme.surfaceContainerHigh.blend(AMOLED_BLACK, 0.6f),
surfaceContainerHighest = dynamicScheme.surfaceContainerHighest.blend(AMOLED_BLACK, 0.6f),
primaryContainer = dynamicScheme.primaryContainer.blend(AMOLED_BLACK, 0.6f),
secondaryContainer = dynamicScheme.secondaryContainer.blend(AMOLED_BLACK, 0.6f),
tertiaryContainer = dynamicScheme.tertiaryContainer.blend(AMOLED_BLACK, 0.6f)
)
}
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
amoledMode && darkTheme -> {
DarkColorScheme.copy(
background = AMOLED_BLACK,
surface = AMOLED_BLACK,
surfaceVariant = DARK_GREY.blend(AMOLED_BLACK, 0.8f),
surfaceContainer = DARK_GREY.blend(AMOLED_BLACK, 0.8f),
surfaceContainerLow = DARK_GREY.blend(AMOLED_BLACK, 0.8f),
surfaceContainerLowest = DARK_GREY.blend(AMOLED_BLACK, 0.8f),
surfaceContainerHigh = DARK_GREY.blend(AMOLED_BLACK, 0.8f),
surfaceContainerHighest = DARK_GREY.blend(AMOLED_BLACK, 0.8f),
)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}

View File

@@ -28,6 +28,7 @@ import java.io.File
* @date 2023/1/1.
*/
private const val TAG = "KsuCli"
private const val BUSYBOX = "/data/adb/ksu/bin/busybox"
private fun ksuDaemonMagicPath(): String {
return ksuApp.applicationInfo.nativeLibraryDir + File.separator + "libksud_magic.so"
@@ -37,10 +38,16 @@ private fun ksuDaemonOverlayfsPath(): String {
return ksuApp.applicationInfo.nativeLibraryDir + File.separator + "libksud_overlayfs.so"
}
fun readMountSystemFile(): Boolean {
val shell = getRootShell()
val filePath = "/data/adb/ksu/mount_system"
val result = ShellUtils.fastCmd(shell, "cat $filePath").trim()
return result == "OVERLAYFS"
}
// Get the path based on the user's choice
fun getKsuDaemonPath(): String {
val prefs = ksuApp.getSharedPreferences("settings", Context.MODE_PRIVATE)
val useOverlayFs = prefs.getBoolean("use_overlay_fs", false)
val useOverlayFs = readMountSystemFile()
return if (useOverlayFs) {
ksuDaemonOverlayfsPath()
@@ -49,6 +56,16 @@ fun getKsuDaemonPath(): String {
}
}
fun updateMountSystemFile(useOverlayFs: Boolean) {
val shell = getRootShell()
val filePath = "/data/adb/ksu/mount_system"
if (useOverlayFs) {
ShellUtils.fastCmd(shell, "echo -n OVERLAYFS > $filePath")
} else {
ShellUtils.fastCmd(shell, "echo -n MAGIC_MOUNT > $filePath")
}
}
data class FlashResult(val code: Int, val err: String, val showReboot: Boolean) {
constructor(result: Shell.Result, showReboot: Boolean) : this(result.code, result.err.joinToString("\n"), showReboot)
constructor(result: Shell.Result) : this(result, result.isSuccess)
@@ -86,12 +103,15 @@ fun Uri.getFileName(context: Context): String? {
fun createRootShell(globalMnt: Boolean = false): Shell {
Shell.enableVerboseLogging = BuildConfig.DEBUG
val builder = Shell.Builder.create()
val builder = Shell.Builder.create().apply {
setFlags(Shell.FLAG_MOUNT_MASTER)
}
return try {
if (globalMnt) {
builder.build(getKsuDaemonPath(), "debug", "su", "-g")
builder.build(ksuDaemonMagicPath(), "debug", "su", "-g")
} else {
builder.build(getKsuDaemonPath(), "debug", "su")
builder.build(ksuDaemonMagicPath(), "debug", "su")
}
} catch (e: Throwable) {
Log.w(TAG, "ksu failed: ", e)
@@ -386,6 +406,22 @@ fun hasMagisk(): Boolean {
return result.isSuccess
}
fun isGlobalNamespaceEnabled(): Boolean {
val shell = getRootShell()
val result =
ShellUtils.fastCmd(shell, "nsenter --mount=/proc/1/ns/mnt cat ${Natives.GLOBAL_NAMESPACE_FILE}")
Log.i(TAG, "is global namespace enabled: $result")
return result == "1"
}
fun setGlobalNamespaceEnabled(value: String) {
getRootShell().newJob()
.add("nsenter --mount=/proc/1/ns/mnt echo $value > ${Natives.GLOBAL_NAMESPACE_FILE}")
.submit { result ->
Log.i(TAG, "setGlobalNamespaceEnabled result: ${result.isSuccess} [${result.out}]")
}
}
fun isSepolicyValid(rules: String?): Boolean {
if (rules == null) {
return true
@@ -443,7 +479,7 @@ fun getFileName(context: Context, uri: Uri): String {
fun moduleBackupDir(): String? {
val shell = getRootShell()
val baseBackupDir = "/sdcard/.ksunext/modules"
val baseBackupDir = "/data/adb/ksu/backup/modules"
val resultBase = ShellUtils.fastCmd(shell, "mkdir -p $baseBackupDir").trim()
if (resultBase.isNotEmpty()) return null
@@ -471,10 +507,10 @@ fun moduleBackup(): Boolean {
val tarName = "modules_backup_$timestamp.tar"
val tarPath = "/data/local/tmp/$tarName"
val internalBackupDir = "/sdcard/.ksunext/modules"
val internalBackupDir = "/data/adb/ksu/backup/modules"
val internalBackupPath = "$internalBackupDir/$tarName"
val tarCmd = "tar -cpf $tarPath -C /data/adb/modules $(ls /data/adb/modules)"
val tarCmd = "$BUSYBOX tar -cpf $tarPath -C /data/adb/modules $(ls /data/adb/modules)"
val tarResult = ShellUtils.fastCmd(shell, tarCmd).trim()
if (tarResult.isNotEmpty()) return false
@@ -491,11 +527,11 @@ fun moduleBackup(): Boolean {
fun moduleRestore(): Boolean {
val shell = getRootShell()
val findTarCmd = "ls -t /sdcard/.ksunext/modules/modules_backup_*.tar 2>/dev/null | head -n 1"
val findTarCmd = "ls -t /data/adb/ksu/backup/modules/modules_backup_*.tar 2>/dev/null | head -n 1"
val tarPath = ShellUtils.fastCmd(shell, findTarCmd).trim()
if (tarPath.isEmpty()) return false
val extractCmd = "tar -xpf $tarPath -C /data/adb/modules_update"
val extractCmd = "$BUSYBOX tar -xpf $tarPath -C /data/adb/modules_update"
val extractResult = ShellUtils.fastCmd(shell, extractCmd).trim()
return extractResult.isEmpty()
}
@@ -514,10 +550,10 @@ fun allowlistBackup(): Boolean {
val tarName = "allowlist_backup_$timestamp.tar"
val tarPath = "/data/local/tmp/$tarName"
val internalBackupDir = "/sdcard/.ksunext/allowlist"
val internalBackupDir = "/data/adb/ksu/backup/allowlist"
val internalBackupPath = "$internalBackupDir/$tarName"
val tarCmd = "tar -cpf $tarPath -C /data/adb/ksu .allowlist"
val tarCmd = "$BUSYBOX tar -cpf $tarPath -C /data/adb/ksu .allowlist"
val tarResult = ShellUtils.fastCmd(shell, tarCmd).trim()
if (tarResult.isNotEmpty()) return false
@@ -534,13 +570,13 @@ fun allowlistBackup(): Boolean {
fun allowlistRestore(): Boolean {
val shell = getRootShell()
// Find the latest allowlist tar backup in /sdcard/.ksunext/allowlist
val findTarCmd = "ls -t /sdcard/.ksunext/allowlist/allowlist_backup_*.tar 2>/dev/null | head -n 1"
// Find the latest allowlist tar backup in /data/adb/ksu/backup/allowlist
val findTarCmd = "ls -t /data/adb/ksu/backup/allowlist/allowlist_backup_*.tar 2>/dev/null | head -n 1"
val tarPath = ShellUtils.fastCmd(shell, findTarCmd).trim()
if (tarPath.isEmpty()) return false
// Extract the tar to /data/adb/ksu (restores .allowlist folder with permissions)
val extractCmd = "tar -xpf $tarPath -C /data/adb/ksu"
val extractCmd = "$BUSYBOX tar -xpf $tarPath -C /data/adb/ksu"
val extractResult = ShellUtils.fastCmd(shell, extractCmd).trim()
return extractResult.isEmpty()
}
@@ -574,12 +610,19 @@ fun getSuSFSVariant(): String {
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} variant")
return result
}
fun getSuSFSFeatures(): String {
val shell = getRootShell()
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} features")
return result
}
fun hasSuSFs_SUS_SU(): String {
val shell = getRootShell()
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} sus_su support")
return result
}
fun susfsSUS_SU_0(): String {
val shell = getRootShell()
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} sus_su 0")
@@ -605,6 +648,25 @@ fun currentMountSystem(): String {
return result.substringAfter(":").substringAfter(" ").trim()
}
fun getModuleSize(dir: File): Long {
val shell = getRootShell()
val cmd = "$BUSYBOX du -sb '${dir.absolutePath}' | awk '{print \$1}'"
val result = ShellUtils.fastCmd(shell, cmd).trim()
return result.toLongOrNull() ?: 0L
}
fun isSuCompatDisabled(): Boolean {
return Natives.version >= Natives.MINIMAL_SUPPORTED_SU_COMPAT && !Natives.isSuEnabled()
}
fun zygiskRequired(dir: File): Boolean {
val shell = getRootShell()
val zygiskLib = "${dir.absolutePath}/zygisk"
val cmd = "ls \"$zygiskLib\""
val result = ShellUtils.fastCmdResult(shell, cmd)
return result
}
fun setAppProfileTemplate(id: String, template: String): Boolean {
val shell = getRootShell()
val escapedTemplate = template.replace("\"", "\\\"")
@@ -638,4 +700,4 @@ fun launchApp(packageName: String) {
fun restartApp(packageName: String) {
forceStopApp(packageName)
launchApp(packageName)
}
}

View File

@@ -0,0 +1,149 @@
package com.rifsxd.ksunext.ui.util
import android.annotation.TargetApi
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.os.Build
import android.provider.Settings
import java.util.Locale
object LocaleHelper {
/**
* Check if should use system language settings (Android 13+)
*/
val useSystemLanguageSettings: Boolean
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
/**
* Launch system app locale settings (Android 13+)
*/
fun launchSystemLanguageSettings(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
try {
val intent = Intent(Settings.ACTION_APP_LOCALE_SETTINGS).apply {
data = Uri.fromParts("package", context.packageName, null)
}
context.startActivity(intent)
} catch (e: Exception) {
// Fallback to app language settings if system settings not available
}
}
}
/**
* Apply saved language setting to context (for Android < 13)
*/
fun applyLanguage(context: Context): Context {
// On Android 13+, language is handled by system
if (useSystemLanguageSettings) {
return context
}
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val localeTag = prefs.getString("app_locale", "system") ?: "system"
return if (localeTag == "system") {
context
} else {
val locale = parseLocaleTag(localeTag)
setLocale(context, locale)
}
}
/**
* Set locale for context (Android < 13)
*/
private fun setLocale(context: Context, locale: Locale): Context {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResources(context, locale)
} else {
updateResourcesLegacy(context, locale)
}
}
@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, locale: Locale): Context {
val configuration = Configuration()
configuration.setLocale(locale)
configuration.setLayoutDirection(locale)
return context.createConfigurationContext(configuration)
}
@SuppressWarnings("deprecation")
private fun updateResourcesLegacy(context: Context, locale: Locale): Context {
Locale.setDefault(locale)
val resources = context.resources
val configuration = resources.configuration
configuration.locale = locale
configuration.setLayoutDirection(locale)
resources.updateConfiguration(configuration, resources.displayMetrics)
return context
}
/**
* Parse locale tag to Locale object
*/
private fun parseLocaleTag(tag: String): Locale {
return try {
if (tag.contains("_")) {
val parts = tag.split("_")
Locale.Builder()
.setLanguage(parts[0])
.setRegion(parts.getOrNull(1) ?: "")
.build()
} else {
Locale.Builder()
.setLanguage(tag)
.build()
}
} catch (e: Exception) {
Locale.getDefault()
}
}
/**
* Restart activity to apply language change (Android < 13)
*/
fun restartActivity(context: Context) {
if (context is Activity && !useSystemLanguageSettings) {
context.recreate()
}
}
/**
* Get current app locale
*/
fun getCurrentAppLocale(context: Context): Locale? {
return if (useSystemLanguageSettings) {
// Android 13+ - get from system app locale settings
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
try {
val localeManager = context.getSystemService(Context.LOCALE_SERVICE) as? android.app.LocaleManager
val locales = localeManager?.applicationLocales
if (locales != null && !locales.isEmpty) {
locales.get(0)
} else {
null // System default
}
} catch (e: Exception) {
null // System default
}
} else {
null // System default
}
} else {
// Android < 13 - get from SharedPreferences
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val localeTag = prefs.getString("app_locale", "system") ?: "system"
if (localeTag == "system") {
null // System default
} else {
parseLocaleTag(localeTag)
}
}
}
}

View File

@@ -1,5 +1,6 @@
package com.rifsxd.ksunext.ui.viewmodel
import android.net.Uri
import android.os.SystemClock
import android.util.Log
import androidx.compose.runtime.derivedStateOf
@@ -8,18 +9,19 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dergoogler.mmrl.platform.Platform
import com.dergoogler.mmrl.platform.TIMEOUT_MILLIS
import kotlinx.coroutines.delay
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import java.io.File
import java.text.Collator
import java.util.Locale
import com.rifsxd.ksunext.ksuApp
import com.rifsxd.ksunext.ui.util.HanziToPinyin
import com.rifsxd.ksunext.ui.util.listModules
import com.rifsxd.ksunext.ui.util.getModuleSize
import com.rifsxd.ksunext.ui.util.zygiskRequired
import org.json.JSONArray
import org.json.JSONObject
@@ -43,7 +45,10 @@ class ModuleViewModel : ViewModel() {
val updateJson: String,
val hasWebUi: Boolean,
val hasActionScript: Boolean,
val dirId: String
val dirId: String,
val size: Long,
val banner: String,
val zygiskRequired: Boolean
)
data class ModuleUpdateInfo(
@@ -60,11 +65,21 @@ class ModuleViewModel : ViewModel() {
var sortAToZ by mutableStateOf(false)
var sortZToA by mutableStateOf(false)
var sortSizeLowToHigh by mutableStateOf(false)
var sortSizeHighToLow by mutableStateOf(false)
var sortEnabledFirst by mutableStateOf(false)
var sortActionFirst by mutableStateOf(false)
var sortWebUiFirst by mutableStateOf(false)
val moduleList by derivedStateOf {
val comparator = when {
sortWebUiFirst -> compareByDescending<ModuleInfo> { it.hasWebUi }
sortEnabledFirst -> compareByDescending<ModuleInfo> { it.enabled }
sortActionFirst -> compareByDescending<ModuleInfo> { it.hasActionScript }
sortAToZ -> compareBy<ModuleInfo> { it.name.lowercase() }
sortZToA -> compareByDescending<ModuleInfo> { it.name.lowercase() }
sortSizeLowToHigh -> compareBy<ModuleInfo> { it.size }
sortSizeHighToLow -> compareByDescending<ModuleInfo> { it.size }
else -> compareBy<ModuleInfo> { it.dirId }
}.thenBy(Collator.getInstance(Locale.getDefault()), ModuleInfo::id)
@@ -85,25 +100,23 @@ class ModuleViewModel : ViewModel() {
isNeedRefresh = true
}
var zipUris by mutableStateOf<List<Uri>>(emptyList())
fun updateZipUris(uris: List<Uri>) {
zipUris = uris
}
fun clearZipUris() {
zipUris = emptyList()
}
fun fetchModuleList() {
viewModelScope.launch {
withContext(Dispatchers.Main) {
isRefreshing = true
}
isRefreshing = true
withContext(Dispatchers.IO) {
withTimeoutOrNull(TIMEOUT_MILLIS) {
while (!Platform.isAlive) {
delay(500)
}
} ?: run {
isRefreshing = false
Log.e(TAG, "Platform is not alive, aborting fetchModuleList")
return@withContext
}
val start = SystemClock.elapsedRealtime()
val oldModuleList = modules
@@ -117,6 +130,10 @@ class ModuleViewModel : ViewModel() {
.map { array.getJSONObject(it) }
.map { obj ->
val id = obj.getString("id")
val dirId = obj.getString("dir_id")
val moduleDir = File("/data/adb/modules/$dirId")
val size = getModuleSize(moduleDir)
val zygiskRequired = zygiskRequired(moduleDir)
ModuleInfo(
id,
@@ -131,7 +148,10 @@ class ModuleViewModel : ViewModel() {
obj.optString("updateJson"),
obj.optBoolean("web"),
obj.optBoolean("action"),
obj.getString("dir_id")
dirId,
size,
obj.optString("banner"),
zygiskRequired
)
}.toList()
isNeedRefresh = false

View File

@@ -1,7 +1,12 @@
package com.rifsxd.ksunext.ui.viewmodel
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.os.IBinder
import android.os.Parcelable
import android.os.SystemClock
import android.util.Log
@@ -11,29 +16,30 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.dergoogler.mmrl.platform.Platform
import com.dergoogler.mmrl.platform.TIMEOUT_MILLIS
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
import com.rifsxd.ksunext.IKsuInterface
import com.rifsxd.ksunext.Natives
import com.rifsxd.ksunext.ksuApp
import com.rifsxd.ksunext.ui.KsuService
import com.rifsxd.ksunext.ui.util.HanziToPinyin
import com.rifsxd.ksunext.ui.webui.getInstalledPackagesAll
import com.rifsxd.ksunext.ui.util.KsuCli
import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeoutOrNull
import java.text.Collator
import java.util.*
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import androidx.core.content.edit
class SuperUserViewModel : ViewModel() {
val isPlatformAlive get() = Platform.isAlive
var refreshOnReturn by mutableStateOf(false)
public set
companion object {
private const val TAG = "SuperUserViewModel"
private var apps by mutableStateOf<List<AppInfo>>(emptyList())
private var profileOverrides by mutableStateOf<Map<String, Natives.Profile>>(emptyMap())
}
@Parcelize
@@ -63,16 +69,26 @@ class SuperUserViewModel : ViewModel() {
}
}
private val prefs = ksuApp.getSharedPreferences("settings", Context.MODE_PRIVATE)!!
var search by mutableStateOf("")
var showSystemApps by mutableStateOf(false)
var showSystemApps by mutableStateOf(prefs.getBoolean("show_system_apps", false))
private set
var isRefreshing by mutableStateOf(false)
private set
fun updateShowSystemApps(newValue: Boolean) {
showSystemApps = newValue
prefs.edit { putBoolean("show_system_apps", newValue) }
}
private val sortedList by derivedStateOf {
val comparator = compareBy<AppInfo> {
when {
it.allowSu -> 0
it.hasCustomProfile -> 1
it.profile != null && it.profile.allowSu -> 0
it.profile != null && (
if (it.profile.allowSu) !it.profile.rootUseDefault else !it.profile.nonRootUseDefault
) -> 1
else -> 2
}
}.then(compareBy(Collator.getInstance(Locale.getDefault()), AppInfo::label))
@@ -82,7 +98,9 @@ class SuperUserViewModel : ViewModel() {
}
val appList by derivedStateOf {
sortedList.filter {
sortedList.map { app ->
profileOverrides[app.packageName]?.let { app.copy(profile = it) } ?: app
}.filter {
it.label.contains(search, true) || it.packageName.contains(
search,
true
@@ -94,26 +112,62 @@ class SuperUserViewModel : ViewModel() {
}
}
fun updateAppProfile(packageName: String, newProfile: Natives.Profile) {
profileOverrides = profileOverrides.toMutableMap().apply {
put(packageName, newProfile)
}
}
private suspend inline fun connectKsuService(
crossinline onDisconnect: () -> Unit = {}
): Pair<IBinder, ServiceConnection> = suspendCoroutine {
val connection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName?) {
onDisconnect()
}
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
it.resume(binder as IBinder to this)
}
}
val intent = Intent(ksuApp, KsuService::class.java)
val task = KsuService.bindOrTask(
intent,
Shell.EXECUTOR,
connection,
)
val shell = KsuCli.SHELL
task?.let { it1 -> shell.execTask(it1) }
}
private fun stopKsuService() {
val intent = Intent(ksuApp, KsuService::class.java)
KsuService.stop(intent)
}
suspend fun fetchAppList() {
isRefreshing = true
val result = connectKsuService {
Log.w(TAG, "KsuService disconnected")
}
withContext(Dispatchers.IO) {
withTimeoutOrNull(TIMEOUT_MILLIS) {
while (!isPlatformAlive) {
delay(500)
}
} ?: return@withContext // Exit early if timeout
val pm = ksuApp.packageManager
val start = SystemClock.elapsedRealtime()
val packages = Platform.getInstalledPackagesAll {
Log.e(TAG, "getInstalledPackagesAll:", it)
Toast.makeText(ksuApp, "Something went wrong, check logs", Toast.LENGTH_SHORT).show()
val binder = result.first
val allPackages = IKsuInterface.Stub.asInterface(binder).getPackages(0)
withContext(Dispatchers.Main) {
stopKsuService()
}
val packages = allPackages.list
apps = packages.map {
val appInfo = it.applicationInfo
val uid = appInfo!!.uid

View File

@@ -0,0 +1,46 @@
package com.rifsxd.ksunext.ui.webui;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import java.util.HashMap;
import java.util.Map;
public class AppIconUtil {
private static final Map<String, Bitmap> iconCache = new HashMap<>();
public static Bitmap loadAppIconSync(Context context, String packageName, int sizePx) {
Bitmap cached = iconCache.get(packageName);
if (cached != null) return cached;
try {
PackageManager pm = context.getPackageManager();
ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
Drawable drawable = pm.getApplicationIcon(appInfo);
Bitmap raw = drawableToBitmap(drawable, sizePx);
Bitmap icon = Bitmap.createScaledBitmap(raw, sizePx, sizePx, true);
iconCache.put(packageName, icon);
return icon;
} catch (Exception e) {
return null;
}
}
private static Bitmap drawableToBitmap(Drawable drawable, int size) {
if (drawable instanceof BitmapDrawable) return ((BitmapDrawable) drawable).getBitmap();
int width = drawable.getIntrinsicWidth() > 0 ? drawable.getIntrinsicWidth() : size;
int height = drawable.getIntrinsicHeight() > 0 ? drawable.getIntrinsicHeight() : size;
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bmp;
}
}

View File

@@ -1,73 +0,0 @@
package com.rifsxd.ksunext.ui.webui
import android.content.ServiceConnection
import android.content.pm.PackageInfo
import android.util.Log
import com.dergoogler.mmrl.platform.Platform
import com.dergoogler.mmrl.platform.hiddenApi.HiddenPackageManager
import com.dergoogler.mmrl.platform.hiddenApi.HiddenUserManager
import com.dergoogler.mmrl.platform.model.IProvider
import com.dergoogler.mmrl.platform.model.PlatformIntent
import com.rifsxd.ksunext.Natives
import com.rifsxd.ksunext.ksuApp
import com.topjohnwu.superuser.ipc.RootService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
class KsuLibSuProvider : IProvider {
override val name = "KsuLibSu"
override fun isAvailable() = true
override suspend fun isAuthorized() = Natives.becomeManager(ksuApp.packageName)
private val serviceIntent
get() = PlatformIntent(
ksuApp,
Platform.KsuNext,
SuService::class.java
)
override fun bind(connection: ServiceConnection) {
RootService.bind(serviceIntent.intent, connection)
}
override fun unbind(connection: ServiceConnection) {
RootService.stop(serviceIntent.intent)
}
}
suspend fun initPlatform() = withContext(Dispatchers.IO) {
try {
val active = Platform.init {
this.context = ksuApp
this.platform = Platform.KsuNext
this.provider = from(KsuLibSuProvider())
}
while (!active) {
delay(1000)
}
return@withContext active
} catch (e: Exception) {
Log.e("KsuLibSu", "Failed to initialize platform", e)
return@withContext false
}
}
fun Platform.Companion.getInstalledPackagesAll(catch: (Exception) -> Unit = {}): List<PackageInfo> =
try {
val packages = mutableListOf<PackageInfo>()
val userInfos = userManager.getUsers()
for (userInfo in userInfos) {
packages.addAll(packageManager.getInstalledPackages(0, userInfo.id))
}
packages
} catch (e: Exception) {
catch(e)
packageManager.getInstalledPackages(0, userManager.myUserId)
}

View File

@@ -0,0 +1,156 @@
package com.rifsxd.ksunext.ui.webui
import android.content.Context
import android.content.res.Configuration
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.dp
import com.rifsxd.ksunext.ui.theme.AMOLED_BLACK
/**
* @author rifsxd
* @date 2025/6/2.
*/
object MonetColorsProvider {
fun getColorsCss(context: Context): String {
val isDark = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
val amoledMode = prefs.getBoolean("enable_amoled", false)
val colorScheme = if (isDark) {
dynamicDarkColorScheme(context)
} else {
dynamicLightColorScheme(context)
}
fun blend(c1: Color, c2: Color, ratio: Float): Color {
val inv = 1f - ratio
return Color(
red = c1.red * inv + c2.red * ratio,
green = c1.green * inv + c2.green * ratio,
blue = c1.blue * inv + c2.blue * ratio,
alpha = c1.alpha
)
}
val monetColors = if (isDark && amoledMode) {
mapOf(
"primary" to colorScheme.primary.toArgb().toHex(),
"onPrimary" to colorScheme.onPrimary.toArgb().toHex(),
"primaryContainer" to blend(colorScheme.primaryContainer, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"onPrimaryContainer" to colorScheme.onPrimaryContainer.toArgb().toHex(),
"inversePrimary" to colorScheme.inversePrimary.toArgb().toHex(),
"secondary" to colorScheme.secondary.toArgb().toHex(),
"onSecondary" to colorScheme.onSecondary.toArgb().toHex(),
"secondaryContainer" to blend(colorScheme.secondaryContainer, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"onSecondaryContainer" to colorScheme.onSecondaryContainer.toArgb().toHex(),
"tertiary" to colorScheme.tertiary.toArgb().toHex(),
"onTertiary" to colorScheme.onTertiary.toArgb().toHex(),
"tertiaryContainer" to blend(colorScheme.tertiaryContainer, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"onTertiaryContainer" to colorScheme.onTertiaryContainer.toArgb().toHex(),
"background" to AMOLED_BLACK.toArgb().toHex(),
"onBackground" to colorScheme.onBackground.toArgb().toHex(),
"surface" to AMOLED_BLACK.toArgb().toHex(),
"tonalSurface" to blend(colorScheme.surfaceColorAtElevation(1.dp), AMOLED_BLACK, 0.6f).toArgb().toHex(),
"onSurface" to colorScheme.onSurface.toArgb().toHex(),
"surfaceVariant" to blend(colorScheme.surfaceVariant, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"onSurfaceVariant" to colorScheme.onSurfaceVariant.toArgb().toHex(),
"surfaceTint" to colorScheme.surfaceTint.toArgb().toHex(),
"inverseSurface" to colorScheme.inverseSurface.toArgb().toHex(),
"inverseOnSurface" to colorScheme.inverseOnSurface.toArgb().toHex(),
"error" to colorScheme.error.toArgb().toHex(),
"onError" to colorScheme.onError.toArgb().toHex(),
"errorContainer" to colorScheme.errorContainer.toArgb().toHex(),
"onErrorContainer" to colorScheme.onErrorContainer.toArgb().toHex(),
"outline" to colorScheme.outline.toArgb().toHex(),
"outlineVariant" to colorScheme.outlineVariant.toArgb().toHex(),
"scrim" to colorScheme.scrim.toArgb().toHex(),
"surfaceBright" to blend(colorScheme.surfaceBright, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"surfaceDim" to blend(colorScheme.surfaceDim, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"surfaceContainer" to blend(colorScheme.surfaceContainer, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"surfaceContainerHigh" to blend(colorScheme.surfaceContainerHigh, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"surfaceContainerHighest" to blend(colorScheme.surfaceContainerHighest, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"surfaceContainerLow" to blend(colorScheme.surfaceContainerLow, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"surfaceContainerLowest" to blend(colorScheme.surfaceContainerLowest, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"filledTonalButtonContentColor" to colorScheme.onPrimaryContainer.toArgb().toHex(),
"filledTonalButtonContainerColor" to blend(colorScheme.secondaryContainer, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"filledTonalButtonDisabledContentColor" to colorScheme.onSurfaceVariant.toArgb().toHex(),
"filledTonalButtonDisabledContainerColor" to blend(colorScheme.surfaceVariant, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"filledCardContentColor" to colorScheme.onPrimaryContainer.toArgb().toHex(),
"filledCardContainerColor" to blend(colorScheme.primaryContainer, AMOLED_BLACK, 0.6f).toArgb().toHex(),
"filledCardDisabledContentColor" to colorScheme.onSurfaceVariant.toArgb().toHex(),
"filledCardDisabledContainerColor" to blend(colorScheme.surfaceVariant, AMOLED_BLACK, 0.6f).toArgb().toHex()
)
} else {
mapOf(
"primary" to colorScheme.primary.toArgb().toHex(),
"onPrimary" to colorScheme.onPrimary.toArgb().toHex(),
"primaryContainer" to colorScheme.primaryContainer.toArgb().toHex(),
"onPrimaryContainer" to colorScheme.onPrimaryContainer.toArgb().toHex(),
"inversePrimary" to colorScheme.inversePrimary.toArgb().toHex(),
"secondary" to colorScheme.secondary.toArgb().toHex(),
"onSecondary" to colorScheme.onSecondary.toArgb().toHex(),
"secondaryContainer" to colorScheme.secondaryContainer.toArgb().toHex(),
"onSecondaryContainer" to colorScheme.onSecondaryContainer.toArgb().toHex(),
"tertiary" to colorScheme.tertiary.toArgb().toHex(),
"onTertiary" to colorScheme.onTertiary.toArgb().toHex(),
"tertiaryContainer" to colorScheme.tertiaryContainer.toArgb().toHex(),
"onTertiaryContainer" to colorScheme.onTertiaryContainer.toArgb().toHex(),
"background" to colorScheme.background.toArgb().toHex(),
"onBackground" to colorScheme.onBackground.toArgb().toHex(),
"surface" to colorScheme.surface.toArgb().toHex(),
"tonalSurface" to colorScheme.surfaceColorAtElevation(1.dp).toArgb().toHex(),
"onSurface" to colorScheme.onSurface.toArgb().toHex(),
"surfaceVariant" to colorScheme.surfaceVariant.toArgb().toHex(),
"onSurfaceVariant" to colorScheme.onSurfaceVariant.toArgb().toHex(),
"surfaceTint" to colorScheme.surfaceTint.toArgb().toHex(),
"inverseSurface" to colorScheme.inverseSurface.toArgb().toHex(),
"inverseOnSurface" to colorScheme.inverseOnSurface.toArgb().toHex(),
"error" to colorScheme.error.toArgb().toHex(),
"onError" to colorScheme.onError.toArgb().toHex(),
"errorContainer" to colorScheme.errorContainer.toArgb().toHex(),
"onErrorContainer" to colorScheme.onErrorContainer.toArgb().toHex(),
"outline" to colorScheme.outline.toArgb().toHex(),
"outlineVariant" to colorScheme.outlineVariant.toArgb().toHex(),
"scrim" to colorScheme.scrim.toArgb().toHex(),
"surfaceBright" to colorScheme.surfaceBright.toArgb().toHex(),
"surfaceDim" to colorScheme.surfaceDim.toArgb().toHex(),
"surfaceContainer" to colorScheme.surfaceContainer.toArgb().toHex(),
"surfaceContainerHigh" to colorScheme.surfaceContainerHigh.toArgb().toHex(),
"surfaceContainerHighest" to colorScheme.surfaceContainerHighest.toArgb().toHex(),
"surfaceContainerLow" to colorScheme.surfaceContainerLow.toArgb().toHex(),
"surfaceContainerLowest" to colorScheme.surfaceContainerLowest.toArgb().toHex(),
"filledTonalButtonContentColor" to colorScheme.onPrimaryContainer.toArgb().toHex(),
"filledTonalButtonContainerColor" to colorScheme.secondaryContainer.toArgb().toHex(),
"filledTonalButtonDisabledContentColor" to colorScheme.onSurfaceVariant.toArgb().toHex(),
"filledTonalButtonDisabledContainerColor" to colorScheme.surfaceVariant.toArgb().toHex(),
"filledCardContentColor" to colorScheme.onPrimaryContainer.toArgb().toHex(),
"filledCardContainerColor" to colorScheme.primaryContainer.toArgb().toHex(),
"filledCardDisabledContentColor" to colorScheme.onSurfaceVariant.toArgb().toHex(),
"filledCardDisabledContainerColor" to colorScheme.surfaceVariant.toArgb().toHex()
)
}
return monetColors.toCssVars()
}
private fun Map<String, String>.toCssVars(): String {
return buildString {
append(":root {\n")
for ((k, v) in this@toCssVars) {
append(" --$k: $v;\n")
}
append("}\n")
}
}
private fun Int.toHex(): String {
return String.format("#%06X", 0xFFFFFF and this)
}
}

View File

@@ -1,6 +1,7 @@
package com.rifsxd.ksunext.ui.webui;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.webkit.WebResourceResponse;
@@ -15,8 +16,12 @@ import com.topjohnwu.superuser.io.SuFileInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import com.rifsxd.ksunext.ui.webui.MonetColorsProvider;
/**
* Handler class to open files from file system by root access
* For more information about android storage please refer to
@@ -81,8 +86,11 @@ public final class SuFilePathHandler implements WebViewAssetLoader.PathHandler {
* which files can be loaded.
* @throws IllegalArgumentException if the directory is not allowed.
*/
private final Context mContext;
public SuFilePathHandler(@NonNull Context context, @NonNull File directory, Shell rootShell) {
try {
mContext = context;
mDirectory = new File(getCanonicalDirPath(directory));
if (!isAllowedInternalStorageDir(context)) {
throw new IllegalArgumentException("The given directory \"" + directory
@@ -130,6 +138,16 @@ public final class SuFilePathHandler implements WebViewAssetLoader.PathHandler {
@WorkerThread
@NonNull
public WebResourceResponse handle(@NonNull String path) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if ("internal/colors.css".equals(path)) {
String css = MonetColorsProvider.INSTANCE.getColorsCss(mContext);
return new WebResourceResponse(
"text/css",
"utf-8",
new ByteArrayInputStream(css.getBytes(StandardCharsets.UTF_8))
);
}
}
try {
File file = getCanonicalFileIfChild(mDirectory, path);
if (file != null) {

View File

@@ -1,14 +0,0 @@
package com.rifsxd.ksunext.ui.webui
import android.content.Intent
import android.os.IBinder
import com.dergoogler.mmrl.platform.model.PlatformIntent.Companion.getPlatform
import com.dergoogler.mmrl.platform.service.ServiceManager
import com.topjohnwu.superuser.ipc.RootService
class SuService : RootService() {
override fun onBind(intent: Intent): IBinder {
val mode = intent.getPlatform()
return ServiceManager(mode)
}
}

View File

@@ -15,8 +15,6 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updateLayoutParams
import androidx.webkit.WebViewAssetLoader
import com.dergoogler.mmrl.platform.model.ModId
import com.dergoogler.mmrl.webui.interfaces.WXOptions
import com.topjohnwu.superuser.Shell
import com.rifsxd.ksunext.ui.util.createRootShell
import java.io.File
@@ -27,6 +25,10 @@ class WebUIActivity : ComponentActivity() {
private var rootShell: Shell? = null
fun erudaConsole(context: android.content.Context): String {
return context.assets.open("eruda.min.js").bufferedReader().use { it.readText() }
}
override fun onCreate(savedInstanceState: Bundle?) {
// Enable edge to edge
@@ -41,15 +43,17 @@ class WebUIActivity : ComponentActivity() {
val name = intent.getStringExtra("name")!!
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
@Suppress("DEPRECATION")
setTaskDescription(ActivityManager.TaskDescription("KernelSU Next - $name"))
setTaskDescription(ActivityManager.TaskDescription("WebUI-Next | $name"))
} else {
val taskDescription =
ActivityManager.TaskDescription.Builder().setLabel("KernelSU Next - $name").build()
val taskDescription = ActivityManager.TaskDescription.Builder().setLabel("WebUI-Next | $name").build()
setTaskDescription(taskDescription)
}
val prefs = getSharedPreferences("settings", MODE_PRIVATE)
WebView.setWebContentsDebuggingEnabled(prefs.getBoolean("enable_web_debugging", false))
val developerOptionsEnabled = prefs.getBoolean("enable_developer_options", false)
val enableWebDebugging = prefs.getBoolean("enable_web_debugging", false)
WebView.setWebContentsDebuggingEnabled(developerOptionsEnabled && enableWebDebugging)
val moduleDir = "/data/adb/modules/${moduleId}"
val webRoot = File("${moduleDir}/webroot")
@@ -65,7 +69,7 @@ class WebUIActivity : ComponentActivity() {
val webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest,
request: WebResourceRequest
): WebResourceResponse? {
return webViewAssetLoader.shouldInterceptRequest(request.url)
}
@@ -85,11 +89,42 @@ class WebUIActivity : ComponentActivity() {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
settings.allowFileAccess = false
webviewInterface = WebViewInterface(
WXOptions(this@WebUIActivity, this, ModId(moduleId))
)
webviewInterface = WebViewInterface(this@WebUIActivity, this, moduleDir)
addJavascriptInterface(webviewInterface, "ksu")
setWebViewClient(webViewClient)
setWebViewClient(object : WebViewClient() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
val url = request.url
//POC: Handle ksu://icon/[packageName] to serve app icon via WebView
if (url.scheme.equals("ksu", ignoreCase = true) && url.host.equals("icon", ignoreCase = true)) {
val packageName = url.path?.substring(1)
if (!packageName.isNullOrEmpty()) {
val icon = AppIconUtil.loadAppIconSync(this@WebUIActivity, packageName, 512)
if (icon != null) {
val stream = java.io.ByteArrayOutputStream()
icon.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, stream)
val inputStream = java.io.ByteArrayInputStream(stream.toByteArray())
return WebResourceResponse("image/png", null, inputStream)
}
}
}
return webViewAssetLoader.shouldInterceptRequest(url)
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
if (developerOptionsEnabled && enableWebDebugging) {
view?.evaluateJavascript(
erudaConsole(this@WebUIActivity),
null
)
view?.evaluateJavascript("eruda.init();", null)
}
}
})
loadUrl("https://mui.kernelsu.org/index.html")
}
@@ -100,4 +135,4 @@ class WebUIActivity : ComponentActivity() {
super.onDestroy()
runCatching { rootShell?.close() }
}
}
}

View File

@@ -1,113 +0,0 @@
package com.rifsxd.ksunext.ui.webui
import android.app.ActivityManager
import android.os.Build
import android.os.Bundle
import android.webkit.WebView
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.lifecycle.lifecycleScope
import com.dergoogler.mmrl.platform.Platform
import com.dergoogler.mmrl.platform.model.ModId
import com.dergoogler.mmrl.ui.component.Loading
import com.dergoogler.mmrl.webui.screen.WebUIScreen
import com.dergoogler.mmrl.webui.util.rememberWebUIOptions
import com.rifsxd.ksunext.BuildConfig
import com.rifsxd.ksunext.ui.theme.KernelSUTheme
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class WebUIXActivity : ComponentActivity() {
private lateinit var webView: WebView
private val userAgent
get(): String {
val ksuVersion = BuildConfig.VERSION_CODE
val platform = Platform.get("Unknown") {
platform.name
}
val platformVersion = Platform.get(-1) {
moduleManager.versionCode
}
val osVersion = Build.VERSION.RELEASE
val deviceModel = Build.MODEL
return "KernelSU Next/$ksuVersion (Linux; Android $osVersion; $deviceModel; $platform/$platformVersion)"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
webView = WebView(this)
lifecycleScope.launch {
initPlatform()
}
val moduleId = intent.getStringExtra("id")!!
val name = intent.getStringExtra("name")!!
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
@Suppress("DEPRECATION")
setTaskDescription(ActivityManager.TaskDescription("KernelSU Next - $name"))
} else {
val taskDescription =
ActivityManager.TaskDescription.Builder().setLabel("KernelSU Next - $name").build()
setTaskDescription(taskDescription)
}
val prefs = getSharedPreferences("settings", MODE_PRIVATE)
setContent {
KernelSUTheme {
var isLoading by remember { mutableStateOf(true) }
LaunchedEffect(Platform.isAlive) {
while (!Platform.isAlive) {
delay(1000)
}
isLoading = false
}
if (isLoading) {
Loading()
return@KernelSUTheme
}
val webDebugging = prefs.getBoolean("enable_web_debugging", false)
val erudaInject = prefs.getBoolean("use_webuix_eruda", false)
val dark = isSystemInDarkTheme()
val options = rememberWebUIOptions(
modId = ModId(moduleId),
debug = webDebugging,
appVersionCode = BuildConfig.VERSION_CODE,
isDarkMode = dark,
enableEruda = erudaInject,
cls = WebUIXActivity::class.java,
userAgentString = userAgent
)
WebUIScreen(
webView = webView,
options = options,
interfaces = listOf(
WebViewInterface.factory()
)
)
}
}
}
}

View File

@@ -1,17 +1,22 @@
package com.rifsxd.ksunext.ui.webui
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.Base64
import android.app.Activity
import android.content.Context
import android.content.pm.ApplicationInfo
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.view.Window
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.widget.Toast
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import com.dergoogler.mmrl.webui.interfaces.WXInterface
import com.dergoogler.mmrl.webui.interfaces.WXOptions
import com.dergoogler.mmrl.webui.model.JavaScriptInterface
import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.ShellUtils
import com.topjohnwu.superuser.internal.UiThreadHandler
@@ -24,15 +29,10 @@ import java.io.File
import java.util.concurrent.CompletableFuture
class WebViewInterface(
wxOptions: WXOptions,
) : WXInterface(wxOptions) {
override var name: String = "ksu"
companion object {
fun factory() = JavaScriptInterface(WebViewInterface::class.java)
}
private val modDir get() = "/data/adb/modules/${modId.id}"
val context: Context,
private val webView: WebView,
private val modDir: String
) {
@JavascriptInterface
fun exec(cmd: String): String {
@@ -65,7 +65,7 @@ class WebViewInterface(
fun exec(
cmd: String,
options: String?,
callbackFunc: String,
callbackFunc: String
) {
val finalCommand = StringBuilder()
processOptions(finalCommand, options)
@@ -174,9 +174,9 @@ class WebViewInterface(
if (context is Activity) {
Handler(Looper.getMainLooper()).post {
if (enable) {
hideSystemUI(activity.window)
hideSystemUI(context.window)
} else {
showSystemUI(activity.window)
showSystemUI(context.window)
}
}
}
@@ -185,7 +185,7 @@ class WebViewInterface(
@JavascriptInterface
fun moduleInfo(): String {
val moduleInfos = JSONArray(listModules())
val currentModuleInfo = JSONObject()
var currentModuleInfo = JSONObject()
currentModuleInfo.put("moduleDir", modDir)
val moduleId = File(modDir).getName()
for (i in 0 until moduleInfos.length()) {
@@ -195,7 +195,7 @@ class WebViewInterface(
continue
}
val keys = currentInfo.keys()
var keys = currentInfo.keys()
for (key in keys) {
currentModuleInfo.put(key, currentInfo.get(key))
}
@@ -203,17 +203,158 @@ class WebViewInterface(
}
return currentModuleInfo.toString()
}
@JavascriptInterface
fun listSystemPackages(): String {
val pm = context.packageManager
val packages = pm.getInstalledPackages(0)
val packageNames = packages
.mapNotNull { pkg ->
val appInfo = pkg.applicationInfo
if (appInfo != null && (appInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0) {
pkg.packageName
} else null
}
.sorted()
val jsonArray = JSONArray()
for (pkgName in packageNames) {
jsonArray.put(pkgName)
}
return jsonArray.toString()
}
@JavascriptInterface
fun listUserPackages(): String {
val pm = context.packageManager
val packages = pm.getInstalledPackages(0)
val packageNames = packages
.mapNotNull { pkg ->
val appInfo = pkg.applicationInfo
if (appInfo != null && (appInfo.flags and ApplicationInfo.FLAG_SYSTEM) == 0) {
pkg.packageName
} else null
}
.sorted()
val jsonArray = JSONArray()
for (pkgName in packageNames) {
jsonArray.put(pkgName)
}
return jsonArray.toString()
}
@JavascriptInterface
fun listAllPackages(): String {
val pm = context.packageManager
val packages = pm.getInstalledPackages(0)
val packageNames = packages.map { it.packageName }.sorted()
val jsonArray = JSONArray()
for (pkgName in packageNames) {
jsonArray.put(pkgName)
}
return jsonArray.toString()
}
@JavascriptInterface
fun getPackagesInfo(packageNamesJson: String): String {
val pm = context.packageManager
val packageNames = JSONArray(packageNamesJson)
val jsonArray = JSONArray()
for (i in 0 until packageNames.length()) {
val pkgName = packageNames.getString(i)
try {
val pkg = pm.getPackageInfo(pkgName, 0)
val appInfo = pkg.applicationInfo
val obj = JSONObject()
obj.put("packageName", pkg.packageName)
obj.put("versionName", pkg.versionName ?: "")
obj.put("versionCode", pkg.longVersionCode)
obj.put("appLabel", if (appInfo != null) pm.getApplicationLabel(appInfo).toString() else "")
obj.put("isSystem", appInfo != null && (appInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0)
obj.put("uid", appInfo?.uid ?: JSONObject.NULL)
jsonArray.put(obj)
} catch (e: Exception) {
val obj = JSONObject()
obj.put("packageName", pkgName)
obj.put("error", "Package not found or inaccessible")
jsonArray.put(obj)
}
}
return jsonArray.toString()
}
private val packageIconCache = HashMap<String, String>()
@JavascriptInterface
fun cacheAllPackageIcons(size: Int) {
val pm = context.packageManager
val packages = pm.getInstalledPackages(0)
val outputStream = java.io.ByteArrayOutputStream()
for (pkg in packages) {
val pkgName = pkg.packageName
if (packageIconCache.containsKey(pkgName)) continue
try {
val appInfo = pm.getApplicationInfo(pkgName, 0)
val drawable = pm.getApplicationIcon(appInfo)
val bitmap = drawableToBitmap(drawable, size)
outputStream.reset()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
val byteArray = outputStream.toByteArray()
val iconBase64 = "data:image/png;base64," + Base64.encodeToString(byteArray, Base64.NO_WRAP)
packageIconCache[pkgName] = iconBase64
} catch (_: Exception) {
packageIconCache[pkgName] = ""
}
}
}
@JavascriptInterface
fun getPackagesIcons(packageNamesJson: String, size: Int): String {
val pm = context.packageManager
val packageNames = JSONArray(packageNamesJson)
val jsonArray = JSONArray()
val outputStream = java.io.ByteArrayOutputStream()
for (i in 0 until packageNames.length()) {
val pkgName = packageNames.getString(i)
val obj = JSONObject()
obj.put("packageName", pkgName)
var iconBase64 = packageIconCache[pkgName]
if (iconBase64 == null) {
try {
val appInfo = pm.getApplicationInfo(pkgName, 0)
val drawable = pm.getApplicationIcon(appInfo)
val bitmap = drawableToBitmap(drawable, size)
outputStream.reset()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
val byteArray = outputStream.toByteArray()
iconBase64 = "data:image/png;base64," + Base64.encodeToString(byteArray, Base64.NO_WRAP)
} catch (_: Exception) {
iconBase64 = ""
}
packageIconCache[pkgName] = iconBase64
}
obj.put("icon", iconBase64)
jsonArray.put(obj)
}
return jsonArray.toString()
}
}
fun drawableToBitmap(drawable: Drawable, size: Int): Bitmap {
if (drawable is BitmapDrawable && drawable.bitmap.width == size && drawable.bitmap.height == size) {
return drawable.bitmap
}
val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, size, size)
drawable.draw(canvas)
return bitmap
}
fun hideSystemUI(window: Window) =
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
controller.hide(WindowInsetsCompat.Type.systemBars())
controller.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
fun showSystemUI(window: Window) =
WindowInsetsControllerCompat(
window,
window.decorView
).show(WindowInsetsCompat.Type.systemBars())
WindowInsetsControllerCompat(window, window.decorView).show(WindowInsetsCompat.Type.systemBars())

View File

@@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:width="22dp"
android:height="22dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path

View File

@@ -0,0 +1,238 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">هل لديك مشكلة؟</string>
<string name="issue_report_body">هل واجهت خطأ أو لديك تعليقات؟</string>
<string name="issue_report_body_2">أبلغ عن ذلك في أقرب وقت ممكن!</string>
<string name="issue_report_github">ابلغ عنه في github</string>
<string name="issue_report_telegram">التواصل عبر تليجرام</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">تأكيد</string>
<string name="app_name">KernelSU Next</string>
<string name="home">الصفحة الرئيسية</string>
<string name="home_not_installed">غير مثبت</string>
<string name="home_click_to_install">إضغط للتثبيت</string>
<string name="lkm_mode_deprecated">وضع LKM قد تم إهماله!</string>
<string name="lkm_alternative_suggestion">قم بتثبيت نواة GKI أو دمج KernelSU Next في جهازك.</string>
<string name="home_working">جارِ العمل</string>
<string name="home_working_version">الإصدار: %d</string>
<string name="home_module_update_count">تحديثات: %d</string>
<string name="home_failure">لم يتم العثور على توقيع KernelSU Next v2 في النواة ! [ !KSU_NEXT &lt;unk&gt; != الحجم/الهاش ]</string>
<string name="home_failure_tip">اطلب من مطور kernel الخاص بك دمج KernelSU Next!</string>
<string name="home_kernel">اصدار النواة</string>
<string name="hook_mode">وضع الخطاف </string>
<string name="enable">تمكين</string>
<string name="disable">تعطيل</string>
<string name="enabled">مفعّل</string>
<string name="disabled">معطَّل</string>
<string name="susfs_supported">مدعوم</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">إصدار SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">إصدار الـ Android</string>
<string name="home_manager_version">إصدار المدير</string>
<string name="home_abi">ABI</string>
<string name="home_selinux_status">‏حالة SELinux</string>
<string name="selinux_status_disabled">معطَّل</string>
<string name="selinux_status_enforcing">مفروض</string>
<string name="selinux_status_permissive">مسموح</string>
<string name="selinux_status_unknown">غير معروف</string>
<string name="superuser">مستخدم خارق</string>
<string name="module_failed_to_enable">فشل في تمكين الإضافة: %s</string>
<string name="module_failed_to_disable">فشل في تمكين الإضافة: %s</string>
<string name="module_empty">لا توجد وحدة مثبتة</string>
<string name="module">وحدة</string>
<string name="module_install_prompt_with_name">سيتم تثبيت الوحدات التالية: %1$s</string>
<string name="module_sort_a_to_z">الترتيب (A → Z)</string>
<string name="module_sort_z_to_a">الترتيب (A → Z)</string>
<string name="module_size_low_to_high">الترتيب (منخفض → عالي)</string>
<string name="module_size_high_to_low">الترتيب (عالي → منخفض)</string>
<string name="uninstall">إلغاء التثبيت</string>
<string name="restore">استعادة</string>
<string name="module_install">تثبيت</string>
<string name="install">تثبيت</string>
<string name="reboot">إعادة التشغيل</string>
<string name="uninstalled">غير مثبت</string>
<string name="settings">الإعدادت</string>
<string name="reboot_userspace">إعادة تشغيل سريع</string>
<string name="reboot_recovery">الاقلاع في وضع الاسترداد</string>
<string name="reboot_bootloader">الاقلاع في وضع البوتلودر</string>
<string name="reboot_download">الاقلاع في وضع التحميل</string>
<string name="reboot_edl">الاقلاع في وضع EDL</string>
<string name="about">عن التطبيق</string>
<string name="module_uninstall_confirm">هل انت متأكد بأنك تريد إلغاء تثبيت الوحدة %s؟</string>
<string name="module_uninstall_success">تم إلغاء تثبيت %s</string>
<string name="module_uninstall_failed">فشل إلغاء تثبيت: %s</string>
<string name="module_restore_confirm">هل انت متأكد من أنك تريد استعادة وحدة %s ؟</string>
<string name="module_restore_success">تم إستعادة %s</string>
<string name="module_restore_failed">فشل في إستعادة: %s</string>
<string name="module_version">الإصدار</string>
<string name="module_author">المطور</string>
<string name="module_id">معرف الوحدة</string>
<string name="module_version_code">رقم الإصدار</string>
<string name="module_update_json">UpdateJson</string>
<string name="module_update_json_empty">فارغ</string>
<string name="enable_developer_options">تفعيل خيارات المطور</string>
<string name="enable_developer_options_summary">إظهار الإعدادات المخفية و معلومات التصحيح الخاصة بالمطورين فقط.</string>
<string name="module_overlay_fs_not_available">الوحدات غير متوفرة لان ال OverlayFS معطل بواسطة ال Kernel!</string>
<string name="refresh">تحديث</string>
<string name="show_system_apps">إظهار تطبيقات النظام</string>
<string name="hide_system_apps">إخفاء تطبيقات النظام</string>
<string name="export_log">تصدير السجلات</string>
<string name="safe_mode">الوضع الآمن</string>
<string name="reboot_to_apply">أعد التشغيل لتطبيق التغييرات</string>
<string name="module_magisk_conflict">الوحدات غير متاحة بسبب تعارضها مع Magisk!</string>
<string name="home_mount_system">تركيب النظام</string>
<string name="home_magic_mount">تركيب النظام</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">غير متاح</string>
<string name="use_overlay_fs">استخدام OverlayFS</string>
<string name="use_overlay_fs_summary">التبديل بين استخدام OverlayFS و Magic Mount لتركيب نظام KernelSU Next.</string>
<string name="reboot_required">مطلوب إعادة التشغيل</string>
<string name="reboot_message">ستصبح التغييرات سارية المفعول بعد إعادة تشغيل النظام. هل تريد إعادة التشغيل الآن؟</string>
<string name="module_restore">استعادة الوحدة</string>
<string name="module_restore_message">استعادة الوحدات من النسخة الاحتياطية الأخيرة.</string>
<string name="backup_restore">النسخ الاحتياطي والاستعادة</string>
<string name="module_backup">نسخ احتياطي للوحدات</string>
<string name="allowlist_restore">استعادة القائمة البيضاء</string>
<string name="allowlist_restore_message">استعادة الوحدات النمطية من النسخة الاحتياطية الأخيرة.</string>
<string name="allowlist_backup">نسخ احتياطي للقائمة البيضاء</string>
<string name="allowlist_backup_message">النسخ الاحتياطي للقائمة البيضاء المُعدة حاليا.</string>
<string name="warning">تحذير</string>
<string name="warning_message">هذه الميزة لا تزال في المرحلة التجريبية و قيد التطوير. الرجاء التأكد من النسخ الاحتياطي لوحداتك قبل المتابعة. استخدم هذه الميزة فقط إذا كنت تفهم المخاطر المحتملة. المتابعة بحذر.</string>
<string name="proceed">متابعة</string>
<string name="cancel">إلغاء</string>
<string name="later">لاحقاً</string>
<string name="lkm_warning_message">تصحيح LKM يعتمد على مكونات مغلقة المصدر. هل تريد الاستمرار؟</string>
<string name="home_next_kernelsu">🔥 الاصدار التالي</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">الفرع التجريبي التالي. تحقق من ذلك على GitHub!</string>
<string name="home_experimental_kernelsu">⚠️ تحذير التطوير التجريبي!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next هي نسخة غير رسمية تخضع دائماً للتطوير التجريبي النشط. وهي تقدم كما هي، بدون ضمانات للاستقرار، أو الأداء، أو الموثوقية.</string>
<string name="home_experimental_kernelsu_body_point_1"> • استخدمه على مسؤوليتك الخاصة: قد تحدث أعطال، أو سلوك غير متوقع، أو مشاكل في النظام.</string>
<string name="home_experimental_kernelsu_body_point_2"> • لا ضمان: المطورون غير مسؤولين عن أي خسارة في البيانات أو تلف للنظام، أو أي عواقب أخرى ناجمة عن استخدامها.</string>
<string name="home_experimental_kernelsu_body_point_3"> • لأغراض الاختبار فقط: موجهة للمستعملين الذين يفهمون المخاطر ويواجهون مشاكل مريحة في استكشاف الأخطاء وإصلاحها.</string>
<string name="about_source_code">عرض الكود المصدر في %1$s</string>
<string name="profile">ملف تعريف التطبيق</string>
<string name="profile_default">الافتراضي</string>
<string name="profile_template">قالب</string>
<string name="profile_custom">مخصص</string>
<string name="profile_name">اسم ملف التعريف</string>
<string name="profile_namespace">تحميل ال namespace</string>
<string name="profile_namespace_inherited">متوارث</string>
<string name="profile_namespace_global">عام</string>
<string name="profile_namespace_individual">فردي</string>
<string name="profile_groups">مجموعات</string>
<string name="profile_capabilities">المُؤَهّلات</string>
<string name="profile_selinux_context">سياق SELinux</string>
<string name="profile_umount_modules">الغاء تحميل الوحدات</string>
<string name="failed_to_update_app_profile">فشل تحديث ملف تعريف التطبيق لـ %s</string>
<string name="require_kernel_version">الإصدار KernelSU Next الحالي %1$d منخفض جدا لكي يعمل المدير بشكل صحيح. الرجاء الترقية إلى الإصدار %2$d أو أعلى!</string>
<string name="settings_umount_modules_default">الغاء تحميل الإضافات</string>
<string name="settings_umount_modules_default_summary">القيمة الافتراضية العامة لـ\"إلغاء تحميل الإضافات\" في ملفات تعريف التطبيقات. إذا تم تمكينه، إزالة جميع تعديلات الإضافات على النظام للتطبيقات التي لا تحتوي على مجموعة ملف تعريف.</string>
<string name="settings_susfs_toggle">أخفاء خطاف kprobes</string>
<string name="settings_susfs_toggle_summary">يعطل هذا الخيار خطاف kprobes الذي أنشأه المدير وبدلا من ذلك، يقوم بتفعيل الخطاف المدمج، تنفيذ نفس الوظيفة التي سيتم تطبيقها على كيرنيل غير GKI ، الذي لا يدعم kprobes.</string>
<string name="profile_umount_modules_summary">تمكين هذا الخيار سيسمح KernelSU Next لاستعادة أي ملفات معدلة بواسطة وحدات هذا التطبيق.</string>
<string name="profile_selinux_domain">النطاق</string>
<string name="profile_selinux_rules">القواعد</string>
<string name="module_update">تحديث</string>
<string name="module_update_available">تحديث</string>
<string name="module_updated">محدث</string>
<string name="module_downloading">جاري تنزيل الوحدة: %s</string>
<string name="module_start_downloading">بدء التنزيل: %s</string>
<string name="new_version_available">الإصدار الجديد: %s متاح ، انقر للتحديث.</string>
<string name="launch_app">تشغيل</string>
<string name="close">إغلاق</string>
<string name="force_stop_app">ايقاف اجباري</string>
<string name="restart_app">إعادة تشغيل</string>
<string name="settings_amoled_mode">وضع AMOLED</string>
<string name="settings_amoled_mode_summary">تمكين سمة سوداء نقية مفيدة لشاشات AMOLED لتقليل إجهاد العين وحفظ البطارية.</string>
<string name="restart_required">مطلوب إعادة التشغيل</string>
<string name="restart_app_message">يحتاج التطبيق إلى إعادة تشغيل حتى يصبح هذا التغيير ساري المفعول.</string>
<string name="failed_to_update_sepolicy">فشل تحديث قواعد SELinux لـ %s</string>
<string name="su_not_allowed">تعذر منح المستخدم الخارق الوصول إلى %s</string>
<string name="module_changelog">سِجل التغييرات</string>
<string name="settings_profile_template">قالب الملف الشخصي للتطبيق</string>
<string name="settings_profile_template_summary">إدارة قالب محلي وعلى الإنترنت لملف التعريف</string>
<string name="app_profile_template_create">إنشاء قالب</string>
<string name="app_profile_template_edit">تحرير القالب</string>
<string name="app_profile_template_id">الرقم التعريفي</string>
<string name="app_profile_template_id_invalid">معرف القالب غير صالح</string>
<string name="app_profile_template_name">الاسم</string>
<string name="app_profile_template_description">الوصف</string>
<string name="app_profile_template_save">حفظ</string>
<string name="app_profile_template_delete">حذف</string>
<string name="app_profile_template_view">عرض القالب</string>
<string name="app_profile_template_readonly">للقراءة فقط</string>
<string name="app_profile_template_id_exist">معرف القالب موجود بالفعل!</string>
<string name="app_profile_import_export">إستيراد/تصدير</string>
<string name="app_profile_import_from_clipboard">استيراد من الحافظة</string>
<string name="app_profile_export_to_clipboard">تصدير إلى الحافظة</string>
<string name="app_profile_template_export_empty">لا يمكن العثور على القالب المحلي للتصدير!</string>
<string name="app_profile_template_import_success">تم الاستيراد بنجاح</string>
<string name="app_profile_template_sync">مزامنة القوالب عبر الإنترنت</string>
<string name="app_profile_template_save_failed">فشل في حفظ القالب</string>
<string name="app_profile_template_import_empty">الحافظة فارغة!</string>
<string name="module_changelog_failed">فشل في جلب سجل التغيير: %s</string>
<string name="settings_check_update">التحقق من وجود تحديثات</string>
<string name="settings_check_update_summary">التحقق تلقائيًا من وجود تحديثات عند فتح التطبيق</string>
<string name="grant_root_failed">فشل في منح صلاحية الجذر!</string>
<string name="action">إجراء</string>
<string name="webui">WebUI</string>
<string name="open">فتح</string>
<string name="enable_web_debugging">تمكين تصحيح أخطاء WebView</string>
<string name="enable_web_debugging_summary">يمكن استخدامه لتصحيح أخطاء WebUI، يرجى تمكينه فقط عند الحاجة.</string>
<string name="direct_install">تثبيت مباشر (مستحسن)</string>
<string name="select_file">اختر ملفا</string>
<string name="install_inactive_slot">تثبيت إلى خانة غير نشطة (بعد OTA)</string>
<string name="install_inactive_slot_warning">سيتم **إجبار** جهازك على الاقلاع إلى الفتحة غير النشطة الحالية بعد إعادة التشغيل!
\nاستخدم هذا الخيار فقط بعد انتهاء التحديث.
\nأستمرار؟</string>
<string name="install_next">التالي</string>
<string name="select_file_tip">يوصي بصورة القسم %1$s</string>
<string name="select_kmi">تحديد KMI</string>
<string name="shrink_sparse_image">تقليص ال sparse image</string>
<string name="shrink_sparse_image_message">غيّر حجم ال sparse image التي توجد بها الوحدة إلى حجمها الحقيقي. يُرجى ملاحظة أن هذا قد يُسبب خللاً في عمل الوحدة، لذا يُرجى استخدامها فقط عند الضرورة (مثل النسخ الاحتياطي).</string>
<string name="settings_uninstall">إلغاء التثبيت</string>
<string name="settings_uninstall_temporary">إلغاء تثبيت مؤقت</string>
<string name="settings_uninstall_permanent">إلغاء التثبيت نهائياً</string>
<string name="settings_restore_stock_image">استعادة الصورة الأصلية</string>
<string name="settings_uninstall_temporary_message">الغاء تثبيت KernelSU Next مؤقتا، استعادة الحالة الاصلية بعد اعادة التشغيل.</string>
<string name="settings_uninstall_permanent_message">إلغاء تثبيت KernelSU Next (الرووت و جميع الوحدات) بشكلٍ كامل و نهائياً.</string>
<string name="settings_restore_stock_image_message">استعادة صورة المصنع الاصلية (لو النسخة الاحتياطية موجودة)، تستخدم عادةً قبل OTA; ان كنت تريد الغاء تثبيت KernelSU Next، الرجاء استخدام \"الغاء التثبيت نهائياً\".</string>
<string name="flashing">جاري الحرق.</string>
<string name="flash_success">تم الحرق بنجاح</string>
<string name="flash_failed">فشل التركيب</string>
<string name="selected_lkm">تحديد LKM: %s</string>
<string name="save_log">حفظ السجلات</string>
<string name="log_saved">تم حفظ السجلات</string>
<string name="send_log">مشاركة السجلات</string>
<string name="settings_disable_su">تعطيل وضع التكامل مع المستخدم الخارق</string>
<string name="settings_disable_su_summary">تعطيل قدرة اي تطبيق على الحصول على إذن الرووت عن طريق الامر su (عمليات الرووت الحالية لن تتاثر).</string>
<string name="settings_language">اللغة</string>
<string name="system_default">افتراضيات النظام</string>
<string name="settings_legacyui">استخدام واجهة المستخدم القديمة</string>
<string name="settings_legacyui_summary">التبديل الى شكل واجهة المستخدم السابقة.</string>
<string name="settings_banner">تمكين اللافتات</string>
<string name="settings_banner_summary">اظهار خلفيات اللافتات للوحدات.</string>
<string name="use_webuix">إستخدام WebUI X</string>
<string name="use_webuix_summary">إستخدام WebUI X بدلاً من WebUI، التي تدعم المزيد من ال APIs.</string>
<string name="use_webuix_eruda">حقن Eruda في WebUI X</string>
<string name="use_webuix_eruda_summary">حقن وحدة التصحيح في WebUI X لجعل تصحيح الأخطاء أسهل. يتطلب تصحيح أخطاء الويب ن يكون مفعل.</string>
<string name="customization">تخصيص</string>
<string name="developer">المطور</string>
<string name="sucompat_disabled">تعطيل العرض</string>
<string name="zygisk_required">Zygisk مطلوب</string>
<string name="zygisk_status">حقن Zygisk</string>
<string name="home_superuser_count_singular">مستخدمون خارقون</string>
<string name="home_superuser_count_plural">مستخدم خارق</string>
<string name="home_module_count_singular">وحدة</string>
<string name="home_module_count_plural">وحدات</string>
<string name="module_backup_message">نسخ احتياطي للوحدات المثبتة حالياً.</string>
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
<string name="module_sort_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI first)</string>
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
</resources>

View File

@@ -1,197 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">تواجه مشكلة؟</string>
<string name="issue_report_body">حصل خطأ ما او لديك تعليقات؟</string>
<string name="issue_report_body_2">بلغنا بها على الفور!</string>
<string name="issue_report_github">ابلغنا عن طريق Github</string>
<string name="issue_report_telegram">تواصل من خلال التليجرام</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">تأكيد</string>
<string name="app_name" translatable="false">KernelSU Next</string>
<string name="home">الصفحة الرئيسية</string>
<string name="home_not_installed">غير مثبت</string>
<string name="home_click_to_install">انقر للتثبيت</string>
<string name="home_working">يعمل</string>
<string name="home_working_version">الإصدار: %d</string>
<string name="home_superuser_count">عدد التطبيقات ذات صلاحيات الروت: %d</string>
<string name="home_module_count">عدد الإضافات: %d</string>
<string name="home_failure">توقيع KSU Next v2 غير موجود [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">اطلب من مطور بتهيئة KSU Next لجهازك</string>
<string name="home_kernel">اصدار Kernel</string>
<string name="enabled">مفعل</string>
<string name="disabled">معطل</string>
<string name="susfs_supported">مدعوم</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">اصدار SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">إصدار الأندرويد</string>
<string name="home_manager_version">اصدار مدير الروت</string>
<string name="home_selinux_status">حالة SELinux</string>
<string name="selinux_status_disabled">معطل</string>
<string name="selinux_status_enforcing">مفعل</string>
<string name="selinux_status_permissive">مرن</string>
<string name="selinux_status_unknown">غير معروف</string>
<string name="superuser">المستخدم خارق</string>
<string name="module_failed_to_enable">فشل في تشغيل إضافة: %s</string>
<string name="module_failed_to_disable">فشل في إيقاف إضافة: %s</string>
<string name="module_empty">لا توجد إضافات مثبته</string>
<string name="module">الإضافات</string>
<string name="module_install_prompt_with_name">الإضافة/ات التالية سيتم تثبيتها: %1$s</string>
<string name="module_sort_a_to_z">تصنيف (أ-ي)</string>
<string name="module_sort_z_to_a">تصنيف (ي-أ)</string>
<string name="uninstall">إلغاء التثبيت</string>
<string name="restore">إستعادة</string>
<string name="module_install">تثبيت</string>
<string name="install">تثبيت</string>
<string name="reboot">إعادة تشغيل</string>
<string name="settings">الإعدادات</string>
<string name="reboot_userspace">إعادة تشغيل سريعة</string>
<string name="reboot_recovery">إعادة التشغيل إلى وضع الريكفري</string>
<string name="reboot_bootloader">إعادة التشغيل إلى وضع bootloader</string>
<string name="reboot_download">إعادة التشغيل إلى وضع التنزيل</string>
<string name="reboot_edl">إعادة التشغيل إلى وضع EDL</string>
<string name="about">حول</string>
<string name="module_uninstall_confirm">هل انت متأكد من حذف تلك الإضافة %s؟</string>
<string name="module_uninstall_success">%s تم إلغاء تثبيت</string>
<string name="module_uninstall_failed">فشل في إلغاء تثبيت: %s</string>
<string name="module_restore_confirm">هل انت متأكد من استرجاع الإضافة؟ %s؟</string>
<string name="module_restore_success">%s تم استعادة</string>
<string name="module_restore_failed">فشل استعادة: %s</string>
<string name="module_version">الإصدار</string>
<string name="module_author">المطور</string>
<string name="module_id">ID</string>
<string name="module_version_code">كود الإصدار</string>
<string name="module_update_json">UpdateJson</string>
<string name="module_update_json_empty">فارغ</string>
<string name="enable_developer_options">تفعيل خيارات المطور</string>
<string name="enable_developer_options_summary">عرض الإعدادات المخفية ومعلومات التصحيح ذات الصلة فقط للمطورين.</string>
<string name="module_overlay_fs_not_available">الإضافات غير متاحة حيث أن OverlayFS معطلة بواسطة النواة.</string>
<string name="refresh">تحديث</string>
<string name="show_system_apps">عرض تطبيقات النظام</string>
<string name="hide_system_apps">إخفاء تطبيقات النظام</string>
<string name="export_log">تصدير السجلات</string>
<string name="safe_mode">وضع الأمان</string>
<string name="reboot_to_apply">إعادة التشغيل لتطبيق التغييرات</string>
<string name="module_magisk_conflict">الإضافات غير متاحة بسبب تعارض مع Magisk!</string>
<string name="home_mount_system">نظام الإضافات</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">غير متاح</string>
<string name="use_overlay_fs">استخدام OverlayFS</string>
<string name="use_overlay_fs_summary">التبديل بين استخدام OverlayFS أو Magic Mount لنظام Mount الخاص بـKernelSU Next.</string>
<string name="reboot_required">إعادة التشغيل مطلوبة</string>
<string name="reboot_message">ستدخل التغييرات حيز التنفيذ بعد إعادة تشغيل النظام. هل تريد إعادة التشغيل الآن؟</string>
<string name="module_restore">استعادة الإضافة</string>
<string name="module_restore_message">استعادة الإضافات من النسخة الاحتياطية الأخيرة.</string>
<string name="backup_restore">نسخ احتياطي واستعادة</string>
<string name="module_backup">نسخ احتياطي للإضافة</string>
<string name="module_backup_message">نسخ احتياطي للإضافات المثبتة حاليًا.</string>
<string name="allowlist_restore">استعادة القائمة المسموح بها</string>
<string name="allowlist_restore_message">استعادة القائمة المسموح بها من النسخة الاحتياطية الأخيرة.</string>
<string name="allowlist_backup">نسخ احتياطي للقائمة المسموح بها</string>
<string name="allowlist_backup_message">نسخ احتياطي للقائمة المسموح بها المكونة حاليًا.</string>
<string name="warning">تحذير</string>
<string name="warning_message">هذه الميزة لا تزال في مرحلة البيتا وتحت التطوير. يرجى التأكد من عمل نسخة احتياطية من الإضافات الخاصة بك قبل المتابعة. استخدم هذه الميزة فقط إذا كنت تفهم المخاطر المحتملة. أكمل بحذر.</string>
<string name="proceed">تابع</string>
<string name="cancel">إلغاء</string>
<string name="later">لاحقًا</string>
<string name="home_next_kernelsu">🔥 الإصدار التالي</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">فرع تجريبي قادم. تحقق منه على GitHub!</string>
<string name="home_experimental_kernelsu">⚠️ تجريبي!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next هو إصدار غير رسمي دائمًا تحت التطوير التجريبي النشط. يتم تقديمه كما هو، دون ضمانات للاستقرار أو الأداء أو الموثوقية.</string>
<string name="home_experimental_kernelsu_body_point_1"> • استخدم على مسؤوليتك: قد تحدث أعطال أو سلوك غير متوقع أو مشاكل في النظام.</string>
<string name="home_experimental_kernelsu_body_point_2"> • لا ضمان: المطورون غير مسؤولين عن أي فقدان للبيانات أو تلف النظام أو عواقب أخرى ناتجة عن استخدامه.</string>
<string name="home_experimental_kernelsu_body_point_3"> • لأغراض الاختبار فقط: مخصص للمستخدمين الذين يفهمون المخاطر ويشعرون بالراحة في حل المشكلات.</string>
<string name="about_source_code"><![CDATA[عرض رمز المصدر في %1$s]]></string>
<string name="profile" translatable="false">ملف التطبيق</string>
<string name="profile_default">افتراضي</string>
<string name="profile_template">قالب</string>
<string name="profile_custom">مخصص</string>
<string name="profile_name">اسم الملف الشخصي</string>
<string name="profile_namespace">مساحة التثبيت</string>
<string name="profile_namespace_inherited">موروث</string>
<string name="profile_namespace_global">عالمي</string>
<string name="profile_namespace_individual">فردي</string>
<string name="profile_groups">المجموعات</string>
<string name="profile_capabilities">القدرات</string>
<string name="profile_selinux_context">سياق SELinux</string>
<string name="profile_umount_modules">إلغاء تثبيت الإضافات</string>
<string name="failed_to_update_app_profile">فشل في تحديث ملف التطبيق لـ %s</string>
<string name="require_kernel_version">إصدار KernelSU Next الحالي %1$d منخفض جدًا لكي يعمل المدير بشكل صحيح. يرجى الترقية إلى الإصدار %2$d أو أعلى!</string>
<string name="settings_umount_modules_default">إلغاء تثبيت الإضافات</string>
<string name="settings_umount_modules_default_summary">القيمة الافتراضية العالمية لـ "إلغاء تثبيت الإضافات" في ملف التطبيق. إذا تم تفعيلها، ستقوم بإزالة جميع التعديلات التي أجرتها الإضافات على النظام للتطبيقات التي لا تحتوي على ملف شخصي محدد.</string>
<string name="settings_susfs_toggle">إخفاء خطافات kprobe</string>
<string name="settings_susfs_toggle_summary">تعطيل خطافات kprobe التي أنشأها ksu، وبدلاً من ذلك، تفعيل الخطافات غير الكروب المدمجة، مما ينفذ نفس الوظائف التي ستطبق على نواة غير GKI، والتي لا تدعم kprobe.</string>
<string name="profile_umount_modules_summary">تفعيل هذا الخيار سيسمح لـ KernelSU Next باستعادة أي ملفات معدلة بواسطة الإضافات لهذا التطبيق.</string>
<string name="profile_selinux_domain">النطاق</string>
<string name="profile_selinux_rules">القواعد</string>
<string name="module_update">تحديث</string>
<string name="module_downloading">جارٍ تنزيل الإضافة: %s</string>
<string name="module_start_downloading">بدء التنزيل: %s</string>
<string name="new_version_available">إصدار جديد %s متاح، انقر للتحديث.</string>
<string name="launch_app">تشغيل</string>
<string name="close">إغلاق</string>
<string name="force_stop_app">إيقاف إجباري</string>
<string name="restart_app">إعادة تشغيل</string>
<string name="failed_to_update_sepolicy">فشل في تحديث قواعد SELinux لـ: %s</string>
<string name="su_not_allowed">لا يُسمح بمنح صلاحيات المستخدم الخارق لـ: %s</string>
<string name="module_changelog">سجل التغييرات</string>
<string name="settings_profile_template">قالب ملف التطبيق</string>
<string name="settings_profile_template_summary">إدارة القالب المحلي وعبر الإنترنت لملف التطبيق</string>
<string name="app_profile_template_create">إنشاء قالب</string>
<string name="app_profile_template_edit">تحرير القالب</string>
<string name="app_profile_template_id">ID</string>
<string name="app_profile_template_id_invalid">معرف القالب غير صالح</string>
<string name="app_profile_template_name">الاسم</string>
<string name="app_profile_template_description">الوصف</string>
<string name="app_profile_template_save">حفظ</string>
<string name="app_profile_template_delete">حذف</string>
<string name="app_profile_template_view">عرض القالب</string>
<string name="app_profile_template_readonly">للقراءة فقط</string>
<string name="app_profile_template_id_exist">معرف القالب موجود بالفعل!</string>
<string name="app_profile_import_export">استيراد/تصدير</string>
<string name="app_profile_import_from_clipboard">استيراد من الحافظة</string>
<string name="app_profile_export_to_clipboard">تصدير إلى الحافظة</string>
<string name="app_profile_template_export_empty">لا يمكن العثور على قالب محلي للتصدير!</string>
<string name="app_profile_template_import_success">تم الاستيراد بنجاح</string>
<string name="app_profile_template_sync">مزامنة القوالب عبر الإنترنت</string>
<string name="app_profile_template_save_failed">فشل في حفظ القالب</string>
<string name="app_profile_template_import_empty">الحافظة فارغة!</string>
<string name="module_changelog_failed">فشل في جلب سجل التغييرات: %s</string>
<string name="settings_check_update">التحقق من التحديث</string>
<string name="settings_check_update_summary">التحقق تلقائيًا من التحديثات عند فتح التطبيق.</string>
<string name="grant_root_failed">فشل في منح صلاحيات الجذر!</string>
<string name="action">إجراء</string>
<string name="open">فتح</string>
<string name="enable_web_debugging">تفعيل تصحيح WebView</string>
<string name="enable_web_debugging_summary">يمكن استخدامه لتصحيح WebUI. يرجى التفعيل فقط عند الحاجة.</string>
<string name="direct_install">التثبيت المباشر (موصى به)</string>
<string name="select_file">اختر ملفًا</string>
<string name="install_inactive_slot">التثبيت في الفتحة غير النشطة (بعد OTA)</string>
<string name="install_inactive_slot_warning">سيتم إجبار جهازك على الإقلاع إلى الفتحة غير النشطة الحالية بعد إعادة التشغيل!\nاستخدم هذا الخيار فقط بعد الانتهاء من OTA.\nهل تريد المتابعة؟</string>
<string name="install_next">التالي</string>
<string name="select_file_tip">%1$s Partition موصى به</string>
<string name="select_kmi">اختر KMI</string>
<string name="shrink_sparse_image">تقليل حجم partition المتناثرة</string>
<string name="shrink_sparse_image_message">إعادة حجم partition حيث توجد الإضافة إلى حجمها الفعلي. لاحظ أن هذا قد يتسبب في عمل الإضافة بشكل غير طبيعي، لذا يرجى استخدامه فقط عند الضرورة (مثل النسخ الاحتياطي).</string>
<string name="settings_uninstall">إلغاء التثبيت</string>
<string name="settings_uninstall_temporary">إلغاء التثبيت مؤقتًا</string>
<string name="settings_uninstall_permanent">إلغاء التثبيت نهائيًا</string>
<string name="settings_restore_stock_image">استعادة الصورة الأصلية</string>
<string name="settings_uninstall_temporary_message">إلغاء تثبيت KernelSU Next مؤقتًا، استعادة الحالة الأصلية بعد إعادة التشغيل التالية.</string>
<string name="settings_uninstall_permanent_message">إلغاء تثبيت KernelSU Next (الجذر وجميع الإضافات) بالكامل ودائمًا.</string>
<string name="settings_restore_stock_image_message">استعادة الصورة الأصلية (إذا كانت النسخة الاحتياطية موجودة)، عادة ما تستخدم قبل OTA؛ إذا كنت بحاجة إلى إلغاء تثبيت KernelSU Next، يرجى استخدام "إلغاء التثبيت نهائيًا".</string>
<string name="flashing">تثبيت</string>
<string name="flash_success">نجح التثبيت</string>
<string name="flash_failed">فشل التثبيت</string>
<string name="selected_lkm">LKM المحدد: %s</string>
<string name="save_log">حفظ السجلات</string>
<string name="log_saved">تم حفظ السجلات</string>
<string name="send_log">مشاركة السجلات</string>
<string name="settings_disable_su">تعطيل توافق su</string>
<string name="settings_disable_su_summary">تعطيل مؤقت لقدرة أي تطبيق على الحصول على صلاحيات الجذر عبر أمر su (لن تتأثر العمليات الجذرية الحالية).</string>
<string name="settings_language">اللغة</string>
</resources>

View File

@@ -0,0 +1,236 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">Имате проблеми?</string>
<string name="issue_report_body">Открихте грешка или имате отзив?</string>
<string name="issue_report_body_2">Докладвайте го възможно най-скоро!</string>
<string name="issue_report_github">Докладвайте в GitHub</string>
<string name="issue_report_telegram">Свържете се чрез Telegram</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Потвърди</string>
<string name="app_name">KernelSU Next</string>
<string name="home">Начало</string>
<string name="home_not_installed">Не е инсталирано</string>
<string name="home_click_to_install">Кликнете, за да инсталирате</string>
<string name="lkm_mode_deprecated">Режимът LKM вече е остарял!</string>
<string name="lkm_alternative_suggestion">Инсталирайте GKI ядро или интегрирайте KernelSU Next към вашето устройство.</string>
<string name="home_working">Работи</string>
<string name="home_working_version">Версия: %d</string>
<string name="home_module_update_count">Актуализации: %d</string>
<string name="home_failure">Подписът на KernelSU Next v2 не е намерен в ядрото! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">Помолете разработчика на вашето ядро да интегрира KernelSU Next!</string>
<string name="home_kernel">Версия на ядрото</string>
<string name="hook_mode">Режим на закачане</string>
<string name="enable">Активиране</string>
<string name="disable">Деактивиране</string>
<string name="enabled">Активиран</string>
<string name="disabled">Деактивиран</string>
<string name="susfs_supported">Поддържан</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">Версия на SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Версия на Андроид</string>
<string name="home_manager_version">Версия на мениджъра</string>
<string name="home_abi">ABI</string>
<string name="home_selinux_status">Състояние на SELinux</string>
<string name="selinux_status_disabled">Деактивиран</string>
<string name="selinux_status_enforcing">Прилагащ</string>
<string name="selinux_status_permissive">Разрешителен</string>
<string name="selinux_status_unknown">Непознат</string>
<string name="superuser">Суперпотребител</string>
<string name="module_failed_to_enable">Неуспешно активиране на модула: %s</string>
<string name="module_failed_to_disable">Неуспешно деактивиране на модула: %s</string>
<string name="module_empty">Няма инсталиран модул</string>
<string name="module">Модул</string>
<string name="module_install_prompt_with_name">Следните модули ще бъдат инсталирани: %1$s</string>
<string name="module_sort_a_to_z">Сортиране (A → Z)</string>
<string name="module_sort_z_to_a">Сортиране (Z → A)</string>
<string name="module_size_low_to_high">Сортиране (Ниско → Високо)</string>
<string name="module_size_high_to_low">Сортиране (Високо → Ниско)</string>
<string name="uninstall">Деинсталирай</string>
<string name="restore">Възстанови</string>
<string name="module_install">Инсталирай</string>
<string name="install">Инсталирай</string>
<string name="reboot">Рестартиране</string>
<string name="uninstalled">Деинсталиран</string>
<string name="settings">Настройки</string>
<string name="reboot_userspace">Софт рестарт</string>
<string name="reboot_recovery">Рестартиране до Recovery</string>
<string name="reboot_bootloader">Рестартиране до Bootloader</string>
<string name="reboot_download">Рестартиране до Download</string>
<string name="reboot_edl">Рестартиране до EDL</string>
<string name="about">Относно</string>
<string name="module_uninstall_confirm">Сигурни ли сте, че искате да деинсталирате модул %s?</string>
<string name="module_uninstall_success">%s деинсталиран</string>
<string name="module_uninstall_failed">Неуспешно деинсталиране: %s</string>
<string name="module_restore_confirm">Сигурни ли сте, че искате да възстановите модул %s?</string>
<string name="module_restore_success">%s възстановен</string>
<string name="module_restore_failed">Неуспешно възстановяване: %s</string>
<string name="module_version">Версия</string>
<string name="module_author">Автор</string>
<string name="module_id">Идентификатор</string>
<string name="module_version_code">Код</string>
<string name="module_update_json">Json за актуализации</string>
<string name="module_update_json_empty">Празен</string>
<string name="enable_developer_options">Активиране на опциите за разработчици</string>
<string name="enable_developer_options_summary">Показване на скрити настройки и информация за отстраняване на грешки, отнасящи се само за разработчици.</string>
<string name="module_overlay_fs_not_available">Модулите не са налични, тъй като OverlayFS е деактивиран от ядрото!</string>
<string name="refresh">Опресни</string>
<string name="show_system_apps">Покажи системни приложения</string>
<string name="hide_system_apps">Скрий системните приложения</string>
<string name="export_log">Експорт на логове</string>
<string name="safe_mode">Безопасен режим</string>
<string name="reboot_to_apply">Рестартирайте, за да влезе в сила</string>
<string name="module_magisk_conflict">Модулите не са налични поради конфликт с Magisk!</string>
<string name="home_mount_system">Модулна система</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Неналично</string>
<string name="use_overlay_fs">Използвай OverlayFS</string>
<string name="use_overlay_fs_summary">Превключване между използване на OverlayFS или Magic Mount за модулната система на KernelSU Next.</string>
<string name="reboot_required">Нужен е рестарт</string>
<string name="reboot_message">Промените ще влязат в сила след рестартирането на системата. Искате ли да рестартирате сега?</string>
<string name="module_restore">Възстановяване на модула</string>
<string name="module_restore_message">Възстановяване на модули от скорошно архивиране.</string>
<string name="backup_restore">Архивиране &amp; Възстановяване</string>
<string name="module_backup">Архивирай модул</string>
<string name="allowlist_restore">Възстановяване на списъка с разрешения</string>
<string name="allowlist_restore_message">Възстановяване на списъка с разрешения от скорошно архивиране.</string>
<string name="allowlist_backup">Архивиране на списъка с разрешения</string>
<string name="allowlist_backup_message">Архивиране на текущо конфигурирания списък с разрешения.</string>
<string name="warning">Предупреждение</string>
<string name="warning_message">Тази функция все още е в бета фаза и е в процес на разработка. Моля, уверете се, че сте направили резервно копие на модулите си, преди да продължите. Използвайте тази функция само ако разбирате потенциалните рискове. Действайте внимателно.</string>
<string name="proceed">Продължи</string>
<string name="cancel">Отказ</string>
<string name="later">По-късно</string>
<string name="lkm_warning_message">Пачът за LKM разчита на компоненти със затворен код. Искате ли да продължите?</string>
<string name="home_next_kernelsu">🔥Следваща версия</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Експериментален клон Next. Вижте го в GitHub!</string>
<string name="home_experimental_kernelsu">⚠️ Предупреждение за експериментална разработка!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next е неофициална версия, която е в процес на активна експериментална разработка. Предоставя се „както е“, без гаранции за стабилност, производителност или надеждност.</string>
<string name="home_experimental_kernelsu_body_point_1"> • Използвайте на свой собствен риск: могат да възникнат сривове, неочаквано поведение или системни проблеми.</string>
<string name="home_experimental_kernelsu_body_point_2"> • Без гаранция: разработчиците не носят отговорност за загуба на данни, системни повреди или други последици, произтичащи от използването му.</string>
<string name="home_experimental_kernelsu_body_point_3"> • Само за тестови цели: предназначено за потребители, които разбират рисковете и са умели да отстраняват проблеми.</string>
<string name="about_source_code">Вижте изходния код в %1$s</string>
<string name="profile">Профил на приложението</string>
<string name="profile_default">Стандартно</string>
<string name="profile_template">Шаблон</string>
<string name="profile_custom">По избор</string>
<string name="profile_name">Име на профила</string>
<string name="profile_namespace">Монтиране на namespace</string>
<string name="profile_namespace_inherited">Наследен</string>
<string name="profile_namespace_global">Глобален</string>
<string name="profile_namespace_individual">Индивидуален</string>
<string name="profile_groups">Групи</string>
<string name="profile_capabilities">Способности</string>
<string name="profile_selinux_context">SELinux контекст</string>
<string name="profile_umount_modules">Демонтиране на модули</string>
<string name="failed_to_update_app_profile">Актуализирането на профила на приложението за %s не бе успешно</string>
<string name="require_kernel_version">Текущата версия %1$d на KernelSU Next е твърде ниска, за да работи мениджърът правилно. Моля, актуализирайте до версия %2$d или по-висока!</string>
<string name="settings_umount_modules_default">Демонтиране на модули</string>
<string name="settings_umount_modules_default_summary">Глобалната стойност по подразбиране за „Демонтиране на модули“ в профила на приложението. Ако е активирана, ще премахне всички модификации на модулите в системата за приложения, които нямат зададен профил.</string>
<string name="settings_susfs_toggle">Скриване на закачването на kprobes</string>
<string name="settings_susfs_toggle_summary">Тази опция деактивира kprobes hook-а, създаден от ksu, и вместо това активира вградения non-kprobes hook, реализирайки същата функционалност, която би била приложена към ядро, различно от GKI, което не поддържа kprobe.</string>
<string name="profile_umount_modules_summary">Активирането на тази опция ще позволи на KernelSU Next да възстанови всички модифицирани файлове от модулите за това приложение.</string>
<string name="profile_selinux_domain">Домейн</string>
<string name="profile_selinux_rules">Правила</string>
<string name="module_update">Актуализиране</string>
<string name="module_update_available">Актуализация</string>
<string name="module_updated">Актуализиран</string>
<string name="module_downloading">Изтегляне на модул: %s</string>
<string name="module_start_downloading">Започнете изтеглянето: %s</string>
<string name="new_version_available">Налична е нова версия %s, кликнете за актуализация.</string>
<string name="launch_app">Стартиране</string>
<string name="close">Затвори</string>
<string name="force_stop_app">Принудително спиране</string>
<string name="restart_app">Рестартиране</string>
<string name="settings_amoled_mode">AMOLED режим</string>
<string name="settings_amoled_mode_summary">Активирайте чисто черна тема, полезна за AMOLED екрани, за да намалите напрежението в очите и да пестите батерия.</string>
<string name="restart_required">Нужен е рестарт</string>
<string name="restart_app_message">Приложението трябва да се рестартира, за да влезе в сила тази промяна.</string>
<string name="failed_to_update_sepolicy">Неуспешно актуализиране на правилата на SELinux за %s</string>
<string name="su_not_allowed">Не можа да се предостави достъп на суперпотребител на %s</string>
<string name="module_changelog">Списък на промените</string>
<string name="settings_profile_template">Шаблон за профил на приложение</string>
<string name="settings_profile_template_summary">Управление на локален и онлайн шаблон на профил на приложението</string>
<string name="app_profile_template_create">Създаване на шаблон</string>
<string name="app_profile_template_edit">Редактиране на Шаблон</string>
<string name="app_profile_template_id">Идентификатор</string>
<string name="app_profile_template_id_invalid">Некоректен идентификатор на шаблона</string>
<string name="app_profile_template_name">Име</string>
<string name="app_profile_template_description">Описание</string>
<string name="app_profile_template_save">Запази</string>
<string name="app_profile_template_delete">Изтрий</string>
<string name="app_profile_template_view">Преглед на шаблона</string>
<string name="app_profile_template_readonly">Само за четене</string>
<string name="app_profile_template_id_exist">Идентификаторът на шаблона вече съществува!</string>
<string name="app_profile_import_export">Импорт/Експорт</string>
<string name="app_profile_import_from_clipboard">Импортиране от клипборда</string>
<string name="app_profile_export_to_clipboard">Експортирай в клипборда</string>
<string name="app_profile_template_export_empty">Не може да се намери локален шаблон за експортиране!</string>
<string name="app_profile_template_import_success">Импортирано успешно</string>
<string name="app_profile_template_sync">Синхронизиране на онлайн шаблони</string>
<string name="app_profile_template_save_failed">Запазването на шаблона не бе успешно</string>
<string name="app_profile_template_import_empty">Клипбордът е празен!</string>
<string name="module_changelog_failed">Извличането на списъка с промени не бе успешно: %s</string>
<string name="settings_check_update">Проверка за актуализации</string>
<string name="settings_check_update_summary">Автоматична проверка за актуализации при отваряне на приложението</string>
<string name="grant_root_failed">Неуспешно предоставяне на root достъп!</string>
<string name="action">Действие</string>
<string name="webui">WebUI</string>
<string name="open">Отваряне</string>
<string name="enable_web_debugging">Активиране на WebView дебъгване</string>
<string name="enable_web_debugging_summary">Може да се използва за дебъгване на WebUI. Моля активирайте само когато е нужно.</string>
<string name="direct_install">Директно инсталиране (препоръчително)</string>
<string name="select_file">Избери файл</string>
<string name="install_inactive_slot">Инсталиране в неактивен слот (след OTA)</string>
<string name="install_inactive_slot_warning">Устройството ви ще бъде **ПРИНУДЕНО** да се стартира от текущия неактивен слот след рестартиране!\nИзползвайте тази опция само след като приключи OTA.\nИскате ли да продължите?</string>
<string name="install_next">Следващ</string>
<string name="select_file_tip">Препоръчва се образ на дял %1$s</string>
<string name="select_kmi">Изберете KMI</string>
<string name="shrink_sparse_image">Минимизиране на разреденото изображение</string>
<string name="shrink_sparse_image_message">Преоразмерете разреденото изображение, където се намира модулът, до действителния му размер. Обърнете внимание, че това може да доведе до неправилна работа на модула, така че, моля, използвайте го само когато е необходимо (например за архивиране).</string>
<string name="settings_uninstall">Деинсталирай</string>
<string name="settings_uninstall_temporary">Деинсталирай временно</string>
<string name="settings_uninstall_permanent">Деинсталирай завинаги</string>
<string name="settings_restore_stock_image">Възстановяване на базово изображение</string>
<string name="settings_uninstall_temporary_message">Временно деинсталирайте KernelSU Next, възстановете първоначалното състояние след следващото рестартиране.</string>
<string name="settings_uninstall_permanent_message">Пълно и окончателно деинсталиране на KernelSU Next (Root и всички модули).</string>
<string name="settings_restore_stock_image_message">Възстановете базовото копие (ако съществува резервно копие), обикновено използвано преди OTA; ако трябва да деинсталирате KernelSU Next, моля, използвайте „Деинсталирай завинаги“.</string>
<string name="flashing">Записване</string>
<string name="flash_success">Успешно записване</string>
<string name="flash_failed">Неуспешно записване</string>
<string name="selected_lkm">Избран LKM: %s</string>
<string name="save_log">Запазване на лог файлове</string>
<string name="log_saved">Лог файлове запазени</string>
<string name="send_log">Сподели лог файлове</string>
<string name="settings_disable_su">Деактивиране на съвместимостта със su</string>
<string name="settings_disable_su_summary">Временно деактивирайте възможността на всяко приложение да получава root права чрез командата su (съществуващите root процеси няма да бъдат засегнати).</string>
<string name="settings_language">Език</string>
<string name="system_default">По подразбиране</string>
<string name="settings_legacyui">Използване на стария потребителски интерфейс</string>
<string name="settings_legacyui_summary">Превключване към предишния стил на потребителския интерфейс.</string>
<string name="settings_banner">Активиране на банери</string>
<string name="settings_banner_summary">Показване на фонови банери за модули.</string>
<string name="use_webuix">Използване на WebUI X</string>
<string name="use_webuix_summary">Използване на WebUI X вместо WebUI, което поддържа повече API.</string>
<string name="use_webuix_eruda">Инжектиране на Eruda в WebUI X</string>
<string name="use_webuix_eruda_summary">Инжектиране на конзола за дебъгване в WebUI X за да се олесни дебъгването. Нужно е Уеб Дебъгване да е активирано.</string>
<string name="customization">Персонализация</string>
<string name="developer">Разработчик</string>
<string name="sucompat_disabled">SUCOMPAT Е ДЕАКТИВИРАН</string>
<string name="zygisk_required">Zygisk е задължителен</string>
<string name="zygisk_status">Инжекция на Zygisk</string>
<string name="home_superuser_count_singular">Суперпотребител</string>
<string name="home_superuser_count_plural">Суперпотребители</string>
<string name="home_module_count_singular">Модул</string>
<string name="home_module_count_plural">Модули</string>
<string name="module_backup_message">Архивиране на текущо инсталираните модули.</string>
<string name="module_sort_enabled_first">Сортиране (първо активирани)</string>
<string name="module_sort_action_first">Сортиране (първо действие)</string>
<string name="module_sort_webui_first">Сортиране (първо WebUI)</string>
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
</resources>

View File

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">Имате проблем?</string>
<string name="issue_report_body">Открихте грешка или имате обратна връзка?</string>
<string name="issue_report_body_2">Докладвайте я възможно най-скоро!</string>
<string name="issue_report_github">Докладвай в GitHub</string>
<string name="issue_report_telegram">Свържете се чрез Telegram</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Потвърди</string>
<string name="app_name" translatable="false">KernelSU Next</string>
<string name="home">Начало</string>
<string name="home_not_installed">Не е инсталирано</string>
<string name="home_click_to_install">Натиснете за инсталиране</string>
<string name="home_working">Работи</string>
<string name="home_working_version">Версия: %d</string>
<string name="home_superuser_count">Суперпотребители: %d</string>
<string name="home_module_count">Модули: %d</string>
<string name="home_failure">Не е намерен подпис KernelSU Next v2 в ядрото! [ !KSU_NEXT || != размер/хеш ]</string>
<string name="home_failure_tip">Помолете разработчика на вашето ядро да интегрира KernelSU Next!</string>
<string name="home_kernel">Версия на ядрото</string>
<string name="enabled">Активирано</string>
<string name="disabled">Деактивирано</string>
<string name="susfs_supported">Поддържано</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">Версия на SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Версия на Android</string>
<string name="home_manager_version">Версия на мениджъра</string>
<string name="home_selinux_status">Статус на SELinux</string>
<string name="selinux_status_disabled">Деактивиран</string>
<string name="selinux_status_enforcing">Строг режим</string>
<string name="selinux_status_permissive">Разрешителен режим</string>
<string name="selinux_status_unknown">Неизвестно</string>
<string name="superuser">Суперпотребител</string>
<string name="module_failed_to_enable">Неуспешно активиране на модул: %s</string>
<string name="module_failed_to_disable">Неуспешно деактивиране на модул: %s</string>
<string name="module_empty">Няма инсталирани модули</string>
<string name="module">Модул</string>
<string name="module_install_prompt_with_name">Следните модули ще бъдат инсталирани: %1$s</string>
<string name="module_sort_a_to_z">Сортиране (А-Я)</string>
<string name="module_sort_z_to_a">Сортиране (Я-А)</string>
<string name="uninstall">Деинсталиране</string>
<string name="restore">Възстановяване</string>
<string name="module_install">Инсталиране</string>
<string name="install">Инсталирай</string>
<string name="reboot">Рестартиране</string>
<string name="settings">Настройки</string>
<string name="reboot_userspace">Мек рестарт</string>
<string name="reboot_recovery">Рестарт в Recovery</string>
<string name="reboot_bootloader">Рестарт в Bootloader</string>
<string name="reboot_download">Рестарт в Download</string>
<string name="reboot_edl">Рестарт в EDL</string>
<string name="about">Относно</string>
<string name="module_uninstall_confirm">Сигурни ли сте, че искате да деинсталирате модула %s?</string>
<string name="module_uninstall_success">%s деинсталиран</string>
<string name="module_uninstall_failed">Неуспешно деинсталиране: %s</string>
<string name="module_restore_confirm">Сигурни ли сте, че искате да възстановите модула %s?</string>
<string name="module_restore_success">%s възстановен</string>
<string name="module_restore_failed">Неуспешно възстановяване: %s</string>
<string name="module_version">Версия</string>
<string name="module_author">Автор</string>
<string name="module_id">ID</string>
<string name="module_version_code">Код</string>
<string name="module_update_json">Актуализиране JSON</string>
<string name="module_update_json_empty">Празно</string>
<string name="enable_developer_options">Активиране на опции за разработчици</string>
<string name="enable_developer_options_summary">Показване на скрити настройки и дебъг информация, релевантни само за разработчици.</string>
<string name="module_overlay_fs_not_available">Модулите не са налични, тъй като OverlayFS е деактивиран от ядрото.</string>
<string name="refresh">Обновяване</string>
<string name="show_system_apps">Показване на системни приложения</string>
<string name="hide_system_apps">Скриване на системни приложения</string>
<string name="export_log">Експорт на логове</string>
<string name="safe_mode">Безопасен режим</string>
<string name="reboot_to_apply">Рестартирайте, за да влязат в сила</string>
<string name="module_magisk_conflict">Модулите не са налични поради конфликт с Magisk!</string>
<string name="home_mount_system">Модулна система</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Недостъпно</string>
<string name="use_overlay_fs">Използване на OverlayFS</string>
<string name="use_overlay_fs_summary">Превключване между използването на OverlayFS и Magic Mount за KernelSU Next.</string>
<string name="reboot_required">Необходим е рестарт</string>
<string name="reboot_message">Промените ще влязат в сила след рестарт. Искате ли да рестартирате сега?</string>
</resources>

View File

@@ -0,0 +1,236 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">সমস্যা হচ্ছে?</string>
<string name="issue_report_body">কোনো ত্রুটির সম্মুখীন অথবা প্রতিক্রিয়া পেয়েছেন?</string>
<string name="issue_report_body_2">ইহা দ্রুত রিপোর্ট করুন!</string>
<string name="issue_report_github">গিটহাবে রিপোর্ট করুন</string>
<string name="issue_report_telegram">টেলিগ্রামে যোগাযোগ করুন</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">নিশ্চিত করুন</string>
<string name="app_name">KernelSU Next</string>
<string name="home">হোম</string>
<string name="home_not_installed">ইন্সটল হয়নি</string>
<string name="home_click_to_install">ইন্সটলের জন্য ক্লিক করুন</string>
<string name="lkm_mode_deprecated">LKM মোড এখন অকার্যকর!</string>
<string name="lkm_alternative_suggestion">GKI কার্নেল ইন্সটল করুন অথবা KernelSU ইন্টিগ্রেড করুন।.</string>
<string name="home_working">কার্যরত</string>
<string name="home_working_version">Version: %d</string>
<string name="home_module_update_count">আপডেটস: %d</string>
<string name="home_failure">KernelSU Next v2 signature পাওয়া যায়নি কার্নেলে! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">আপনার কার্নেল ডেভেলপারকে বলুন KernelSU Next ইন্টিগ্রেট করতে!</string>
<string name="home_kernel">কার্নেল ভার্সন</string>
<string name="hook_mode">হুক মোড</string>
<string name="enable">সক্রিয়</string>
<string name="disable">নিষ্ক্রিয়</string>
<string name="enabled">সক্রিয় করা হয়েছে</string>
<string name="disabled">নিষ্ক্রিয় করা হয়েছে</string>
<string name="susfs_supported">সমর্থিত</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">SuSFS ভার্সন</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">এন্ড্রয়েড ভার্সন</string>
<string name="home_manager_version">ম্যানেজার ভার্সন</string>
<string name="home_abi">ABI</string>
<string name="home_selinux_status">SELinux এর অবস্থা</string>
<string name="selinux_status_disabled">অকার্যকর</string>
<string name="selinux_status_enforcing">বলবৎ করা</string>
<string name="selinux_status_permissive">অনুমতিমূলক</string>
<string name="selinux_status_unknown">অজানা</string>
<string name="superuser">সুপারইউজার</string>
<string name="module_failed_to_enable">মডিউল সক্রিয় করতে ব্যর্থ: %s</string>
<string name="module_failed_to_disable">মডিউল নিষ্ক্রিয় করতে ব্যর্থ: %s</string>
<string name="module_empty">কোনো মডিউল ইন্সটল করা নেই</string>
<string name="module">মডিউল</string>
<string name="module_install_prompt_with_name">নিম্নলিখিত মডিউলগুলি ইনস্টল করা হবে: %1$s</string>
<string name="module_sort_a_to_z">সাজান (A → Z)</string>
<string name="module_sort_z_to_a">সাজান (Z → A)</string>
<string name="module_size_low_to_high">সাজান (নিম্ন → উচ্চ)</string>
<string name="module_size_high_to_low">সাজান (উচ্চ → নিম্ন)</string>
<string name="uninstall">আনইন্সটল</string>
<string name="restore">পুনরুদ্ধার করা</string>
<string name="module_install">ইন্সটল</string>
<string name="install">ইন্সটল</string>
<string name="reboot">রিবুট</string>
<string name="uninstalled">আনইনস্টল করা হয়েছে</string>
<string name="settings">সেটিংস</string>
<string name="reboot_userspace">সফট রিবুট</string>
<string name="reboot_recovery">রিকভারি জন্য রিবুট করুন</string>
<string name="reboot_bootloader">Reboot to Bootloader</string>
<string name="reboot_download">Reboot to Download</string>
<string name="reboot_edl">Reboot to EDL</string>
<string name="about">About</string>
<string name="module_uninstall_confirm">Are you sure you want to uninstall module %s?</string>
<string name="module_uninstall_success">%s uninstalled</string>
<string name="module_uninstall_failed">Failed to uninstall: %s</string>
<string name="module_restore_confirm">Are you sure you want to restore module %s?</string>
<string name="module_restore_success">%s restored</string>
<string name="module_restore_failed">Failed to restore: %s</string>
<string name="module_version">Version</string>
<string name="module_author">Author</string>
<string name="module_id">ID</string>
<string name="module_version_code">কোড</string>
<string name="module_update_json">UpdateJson</string>
<string name="module_update_json_empty">খালি</string>
<string name="enable_developer_options">Enable developer options</string>
<string name="enable_developer_options_summary">Show hidden settings and debug info relevant only for developers.</string>
<string name="module_overlay_fs_not_available">Modules are unavailable as OverlayFS is disabled by the kernel!</string>
<string name="refresh">Refresh</string>
<string name="show_system_apps">Show system apps</string>
<string name="hide_system_apps">Hide system apps</string>
<string name="export_log">Export logs</string>
<string name="safe_mode">Safe mode</string>
<string name="reboot_to_apply">Reboot to take effect</string>
<string name="module_magisk_conflict">Modules are unavailable due to a conflict with Magisk!</string>
<string name="home_mount_system">Mount system</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Unavailable</string>
<string name="use_overlay_fs">Use OverlayFS</string>
<string name="use_overlay_fs_summary">Toggle between using OverlayFS over Magic Mount for KernelSU Next\'s mount system.</string>
<string name="reboot_required">Reboot required</string>
<string name="reboot_message">The changes will take effect after the system restart. Do you want to reboot now?</string>
<string name="module_restore">Restore module</string>
<string name="module_restore_message">Restore modules from recent backup.</string>
<string name="backup_restore">Backup &amp; Restore</string>
<string name="module_backup">Backup module</string>
<string name="allowlist_restore">Restore allowlist</string>
<string name="allowlist_restore_message">Restore allowlist from recent backup.</string>
<string name="allowlist_backup">Backup allowlist</string>
<string name="allowlist_backup_message">Backup currently configured allowlist.</string>
<string name="warning">Warning</string>
<string name="warning_message">এই বৈশিষ্ট্যটি এখনও বিটা পর্যায়ে রয়েছে এবং বিকাশের অধীনে রয়েছে। এগিয়ে যাওয়ার আগে দয়া করে আপনার মডিউলগুলির ব্যাকআপ নিন। সম্ভাব্য ঝুঁকিগুলি বুঝতে পারলেই কেবল এই বৈশিষ্ট্যটি ব্যবহার করুন। সাবধানতার সাথে এগিয়ে যান।</string>
<string name="proceed">এগিয়ে যান</string>
<string name="cancel">বাতিল করুন</string>
<string name="later">পরে</string>
<string name="lkm_warning_message">LKM প্যাচটি ক্লোজড সোর্স উপাদানের উপর নির্ভর করে। আপনি কি চালিয়ে যেতে চান?</string>
<string name="home_next_kernelsu">🔥 পরবর্তী বিল্ড</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Next experimental branch. Check it out on GitHub!</string>
<string name="home_experimental_kernelsu">⚠️পরীক্ষামূলক উন্নয়নের সতর্কতা!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next একটি বেসরকারী সংস্করণ যা সর্বদা সক্রিয় পরীক্ষামূলক বিকাশের অধীনে থাকে। এটি যেমন আছে তেমনই সরবরাহ করা হয়, স্থিতিশীলতা, কর্মক্ষমতা বা নির্ভরযোগ্যতার কোনও গ্যারান্টি ছাড়াই।</string>
<string name="home_experimental_kernelsu_body_point_1">• আপনার নিজের ঝুঁকিতে ব্যবহার করুন: ক্র্যাশ, অপ্রত্যাশিত আচরণ, অথবা সিস্টেম সমস্যা দেখা দিতে পারে।</string>
<string name="home_experimental_kernelsu_body_point_2">• কোনও ওয়ারেন্টি নেই: ডেভেলপাররা এর ব্যবহারের ফলে কোনও ডেটা ক্ষতি, সিস্টেমের ক্ষতি বা অন্যান্য পরিণতির জন্য দায়ী থাকবে না।</string>
<string name="home_experimental_kernelsu_body_point_3">• শুধুমাত্র পরীক্ষার উদ্দেশ্যে: ঝুঁকিগুলি বোঝেন এবং সমস্যা সমাধানে স্বাচ্ছন্দ্য বোধ করেন এমন ব্যবহারকারীদের জন্য।</string>
<string name="about_source_code">সোর্স কোড দেখুন %1$s</string>
<string name="profile">App Profile</string>
<string name="profile_default">ডিফল্ট</string>
<string name="profile_template">টেমপ্লেট</string>
<string name="profile_custom">কাস্টম</string>
<string name="profile_name">প্রোফাইলের নাম</string>
<string name="profile_namespace">নেমস্পেস মাউন্ট করুন</string>
<string name="profile_namespace_inherited">উত্তরাধিকারসূত্রে প্রাপ্ত</string>
<string name="profile_namespace_global">গ্লোবাল</string>
<string name="profile_namespace_individual">স্বতন্ত্র</string>
<string name="profile_groups">গ্রুপ</string>
<string name="profile_capabilities">সক্ষমতা</string>
<string name="profile_selinux_context">SELinux প্রসঙ্গ</string>
<string name="profile_umount_modules">Umount modules</string>
<string name="failed_to_update_app_profile">Failed to update App Profile for %s</string>
<string name="require_kernel_version">The current KernelSU Next version %1$d is too low for the manager to work properly. Please upgrade to version %2$d or higher!</string>
<string name="settings_umount_modules_default">Umount modules</string>
<string name="settings_umount_modules_default_summary">The global default value for \"Umount modules\" in App Profile. If enabled, it will remove all module modifications to the system for apps that don\'t have a profile set.</string>
<string name="settings_susfs_toggle">Hide kprobes hook</string>
<string name="settings_susfs_toggle_summary">This option disables the kprobes hook created by ksu and, instead, activates the embedded non-kprobes hook, implementing the same functionality that would be applied to a non-GKI kernel, which doesn\'t support kprobe.</string>
<string name="profile_umount_modules_summary">Enabling this option will allow KernelSU Next to restore any modified files by the modules for this app.</string>
<string name="profile_selinux_domain">Domain</string>
<string name="profile_selinux_rules">Rules</string>
<string name="module_update">Update</string>
<string name="module_update_available">Update</string>
<string name="module_updated">Updated</string>
<string name="module_downloading">Downloading module: %s</string>
<string name="module_start_downloading">Start downloading: %s</string>
<string name="new_version_available">New version %s is available, click to upgrade.</string>
<string name="launch_app">Launch</string>
<string name="close">Close</string>
<string name="force_stop_app">Force stop</string>
<string name="restart_app">Restart</string>
<string name="settings_amoled_mode">AMOLED mode</string>
<string name="settings_amoled_mode_summary">Enable a pure black theme useful for AMOLED screens to reduce eye strain and save battery.</string>
<string name="restart_required">Restart required</string>
<string name="restart_app_message">The app needs to restart for this change to take effect.</string>
<string name="failed_to_update_sepolicy">Failed to update SELinux rules for %s</string>
<string name="su_not_allowed">Couldn\'t grant Superuser access to %s</string>
<string name="module_changelog">Changelog</string>
<string name="settings_profile_template">App Profile template</string>
<string name="settings_profile_template_summary">Manage local and online template of App Profile</string>
<string name="app_profile_template_create">Create template</string>
<string name="app_profile_template_edit">Edit template</string>
<string name="app_profile_template_id">ID</string>
<string name="app_profile_template_id_invalid">Invalid template ID</string>
<string name="app_profile_template_name">Name</string>
<string name="app_profile_template_description">Description</string>
<string name="app_profile_template_save">Save</string>
<string name="app_profile_template_delete">Delete</string>
<string name="app_profile_template_view">View template</string>
<string name="app_profile_template_readonly">Read only</string>
<string name="app_profile_template_id_exist">Template ID already exists!</string>
<string name="app_profile_import_export">Import/Export</string>
<string name="app_profile_import_from_clipboard">Import from clipboard</string>
<string name="app_profile_export_to_clipboard">Export to clipboard</string>
<string name="app_profile_template_export_empty">Cannot find local template to export!</string>
<string name="app_profile_template_import_success">Imported successfully</string>
<string name="app_profile_template_sync">Sync online templates</string>
<string name="app_profile_template_save_failed">Failed to save template</string>
<string name="app_profile_template_import_empty">Clipboard is empty!</string>
<string name="module_changelog_failed">Fetch changelog failed: %s</string>
<string name="settings_check_update">Check for updates</string>
<string name="settings_check_update_summary">Automatically check for updates when opening the app</string>
<string name="grant_root_failed">Failed to grant root!</string>
<string name="action">Action</string>
<string name="webui">WebUI</string>
<string name="open">Open</string>
<string name="enable_web_debugging">Enable WebView debugging</string>
<string name="enable_web_debugging_summary">Can be used to debug WebUI. Please enable only when needed.</string>
<string name="direct_install">Direct install (Recommended)</string>
<string name="select_file">Select a file</string>
<string name="install_inactive_slot">Install to inactive slot (After OTA)</string>
<string name="install_inactive_slot_warning">Your device will be **FORCED** to boot to the current inactive slot after a reboot!\nOnly use this option after OTA is done.\nContinue?</string>
<string name="install_next">Next</string>
<string name="select_file_tip">%1$s partition image is recommended</string>
<string name="select_kmi">Select KMI</string>
<string name="shrink_sparse_image">Minimize sparse image</string>
<string name="shrink_sparse_image_message">Resize the sparse image where the module is located to its actual size. Note that this may cause the module to work abnormally, so please only use when necessary (Such as for backup).</string>
<string name="settings_uninstall">Uninstall</string>
<string name="settings_uninstall_temporary">Uninstall temporarily</string>
<string name="settings_uninstall_permanent">Uninstall permanently</string>
<string name="settings_restore_stock_image">Restore stock image</string>
<string name="settings_uninstall_temporary_message">Temporarily uninstall KernelSU Next, restore to original state after next reboot.</string>
<string name="settings_uninstall_permanent_message">Uninstalling KernelSU Next (Root and all modules) completely and permanently.</string>
<string name="settings_restore_stock_image_message">Restore the stock factory image (If a backup exists), usually used before OTA; if you need to uninstall KernelSU Next, please use \"Uninstall permanently\".</string>
<string name="flashing">Flashing</string>
<string name="flash_success">Flash success</string>
<string name="flash_failed">Flash failed</string>
<string name="selected_lkm">Selected LKM: %s</string>
<string name="save_log">Save logs</string>
<string name="log_saved">Logs saved</string>
<string name="send_log">Share logs</string>
<string name="settings_disable_su">Disable su compatibility</string>
<string name="settings_disable_su_summary">Temporarily disable the ability of any app to gain root privileges via the su command (Existing root processes won\'t be affected).</string>
<string name="settings_language">Language</string>
<string name="system_default">System default</string>
<string name="settings_legacyui">Use legacy UI</string>
<string name="settings_legacyui_summary">Switch to the previous user interface style.</string>
<string name="settings_banner">Enable banners</string>
<string name="settings_banner_summary">Show background banners for modules.</string>
<string name="use_webuix">Use WebUI X</string>
<string name="use_webuix_summary">Use WebUI X instead of WebUI, which supports more APIs.</string>
<string name="use_webuix_eruda">Inject Eruda into WebUI X</string>
<string name="use_webuix_eruda_summary">Inject a debug console into WebUI X to make debugging easier. Requires web debugging to be on.</string>
<string name="customization">Customization</string>
<string name="developer">Developer</string>
<string name="sucompat_disabled">SUCOMPAT DISABLED</string>
<string name="zygisk_required">Zygisk required</string>
<string name="zygisk_status">Zygisk injection</string>
<string name="home_superuser_count_singular">Superuser</string>
<string name="home_superuser_count_plural">Superusers</string>
<string name="home_module_count_singular">Module</string>
<string name="home_module_count_plural">Modules</string>
<string name="module_backup_message">Backup currently installed modules.</string>
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
<string name="module_sort_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI first)</string>
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
</resources>

View File

@@ -0,0 +1,236 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">Haben Sie Schwierigkeiten?</string>
<string name="issue_report_body">Sind Sie auf einen Fehler gestoßen, oder wollen Sie eine Rückmeldung geben?</string>
<string name="issue_report_body_2">Melden Sie es so schnell wie möglich!</string>
<string name="issue_report_github">Meldung über GitHub</string>
<string name="issue_report_telegram">Kontakt über Telegram</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Bestätigen</string>
<string name="app_name">KernelSU Next</string>
<string name="home">Hauptseite</string>
<string name="home_not_installed">Nicht installiert</string>
<string name="home_click_to_install">Klicke zum Installieren</string>
<string name="lkm_mode_deprecated">Der LKM-Modus ist jetzt veraltet!</string>
<string name="lkm_alternative_suggestion">Installieren Sie den GKI-Kernel oder integrieren Sie KernelSU Next in Ihrem Gerät.</string>
<string name="home_working">Funktioniert</string>
<string name="home_working_version">Version: %d</string>
<string name="home_module_update_count">Aktualisierungen: %d</string>
<string name="home_failure">KernelSU Next v2 Signatur nicht gefunden im Kernel! [!KSU_NEXT || != Größe/Hash]</string>
<string name="home_failure_tip">Bitten Sie Ihren Kernel-Entwickler KernelSU Next zu integrieren!</string>
<string name="home_kernel">Kernel-Version</string>
<string name="hook_mode">Einbindungs-Modus</string>
<string name="enable">Aktivieren</string>
<string name="disable">Deaktivieren</string>
<string name="enabled">Aktiviert</string>
<string name="disabled">Deaktiviert</string>
<string name="susfs_supported">Unterstützt</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">SuSFS-Version</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Android-Version</string>
<string name="home_manager_version">Manager-Version</string>
<string name="home_abi">Application Binary Interface (ABI)</string>
<string name="home_selinux_status">SELinux-Status</string>
<string name="selinux_status_disabled">Deaktiviert</string>
<string name="selinux_status_enforcing">Erzwingung</string>
<string name="selinux_status_permissive">Freizügig</string>
<string name="selinux_status_unknown">Unbekannt</string>
<string name="superuser">Superuser</string>
<string name="module_failed_to_enable">Modulaktivierung fehlgeschlagen: %s</string>
<string name="module_failed_to_disable">Moduldeaktivierung fehlgeschlagen: %s</string>
<string name="module_empty">Kein Modul installiert</string>
<string name="module">Modul</string>
<string name="module_install_prompt_with_name">Die folgenden Module werden installiert: %1$s</string>
<string name="module_sort_a_to_z">Sortierung (A → Z)</string>
<string name="module_sort_z_to_a">Sortierung (Z → A)</string>
<string name="module_size_low_to_high">Sortierung (niedrig → hoch)</string>
<string name="module_size_high_to_low">Sortierung (hoch → niedrig)</string>
<string name="uninstall">Deinstallieren</string>
<string name="restore">Wiederherstellen</string>
<string name="module_install">Installieren</string>
<string name="install">Installieren</string>
<string name="reboot">Neustart</string>
<string name="uninstalled">deinstalliert</string>
<string name="settings">Einstellungen</string>
<string name="reboot_userspace">Schneller Neustart</string>
<string name="reboot_recovery">Neustart ins Recovery</string>
<string name="reboot_bootloader">Neustart in den Bootloader</string>
<string name="reboot_download">Neustart in den Download-Modus</string>
<string name="reboot_edl">Neustart in den Notfall-Download-Modus (EDL)</string>
<string name="about">Über</string>
<string name="module_uninstall_confirm">Möchten Sie das Modul %s wirklich deinstallieren?</string>
<string name="module_uninstall_success">%s deinstalliert</string>
<string name="module_uninstall_failed">Deinstallation fehlgeschlagen: %s</string>
<string name="module_restore_confirm">Sind Sie sicher, dass Sie das Modul %s wiederherstellen möchten?</string>
<string name="module_restore_success">%s wiederhergestellt</string>
<string name="module_restore_failed">Wiederherstellung fehlgeschlagen: %s</string>
<string name="module_version">Version</string>
<string name="module_author">Autor</string>
<string name="module_id">Kennung</string>
<string name="module_version_code">Schlüssel</string>
<string name="module_update_json">Aktualisiere Json</string>
<string name="module_update_json_empty">Leer</string>
<string name="enable_developer_options">Aktivieren Sie die Entwickleroptionen</string>
<string name="enable_developer_options_summary">Zeigen Sie die versteckten Einstellungen und Fehlersuche-Informationen, die nur für Entwickler relevant sind.</string>
<string name="module_overlay_fs_not_available">Module sind nicht verfügbar, da OverlayFS vom Kernel deaktiviert wurde!</string>
<string name="refresh">Aktualisieren</string>
<string name="show_system_apps">System-Apps anzeigen</string>
<string name="hide_system_apps">System-Apps ausblenden</string>
<string name="export_log">Exportprotokolle</string>
<string name="safe_mode">Abgesicherter Modus</string>
<string name="reboot_to_apply">Neu starten, um wirksam zu werden</string>
<string name="module_magisk_conflict">Module sind aufgrund eines Konflikts mit Magisk nicht verfügbar!</string>
<string name="home_mount_system">Einhäng-Methode</string>
<string name="home_magic_mount">Magic einhängen</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Nicht verfügbar</string>
<string name="use_overlay_fs">Verwenden Sie OverlayFS</string>
<string name="use_overlay_fs_summary">Schalten Sie zwischen der Verwendung von OverlayFS und Magic Mount für das Einhängesystem von KernelSU Next um.</string>
<string name="reboot_required">Neustart erforderlich</string>
<string name="reboot_message">Die Änderungen werden nach dem Neustart des Systems wirksam. Möchten Sie jetzt neu starten?</string>
<string name="module_restore">Module wiederherstellen</string>
<string name="module_restore_message">Die Module aus der letzten Sicherung wiederherstellen.</string>
<string name="backup_restore">Sicherung &amp; Wiederherstellung</string>
<string name="module_backup">Module sichern</string>
<string name="allowlist_restore">Zulassungsliste wiederherstellen</string>
<string name="allowlist_restore_message">Die Zulassungsliste aus der letzten Sicherung wiederherstellen.</string>
<string name="allowlist_backup">Zulassungsliste sichern</string>
<string name="allowlist_backup_message">Sichern der momentan konfigurierten Zulassungsliste.</string>
<string name="warning">Warnung</string>
<string name="warning_message">Diese Funktion befindet sich noch im Beta-Status und in der Entwicklung. Bitte stellen Sie sicher, dass Sie Ihre Module sichern bevor Sie fortfahren. Verwenden Sie diese Funktion nur, wenn Sie die potenziellen Risiken verstehen. Vorsichtig vorgehen.</string>
<string name="proceed">Fortfahren</string>
<string name="cancel">Abbrechen</string>
<string name="later">Später</string>
<string name="lkm_warning_message">Der LKM-Patch basiert auf geschlossenen Quellen-Komponenten. Möchten Sie fortfahren?</string>
<string name="home_next_kernelsu">🔥 Nächster Build</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Nächster experimenteller Zweig. Probieren Sie es auf GitHub aus!</string>
<string name="home_experimental_kernelsu">⚠️ Warnung vor experimenteller Entwicklung!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next ist eine nicht-offizielle Version, die sich stets in aktiver experimenteller Entwicklung befindet. Sie wird im Ist-Zustand zur Verfügung gestellt, ohne Garantie auf Stabilität, Leistung oder Zuverlässigkeit.</string>
<string name="home_experimental_kernelsu_body_point_1"> • Verwenden Sie auf eigenes Risiko: Abstürze, unerwartes Verhalten oder Systemprobleme können auftreten.</string>
<string name="home_experimental_kernelsu_body_point_2"> • Keine Garantie: Die Entwickler sind nicht verantwortlich für Datenverluste, Systemschäden oder andere Folgen, die sich aus der Nutzung ergeben.</string>
<string name="home_experimental_kernelsu_body_point_3"> • Nur zu Testzwecken: für Benutzer, die sich der Risiken bewusst sind und mit der Behebung von Problemen vertraut sind.</string>
<string name="about_source_code">Quellcode anzeigen unter %1$s</string>
<string name="profile">App-Profil</string>
<string name="profile_default">Standard</string>
<string name="profile_template">Vorlage</string>
<string name="profile_custom">Benutzerdefiniert</string>
<string name="profile_name">Profilname</string>
<string name="profile_namespace">Namensraum einhängen</string>
<string name="profile_namespace_inherited">Geerbt</string>
<string name="profile_namespace_global">Global</string>
<string name="profile_namespace_individual">Individuell</string>
<string name="profile_groups">Gruppen</string>
<string name="profile_capabilities">Fähigkeiten</string>
<string name="profile_selinux_context">SELinux Kontext</string>
<string name="profile_umount_modules">Module aushängen</string>
<string name="failed_to_update_app_profile">Das App Profil für %s wurde nicht aktualisiert</string>
<string name="require_kernel_version">Der aktuelle KernelSU Next Version %1$d ist zu niedrig, als dass der Manager ordnungsgemäß funktioniert. Bitte aktualisieren Sie auf Version %2$d oder höher!</string>
<string name="settings_umount_modules_default">Module aushängen</string>
<string name="settings_umount_modules_default_summary">Der globale Standardwert für „Module aushängen“ im App-Profil. Wenn er aktiviert ist, werden alle Moduländerungen im System für Apps entfernt, für die kein Profil festgelegt ist.</string>
<string name="settings_susfs_toggle">Kprobes Hook ausblenden</string>
<string name="settings_susfs_toggle_summary">Diese Option deaktiviert den von ksu erzeugten kprobes-Hook und aktiviert stattdessen den eingebetteten non-kprobes-Hook, der die gleiche Funktionalität implementiert, die auf einen Nicht-GKI-Kernel angewendet würde, der kprobe nicht unterstützt.</string>
<string name="profile_umount_modules_summary">Wenn Sie diese Option aktivieren, kann KernelSU Next alle von den Modulen für diese Anwendung geänderten Dateien wiederherstellen.</string>
<string name="profile_selinux_domain">Domäne</string>
<string name="profile_selinux_rules">Regeln</string>
<string name="module_update">Aktualisieren</string>
<string name="module_update_available">Aktualisieren</string>
<string name="module_updated">Aktualisiert</string>
<string name="module_downloading">Modul wird heruntergeladen: %s</string>
<string name="module_start_downloading">Start des Herunterladens: %s</string>
<string name="new_version_available">Neue Version %s ist verfügbar, klicken Sie zum Aktualisieren.</string>
<string name="launch_app">Start</string>
<string name="close">Schließen</string>
<string name="force_stop_app">Stopp erzwingen</string>
<string name="restart_app">Neu starten</string>
<string name="settings_amoled_mode">AMOLED-Modus</string>
<string name="settings_amoled_mode_summary">Aktivieren Sie ein rein schwarzes Thema, das für AMOLED-Bildschirme nützlich ist, um die Augen zu entlasten und den Akku zu schonen.</string>
<string name="restart_required">Neustart erforderlich</string>
<string name="restart_app_message">Die App muss neu gestartet werden, damit diese Änderung wirksam wird.</string>
<string name="failed_to_update_sepolicy">Aktualisierung der SELinux Regeln für %s fehlgeschlagen</string>
<string name="su_not_allowed">Superuser-Zugriff auf %s konnte nicht gewährt werden</string>
<string name="module_changelog">Änderungsprotokoll</string>
<string name="settings_profile_template">App Profilvorlage</string>
<string name="settings_profile_template_summary">Verwalten Sie lokale und Online-Vorlagen von App-Profilen</string>
<string name="app_profile_template_create">Vorlage erstellen</string>
<string name="app_profile_template_edit">Vorlage bearbeiten</string>
<string name="app_profile_template_id">Kennung</string>
<string name="app_profile_template_id_invalid">Ungültige Vorlagen-Kennung</string>
<string name="app_profile_template_name">Name</string>
<string name="app_profile_template_description">Beschreibung</string>
<string name="app_profile_template_save">Speichern</string>
<string name="app_profile_template_delete">Löschen</string>
<string name="app_profile_template_view">Vorlage anzeigen</string>
<string name="app_profile_template_readonly">Nur lesen</string>
<string name="app_profile_template_id_exist">Vorlagen -Kennung existiert bereits!</string>
<string name="app_profile_import_export">Importieren/Exportieren</string>
<string name="app_profile_import_from_clipboard">Aus der Zwischenablage importieren</string>
<string name="app_profile_export_to_clipboard">In die Zwischenablage exportieren</string>
<string name="app_profile_template_export_empty">Lokale Vorlage zum Exportieren nicht gefunden!</string>
<string name="app_profile_template_import_success">Erfolgreich importiert</string>
<string name="app_profile_template_sync">Online Vorlagen synchronisieren</string>
<string name="app_profile_template_save_failed">Vorlage speichern fehlgeschlagenen</string>
<string name="app_profile_template_import_empty">Zwischenablage ist leer!</string>
<string name="module_changelog_failed">Änderungsprotokoll abrufen fehlgeschlagen: %s</string>
<string name="settings_check_update">Nach Aktualisierungen suchen</string>
<string name="settings_check_update_summary">Automatische Suche nach Updates beim Öffnen der App</string>
<string name="grant_root_failed">Root-Zugriff konnte nicht gewährt werden!</string>
<string name="action">Aktion</string>
<string name="webui">WebUI</string>
<string name="open">Öffnen</string>
<string name="enable_web_debugging">WebView-Debugging einschalten</string>
<string name="enable_web_debugging_summary">Kann zum Debuggen von WebUI verwendet werden. Bitte nur bei Bedarf aktivieren.</string>
<string name="direct_install">Direkte Installation (empfohlen)</string>
<string name="select_file">Datei wählen</string>
<string name="install_inactive_slot">Auf inaktive Partition installieren (nach OTA)</string>
<string name="install_inactive_slot_warning">Ihr Gerät wird **gezwungen**, nach einem Neustart in die aktuell inaktive Partition zu booten!\nVerwenden Sie diese Option nur, nachdem OTA abgeschlossen ist.\nFortfahren?</string>
<string name="install_next">Weiter</string>
<string name="select_file_tip">%1$s Partitionsabbild wird empfohlen</string>
<string name="select_kmi">Wählen Sie KMI</string>
<string name="shrink_sparse_image">Sparse-Image minimieren</string>
<string name="shrink_sparse_image_message">Ändern Sie die Größe des Sparse-Images, in dem sich das Modul befindet, auf seine tatsächliche Größe. Beachten Sie, dass dies dazu führen kann, dass das Modul nicht ordnungsgemäß funktioniert, und verwenden Sie es daher nur, wenn es notwendig ist (z. B. zur Sicherung).</string>
<string name="settings_uninstall">Deinstallieren</string>
<string name="settings_uninstall_temporary">Vorübergehend deinstallieren</string>
<string name="settings_uninstall_permanent">Dauerhaft deinstallieren</string>
<string name="settings_restore_stock_image">Werksabbild wiederherstellen</string>
<string name="settings_uninstall_temporary_message">Vorübergehende Deinstallation von KernelSU Next, Wiederherstellung des ursprünglichen Zustands nach dem nächsten Neustart.</string>
<string name="settings_uninstall_permanent_message">KernelSU Next (Root und alle Module) vollständig und dauerhaft deinstallieren.</string>
<string name="settings_restore_stock_image_message">Stellen Sie das Werksabbild wieder her (wenn ein Backup vorhanden ist), das normalerweise vor OTA verwendet wird; Wenn Sie KernelSU Next deinstallieren müssen, verwenden Sie bitte „Dauerhaft deinstallieren“.</string>
<string name="flashing">Schreiben</string>
<string name="flash_success">Schreiben erfolgreich</string>
<string name="flash_failed">Schreiben fehlgeschlagen</string>
<string name="selected_lkm">Ausgewählte LKM: %s</string>
<string name="save_log">Protokolle speichern</string>
<string name="log_saved">Protokolle gespeichert</string>
<string name="send_log">Protokolle teilen</string>
<string name="settings_disable_su">su-Kompatibilität deaktivieren</string>
<string name="settings_disable_su_summary">Deaktivieren Sie vorübergehend die Fähigkeit jeder Anwendung, über den Befehl su Root-Rechte zu erlangen (bestehende Root-Prozesse sind davon nicht betroffen).</string>
<string name="settings_language">Sprache</string>
<string name="system_default">Systemvorgabe</string>
<string name="settings_legacyui">Alte Benutzeroberfläche verwenden</string>
<string name="settings_legacyui_summary">Wechseln Sie zum vorherigen Benutzeroberflächenstil.</string>
<string name="settings_banner">Aktivieren von Bannern</string>
<string name="settings_banner_summary">Hintergrundbanner für Module anzeigen.</string>
<string name="use_webuix">Verwende WebUI X</string>
<string name="use_webuix_summary">Verwenden Sie WebUI X anstelle von WebUI, das mehr APIs unterstützt.</string>
<string name="use_webuix_eruda">Eruda in WebUI X einbinden</string>
<string name="use_webuix_eruda_summary">Einfügen einer Debug-Konsole in WebUI X, um das Debugging zu erleichtern. Erfordert, dass Web-Debugging eingeschaltet ist.</string>
<string name="customization">Personalisierung</string>
<string name="developer">Entwickler</string>
<string name="sucompat_disabled">SUCOMPAT DEAKTIVIERT</string>
<string name="zygisk_required">Zygisk erforderlich</string>
<string name="zygisk_status">Zygisk-Einbindung</string>
<string name="home_superuser_count_singular">Superuser</string>
<string name="home_superuser_count_plural">Superusers</string>
<string name="home_module_count_singular">Modul</string>
<string name="home_module_count_plural">Module</string>
<string name="module_backup_message">Sicherung der aktuell installierten Module.</string>
<string name="module_sort_enabled_first">Sortierung (aktivierte zuerst)</string>
<string name="module_sort_action_first">Sortierung (Aktion zuerst)</string>
<string name="module_sort_webui_first">Sortierung (WebUI zuerst)</string>
<string name="settings_global_namespace_mode">Globaler Namensraum-Modus</string>
<string name="settings_global_namespace_mode_summary">Alle Root-Sitzungen verwenden den globalen Mount-Namespace</string>
</resources>

View File

@@ -1,193 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">Haben Sie Probleme?</string>
<string name="issue_report_body">Sind Sie auf einen Fehler gestoßen oder haben Sie Feedback??</string>
<string name="issue_report_body_2">Melden Sie es so schnell wie möglich!</string>
<string name="issue_report_github">Auf GitHub melden</string>
<string name="issue_report_telegram">Kontakt über Telegramm</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Bestätigen</string>
<string name="app_name" translatable="false">KernelSU Next</string>
<string name="home">Home</string>
<string name="home_not_installed">Nicht installiert</string>
<string name="home_click_to_install">Zum installieren klicken</string>
<string name="home_working">Funktioniert</string>
<string name="home_working_version">Version: %d</string>
<string name="home_superuser_count">Superusers: %d</string>
<string name="home_module_count">Module: %d</string>
<string name="home_failure">KernelSU Next v2 Signatur nicht im Kernel gefunden! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">Bitten Sie Ihren Kernel-Entwickler, KernelSU Next zu integrieren!</string>
<string name="home_kernel">Kernel version</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">SuSFS version</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Android version</string>
<string name="home_manager_version">Manager version</string>
<string name="home_selinux_status">SELinux status</string>
<string name="selinux_status_disabled">Deaktiviert</string>
<string name="selinux_status_enforcing">Enforcing</string>
<string name="selinux_status_permissive">Permissive</string>
<string name="selinux_status_unknown">Unbekannt</string>
<string name="superuser">Superuser</string>
<string name="module_failed_to_enable">Aktivierung des Moduls fehlgeschlagen: %s</string>
<string name="module_failed_to_disable">Deaktivierung des Moduls fehlgeschlagen: %s</string>
<string name="module_empty">Kein Modul installiert</string>
<string name="module">Modul</string>
<string name="module_install_prompt_with_name">Das/die folgende(n) Modul(e) wird/werden installiert: %1$s</string>
<string name="module_sort_a_to_z">Sortieren (A-Z)</string>
<string name="module_sort_z_to_a">Sortieren (Z-A)</string>
<string name="uninstall">Deinstallieren</string>
<string name="restore">Wiederherstellen</string>
<string name="module_install">Installieren</string>
<string name="install">Installieren</string>
<string name="reboot">Neustart</string>
<string name="settings">Einstellungen</string>
<string name="reboot_userspace">Weicher Neustart</string>
<string name="reboot_recovery">Neustart zur Recovery</string>
<string name="reboot_bootloader">Neustart zum Bootloader</string>
<string name="reboot_download">Neustart zu Download</string>
<string name="reboot_edl">Neustart zu EDL</string>
<string name="about">Über</string>
<string name="module_uninstall_confirm">Sind Sie sicher, dass Sie das Modul deinstallieren möchten? %s?</string>
<string name="module_uninstall_success">%s deinstalliert</string>
<string name="module_uninstall_failed">Deinstallierung fehlgeschlagen %s</string>
<string name="module_restore_confirm">Sind Sie sicher, dass Sie das Modul wiederherstellen wollen? %s?</string>
<string name="module_restore_success">%s wiederhergestekkt</string>
<string name="module_restore_failed">Wiederherstellung fehlgeschlagen: %s</string>
<string name="module_version">Version</string>
<string name="module_author">Autor</string>
<string name="module_id">ID</string>
<string name="module_version_code">Code</string>
<string name="module_update_json">UpdateJson</string>
<string name="module_update_json_empty">leer</string>
<string name="enable_developer_options">Aktiviere Entwickler-Optionen</string>
<string name="enable_developer_options_summary">Versteckte Einstellungen und Debug-Informationen anzeigen, die nur für Entwickler relevant sind.</string>
<string name="module_overlay_fs_not_available">Die Module sind nicht verfügbar, da OverlayFS vom Kernel deaktiviert ist.</string>
<string name="refresh">Aktualisieren</string>
<string name="show_system_apps">zeige system apps</string>
<string name="hide_system_apps">verstecke system apps</string>
<string name="export_log">Logs exportieren</string>
<string name="safe_mode">Abgesicherter Modus</string>
<string name="reboot_to_apply">Neustart, um wirksam zu werden</string>
<string name="module_magisk_conflict">Die Module sind aufgrund eines Konflikts mit Magisk nicht verfügbar!</string>
<string name="home_mount_system">Modul system</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Nicht verfügbar</string>
<string name="use_overlay_fs">OverlayFS verwenden</string>
<string name="use_overlay_fs_summary">Schalten Sie zwischen der Verwendung von OverlayFS und Magic Mount für das mount System von KernelSU Next um.</string>
<string name="reboot_required">Neustart erforderlich</string>
<string name="reboot_message">Die Änderungen werden nach dem Neustart des Systems wirksam. Möchten Sie jetzt neu starten?</string>
<string name="module_restore">Wiederherstellen module</string>
<string name="module_restore_message">Wiederherstellen von Modulen aus der letzten Sicherung.</string>
<string name="backup_restore">Sicherung &amp; Wiederherstellen</string>
<string name="module_backup">Sicherung module</string>
<string name="module_backup_message">Sicherung der aktuell installierten Module.</string>
<string name="allowlist_restore">Wiederherstellen der Zulassen-Liste</string>
<string name="allowlist_restore_message">Wiederherstellen der Zulassen-Liste aus dem letzten Backup.</string>
<string name="allowlist_backup">Sicherung der Zulassen-Liste</string>
<string name="allowlist_backup_message">Sicherung der aktuell konfigurierten Zulassen-Liste.</string>
<string name="warning">Warnung</string>
<string name="warning_message">diese Funktion befindet sich noch in der Beta-Phase und in der Entwicklung. Bitte stellen Sie sicher, dass Sie Ihre Module sichern, bevor Sie fortfahren. Verwenden Sie diese Funktion nur, wenn Sie sich der möglichen Risiken bewusst sind. Gehen Sie mit Bedacht vor.</string>
<string name="proceed">Fortfahren</string>
<string name="cancel">Abbruch</string>
<string name="later">Später</string>
<string name="home_next_kernelsu">🔥 Next build</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Next experimenteller Zweig. Entdecken Sie es auf GitHub!</string>
<string name="home_experimental_kernelsu">⚠️ Warnung vor experimenteller Entwicklung!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next ist eine nicht-offizielle Version, die sich stets in aktiver experimenteller Entwicklung befindet. Sie wird im Ist-Zustand zur Verfügung gestellt, ohne Garantie auf Stabilität, Leistung oder Zuverlässigkeit.</string>
<string name="home_experimental_kernelsu_body_point_1"> • Die Verwendung erfolgt auf eigene Gefahr: Abstürze, unerwartetes Verhalten oder Systemprobleme können auftreten.</string>
<string name="home_experimental_kernelsu_body_point_2"> • Keine Garantie: Die Entwickler sind nicht verantwortlich für Datenverluste, Systemschäden oder andere Folgen, die sich aus der Nutzung ergeben.</string>
<string name="home_experimental_kernelsu_body_point_3"> • Nur zu Testzwecken: für Benutzer, die sich der Risiken bewusst sind und mit der Behebung von Problemen vertraut sind.</string>
<string name="about_source_code"><![CDATA[Quellcode ansehen unter %1$s]]></string>
<string name="profile" translatable="false">App Profile</string>
<string name="profile_default">Standard</string>
<string name="profile_template">Vorlage</string>
<string name="profile_custom">Benutzerdefiniert</string>
<string name="profile_name">Profilname</string>
<string name="profile_namespace">Mount namespace</string>
<string name="profile_namespace_inherited">Vererbt</string>
<string name="profile_namespace_global">Global</string>
<string name="profile_namespace_individual">Individuell</string>
<string name="profile_groups">Gruppen</string>
<string name="profile_capabilities">Funktionen</string>
<string name="profile_selinux_context">SELinux context</string>
<string name="profile_umount_modules">Umount Module</string>
<string name="failed_to_update_app_profile">App-Profil konnte nicht aktualisiert werden für %s</string>
<string name="require_kernel_version">Die aktuelle KernelSU Next Version %1$d ist zu veraltet, damit der Manager richtig funktioniert. aktualisieren Sie bitte auf Version %2$d oder höher!</string>
<string name="settings_umount_modules_default">Umount Module</string>
<string name="settings_umount_modules_default_summary">Der globale Standardwert für \„Umount Module\“ in App Profile. Wenn er aktiviert ist, werden alle Moduländerungen im System für Anwendungen entfernt, für die kein Profil festgelegt wurde.</string>
<string name="settings_susfs_toggle">verstecke kprobes hook</string>
<string name="settings_susfs_toggle_summary">Diese Option deaktiviert die von ksu erzeugten kprobe-hooks und aktiviert stattdessen die eingebetteten nicht-kprobe-hooks, die die gleiche Funktionalität implementieren, die auf einen Nicht-GKI-Kernel angewendet würde, der kprobe nicht unterstützt.</string>
<string name="profile_umount_modules_summary">Wenn Sie diese Option aktivieren, kann KernelSU Next alle von den Modulen für diese Anwendung geänderten Dateien wiederherstellen.</string>
<string name="profile_selinux_domain">Domain</string>
<string name="profile_selinux_rules">Regeln</string>
<string name="module_update">Aktualisierung</string>
<string name="module_downloading">Herunterladen des Moduls: %s</string>
<string name="module_start_downloading">Mit dem Herunterladen beginnen: %s</string>
<string name="new_version_available">Neue Version %s ist verfügbar, klicken Sie zum Aktualisieren.</string>
<string name="launch_app">Start</string>
<string name="close">Schließen</string>
<string name="force_stop_app">Stopp erzwingen</string>
<string name="restart_app">Neustart</string>
<string name="failed_to_update_sepolicy">SELinux-Regeln konnten nicht aktualisiert werden: %s</string>
<string name="su_not_allowed">Das Gewähren von Superuser ist nicht erlaubt: %s</string>
<string name="module_changelog">Änderungsbericht</string>
<string name="settings_profile_template">App Profil Vorlage</string>
<string name="settings_profile_template_summary">Verwalten Sie lokale und Online-Vorlagen von App-Profilen</string>
<string name="app_profile_template_create">Vorlage erstellen</string>
<string name="app_profile_template_edit">Vorlage bearbeiten</string>
<string name="app_profile_template_id">ID</string>
<string name="app_profile_template_id_invalid">Ungültige Vorlagen-ID</string>
<string name="app_profile_template_name">Name</string>
<string name="app_profile_template_description">Beschreibung</string>
<string name="app_profile_template_save">Speichern</string>
<string name="app_profile_template_delete">Löschen</string>
<string name="app_profile_template_view">Vorlage ansehen</string>
<string name="app_profile_template_readonly">Nur lesen</string>
<string name="app_profile_template_id_exist">Die Vorlagen-ID existiert bereits!</string>
<string name="app_profile_import_export">Importieren/Exportieren</string>
<string name="app_profile_import_from_clipboard">Importieren aus der Zwischenablage</string>
<string name="app_profile_export_to_clipboard">In die Zwischenablage exportieren</string>
<string name="app_profile_template_export_empty">Lokale Vorlage für den Export nicht gefunden!</string>
<string name="app_profile_template_import_success">Erfolgreich importiert</string>
<string name="app_profile_template_sync">Online-Vorlagen synchronisieren</string>
<string name="app_profile_template_save_failed">Vorlage konnte nicht gespeichert werden</string>
<string name="app_profile_template_import_empty">Die Zwischenablage ist leer!</string>
<string name="module_changelog_failed">Abrufen des Änderungsberichts fehlgeschlagen: %s</string>
<string name="settings_check_update">Prüfen auf Aktualisierung</string>
<string name="settings_check_update_summary">Beim Öffnen der App automatisch nach Updates suchen.</string>
<string name="grant_root_failed">Root konnte nicht gewährt werden!</string>
<string name="action">Aktion</string>
<string name="open">Öffnen</string>
<string name="enable_web_debugging">WebView-Debugging aktivieren</string>
<string name="enable_web_debugging_summary">Kann zum Debuggen von WebUI verwendet werden. Bitte nur bei Bedarf aktivieren.</string>
<string name="direct_install">Direkte Installation (empfohlen)</string>
<string name="select_file">Eine Datei auswählen</string>
<string name="install_inactive_slot">Auf inaktivem slot installieren (nach OTA)</string>
<string name="install_inactive_slot_warning">Ihr Gerät wird **gezwungen**, nach einem Neustart in den aktuell inaktiven slot zu booten!\n Verwenden Sie diese Option nur, nachdem OTA abgeschlossen ist.\nFortfahren?</string>
<string name="install_next">Weiter</string>
<string name="select_file_tip">%1$s Partitionsabbild wird empfohlen</string>
<string name="select_kmi">KMI auswählen</string>
<string name="shrink_sparse_image">Minimierung des sparse Abbildes</string>
<string name="shrink_sparse_image_message">Ändern Sie die Größe des Sparse-Abbildes, in dem sich das Modul befindet, auf seine tatsächliche Größe. Beachten Sie, dass dies dazu führen kann, dass das Modul nicht ordnungsgemäß funktioniert, und verwenden Sie es daher nur, wenn es notwendig ist (z. B. zur Sicherung).</string>
<string name="settings_uninstall">Deinstallieren</string>
<string name="settings_uninstall_temporary">vorübergehend Deinstallieren</string>
<string name="settings_uninstall_permanent">Endgültig deinstallieren</string>
<string name="settings_restore_stock_image">Stock-Image wiederherstellen</string>
<string name="settings_uninstall_temporary_message">Vorübergehende Deinstallation von KernelSU Next, Wiederherstellung des ursprünglichen Zustands nach dem nächsten Neustart.</string>
<string name="settings_uninstall_permanent_message">KernelSU Next (Root und alle Module) vollständig und dauerhaft deinstallieren.</string>
<string name="settings_restore_stock_image_message">Stellen Sie das Werksabbild wieder her (wenn ein Backup vorhanden ist), das normalerweise vor OTA verwendet wird; wenn Sie KernelSU als Nächstes deinstallieren müssen, verwenden Sie bitte \„Endgültig deinstallieren\“.</string>
<string name="flashing">Flashing</string>
<string name="flash_success">Flash erfolgreich</string>
<string name="flash_failed">Flash fehlgeschlagen</string>
<string name="selected_lkm">Ausgewähltes LKM: %s</string>
<string name="save_log">Protokolle speichern</string>
<string name="log_saved">Protokolle gespeichert</string>
<string name="send_log">Protokolle teilen</string>
<string name="settings_disable_su">Su-Kompatibilität deaktivieren</string>
<string name="settings_disable_su_summary">Deaktivieren Sie vorübergehend alle Anwendungen, die über den Befehl su Root-Rechte erhalten (bestehende Root-Prozesse sind davon nicht betroffen).</string>
</resources>

View File

@@ -0,0 +1,236 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">¿Tienes problemas?</string>
<string name="issue_report_body">¿Encontraste un error o tienes comentarios?</string>
<string name="issue_report_body_2">¡Repórtalo lo mas pronto posible!</string>
<string name="issue_report_github">Reportar en GitHub</string>
<string name="issue_report_telegram">Contactar por Telegram</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Confirmar</string>
<string name="app_name">KernelSU Next</string>
<string name="home">Inicio</string>
<string name="home_not_installed">No instalado</string>
<string name="home_click_to_install">Haz clic para instalar</string>
<string name="lkm_mode_deprecated">¡El modo LKM está obsoleto!</string>
<string name="lkm_alternative_suggestion">Instale un kernel GKI o integre KernelSU Next a su dispositivo.</string>
<string name="home_working">Funcionando</string>
<string name="home_working_version">Versión: %d</string>
<string name="home_module_update_count">Actualizaciones: %d</string>
<string name="home_failure">¡Firma v2 de KernelSU Next no encontrada en el kernel! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">¡Pídele a tu desarrollador de kernel que integre KernelSU Next!</string>
<string name="home_kernel">Versión del kernel</string>
<string name="hook_mode">Método de intercepción</string>
<string name="enable">Activar</string>
<string name="disable">Desactivar</string>
<string name="enabled">Activado</string>
<string name="disabled">Desactivado</string>
<string name="susfs_supported">Compatible</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">Versión de SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Versión de Android</string>
<string name="home_manager_version">Versión del gestor</string>
<string name="home_abi">ABI</string>
<string name="home_selinux_status">Estado de SELinux</string>
<string name="selinux_status_disabled">Deshabilitado</string>
<string name="selinux_status_enforcing">Estricto</string>
<string name="selinux_status_permissive">Permisivo</string>
<string name="selinux_status_unknown">Desconocido</string>
<string name="superuser">Superusuario</string>
<string name="module_failed_to_enable">No se pudo activar el módulo: %s</string>
<string name="module_failed_to_disable">No se pudo desactivar el módulo: %s</string>
<string name="module_empty">Ningún módulo instalado</string>
<string name="module">Módulo</string>
<string name="module_install_prompt_with_name">Los siguientes módulos serán instalados: %1$s</string>
<string name="module_sort_a_to_z">Ordenar (A → Z)</string>
<string name="module_sort_z_to_a">Ordenar (Z → A)</string>
<string name="module_size_low_to_high">Ordenar (Menor → Mayor)</string>
<string name="module_size_high_to_low">Ordenar (Mayor → Menor)</string>
<string name="uninstall">Desinstalar</string>
<string name="restore">Restaurar</string>
<string name="module_install">Instalar</string>
<string name="install">Instalar</string>
<string name="reboot">Reiniciar</string>
<string name="uninstalled">Desinstalado</string>
<string name="settings">Ajustes</string>
<string name="reboot_userspace">Reinicio rápido</string>
<string name="reboot_recovery">Reiniciar en modo Recovery</string>
<string name="reboot_bootloader">Reiniciar en modo Bootloader</string>
<string name="reboot_download">Reiniciar en modo Download</string>
<string name="reboot_edl">Reiniciar en Modo EDL</string>
<string name="about">Acerca de</string>
<string name="module_uninstall_confirm">¿Estás seguro que quieres desinstalar el módulo %s?</string>
<string name="module_uninstall_success">%s desinstalado</string>
<string name="module_uninstall_failed">No se pudo desinstalar: %s</string>
<string name="module_restore_confirm">¿Estás seguro que quieres restaurar el módulo %s?</string>
<string name="module_restore_success">%s restaurado</string>
<string name="module_restore_failed">No se pudo restaurar: %s</string>
<string name="module_version">Versión</string>
<string name="module_author">Autor</string>
<string name="module_id">Identificador</string>
<string name="module_version_code">Revisión</string>
<string name="module_update_json">UpdateJson</string>
<string name="module_update_json_empty">Vacío</string>
<string name="enable_developer_options">Activar opciones de desarrollador</string>
<string name="enable_developer_options_summary">Muestra ajustes ocultos e información de depuración relevantes solo para desarrolladores.</string>
<string name="module_overlay_fs_not_available">¡Los módulos no están disponibles ya que OverlayFS está deshabilitado por el kernel!</string>
<string name="refresh">Actualizar</string>
<string name="show_system_apps">Mostrar aplicaciones del sistema</string>
<string name="hide_system_apps">Ocultar aplicaciones del sistema</string>
<string name="export_log">Exportar logs</string>
<string name="safe_mode">Modo seguro</string>
<string name="reboot_to_apply">Reiniciar para aplicar cambios</string>
<string name="module_magisk_conflict">¡Los módulos no están disponibles debido a un conflicto con Magisk!</string>
<string name="home_mount_system">Mecanismo de montaje</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">No disponible</string>
<string name="use_overlay_fs">Usar OverlayFS</string>
<string name="use_overlay_fs_summary">Alternar entre usar OverlayFS o Magic Mount para el mecanismo de montaje de KernelSU Next.</string>
<string name="reboot_required">Reinicio requerido</string>
<string name="reboot_message">Los cambios tendrán efecto después de reiniciar el sistema. ¿Deseas reiniciar ahora?</string>
<string name="module_restore">Restaurar módulo</string>
<string name="module_restore_message">Restaurar módulos desde una copia de seguridad reciente.</string>
<string name="backup_restore">Copia de seguridad y Restauración</string>
<string name="module_backup">Respaldar módulo</string>
<string name="allowlist_restore">Restaurar lista blanca</string>
<string name="allowlist_restore_message">Restaurar la lista blanca desde una copia de seguridad reciente.</string>
<string name="allowlist_backup">Respaldar lista blanca</string>
<string name="allowlist_backup_message">Respaldar la lista blanca actualmente configurada.</string>
<string name="warning">Advertencia</string>
<string name="warning_message">Esta función aún está en fase beta y en desarrollo. Asegúrate de hacer una copia de seguridad de tus módulos antes de continuar. Usa esta función solo si entiendes los riesgos potenciales. Procede con precaución.</string>
<string name="proceed">Continuar</string>
<string name="cancel">Cancelar</string>
<string name="later">Más adelante</string>
<string name="lkm_warning_message">El parche LKM depende de componentes de código cerrado. ¿Quieres continuar?</string>
<string name="home_next_kernelsu">🔥 Compilación Next</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Rama Next experimental. ¡Échale un vistazo en GitHub!</string>
<string name="home_experimental_kernelsu">⚠️ ¡Advertencia de desarrollo experimental!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next es una versión no oficial que siempre está en desarrollo experimental activo. Se proporciona \"tal cual\", sin garantías de estabilidad, rendimiento o fiabilidad.</string>
<string name="home_experimental_kernelsu_body_point_1"> • Úsalo bajo tu propio riesgo: pueden ocurrir fallos, comportamientos inesperados o problemas en el sistema.</string>
<string name="home_experimental_kernelsu_body_point_2"> • Sin garantía: los desarrolladores no se hacen responsables de ninguna pérdida de datos, daño al sistema u otras consecuencias resultantes de su uso.</string>
<string name="home_experimental_kernelsu_body_point_3"> • Solo para fines de prueba: destinado a usuarios que entienden los riesgos y se sienten cómodos solucionando problemas.</string>
<string name="about_source_code">Ver el código fuente en %1$s</string>
<string name="profile">Perfil de Aplicación</string>
<string name="profile_default">Predeterminado</string>
<string name="profile_template">Plantilla</string>
<string name="profile_custom">Personalizado</string>
<string name="profile_name">Nombre de perfil</string>
<string name="profile_namespace">Espacio de montaje aislado</string>
<string name="profile_namespace_inherited">Heredado</string>
<string name="profile_namespace_global">Global</string>
<string name="profile_namespace_individual">Individual</string>
<string name="profile_groups">Grupos</string>
<string name="profile_capabilities">Privilegios</string>
<string name="profile_selinux_context">Contexto de SELinux</string>
<string name="profile_umount_modules">Desmontar módulos</string>
<string name="failed_to_update_app_profile">Error al actualizar el perfil de aplicación para %s</string>
<string name="require_kernel_version">La versión actual de KernelSU Next %1$d es demasiado antigua para que el gestor funcione correctamente. ¡Actualiza a la versión %2$d o superior!</string>
<string name="settings_umount_modules_default">Desmontar módulos</string>
<string name="settings_umount_modules_default_summary">El valor global predeterminado para \"Desmontar módulos\" en el Perfil de App. Si se activa, eliminará todas las modificaciones de módulos en el sistema para las aplicaciones que no tengan un perfil establecido.</string>
<string name="settings_susfs_toggle">Ocultar la intercepción de kprobes</string>
<string name="settings_susfs_toggle_summary">Esta opción desactiva la intercepción de kprobes creada por ksu y, en su lugar, activa la intercepción integrada que no se basa en kprobes, implementando la misma funcionalidad que se aplicaría a un kernel no GKI, que no soporta kprobes.</string>
<string name="profile_umount_modules_summary">Activar esta opción permitirá a KernelSU Next restaurar cualquier archivo modificado por los módulos para esta apliacion.</string>
<string name="profile_selinux_domain">Dominio</string>
<string name="profile_selinux_rules">Reglas</string>
<string name="module_update">Actualizar</string>
<string name="module_update_available">Actualización</string>
<string name="module_updated">Actualizado</string>
<string name="module_downloading">Descargando módulo: %s</string>
<string name="module_start_downloading">Iniciando descarga: %s</string>
<string name="new_version_available">Nueva versión %s disponible, toca para actualizar.</string>
<string name="launch_app">Iniciar</string>
<string name="close">Cerrar</string>
<string name="force_stop_app">Forzar detención</string>
<string name="restart_app">Reiniciar</string>
<string name="settings_amoled_mode">Modo AMOLED</string>
<string name="settings_amoled_mode_summary">Activa un aspecto negro puro, útil para pantallas AMOLED, reducir la fatiga visual y ahorrar batería.</string>
<string name="restart_required">Reinicio necesario</string>
<string name="restart_app_message">La aplicación necesita reiniciarse para que este cambio tenga efecto.</string>
<string name="failed_to_update_sepolicy">Error al actualizar las reglas de SELinux para %s</string>
<string name="su_not_allowed">No se pudo conceder acceso de Superusuario a %s</string>
<string name="module_changelog">Registro de cambios</string>
<string name="settings_profile_template">Plantilla del perfil de aplicación</string>
<string name="settings_profile_template_summary">Gestiona plantillas locales y en línea del Perfil de la Aplicación</string>
<string name="app_profile_template_create">Crear plantilla</string>
<string name="app_profile_template_edit">Editar plantilla</string>
<string name="app_profile_template_id">ID</string>
<string name="app_profile_template_id_invalid">ID de plantilla inválido</string>
<string name="app_profile_template_name">Nombre</string>
<string name="app_profile_template_description">Descripción</string>
<string name="app_profile_template_save">Guardar</string>
<string name="app_profile_template_delete">Borrar</string>
<string name="app_profile_template_view">Ver plantilla</string>
<string name="app_profile_template_readonly">Sólo lectura</string>
<string name="app_profile_template_id_exist">¡El ID de plantilla ya existe!</string>
<string name="app_profile_import_export">Importar/Exportar</string>
<string name="app_profile_import_from_clipboard">Importar desde portapapeles</string>
<string name="app_profile_export_to_clipboard">Exportar al portapapeles</string>
<string name="app_profile_template_export_empty">¡No se encontraron plantillas locales para exportar!</string>
<string name="app_profile_template_import_success">Importado con éxito</string>
<string name="app_profile_template_sync">Sincronizar plantillas en línea</string>
<string name="app_profile_template_save_failed">Error al guardar plantilla</string>
<string name="app_profile_template_import_empty">¡El portapapeles está vacío!</string>
<string name="module_changelog_failed">Error al obtener registro de cambios: %s</string>
<string name="settings_check_update">Verificar si hay actualizaciones</string>
<string name="settings_check_update_summary">Buscar actualizaciones automáticamente al abrir la aplicación</string>
<string name="grant_root_failed">¡Error al conceder root!</string>
<string name="action">Acción</string>
<string name="webui">WebUI</string>
<string name="open">Abrir</string>
<string name="enable_web_debugging">Activar depuración de WebView</string>
<string name="enable_web_debugging_summary">Puede usarse para depurar WebUI. Habilitar solo cuando sea necesario.</string>
<string name="direct_install">Instalación directa (Recomendado)</string>
<string name="select_file">Seleccionar un archivo</string>
<string name="install_inactive_slot">Instalar al ranura inactiva (Después de OTA)</string>
<string name="install_inactive_slot_warning">¡Tu dispositivo será **FORZADO** a iniciar en la ranura inactiva actual después de reiniciar!\nUsa esta opción solo después de haber realizado una OTA.\n¿Continuar?</string>
<string name="install_next">Siguiente</string>
<string name="select_file_tip">Se recomienda la imagen de partición %1$s</string>
<string name="select_kmi">Seleccionar KMI</string>
<string name="shrink_sparse_image">Minimizar imagen sparse</string>
<string name="shrink_sparse_image_message">Redimensiona la imagen sparse donde se encuentra el módulo a su tamaño real. Ten en cuenta que esto puede hacer que el módulo funcione de forma anómala, así que por favor, úsalo solo cuando sea necesario (como para una copia de seguridad).</string>
<string name="settings_uninstall">Desinstalar</string>
<string name="settings_uninstall_temporary">Desinstalar temporalmente</string>
<string name="settings_uninstall_permanent">Desinstalar permanentemente</string>
<string name="settings_restore_stock_image">Restaurar imagen stock</string>
<string name="settings_uninstall_temporary_message">Desinstalar temporalmente KernelSU Next, restaurar al estado original después del próximo reinicio.</string>
<string name="settings_uninstall_permanent_message">Desinstalar KernelSU Next (Root y todos los módulos) completa y permanentemente.</string>
<string name="settings_restore_stock_image_message">Restaura la imagen stock (si existe una copia de seguridad), usado normalmente antes de una OTA; si necesitas desinstalar KernelSU Next, usa \"Desinstalación permanente\".</string>
<string name="flashing">Flasheando</string>
<string name="flash_success">Flasheado con éxito</string>
<string name="flash_failed">Error en el flasheo</string>
<string name="selected_lkm">Seleccionado LKM: %s</string>
<string name="save_log">Guardar logs</string>
<string name="log_saved">Logs guardados</string>
<string name="send_log">Enviar logs</string>
<string name="settings_disable_su">Deshabilitar compatibilidad su</string>
<string name="settings_disable_su_summary">Desactiva temporalmente la capacidad de cualquier app para obtener privilegios root mediante el comando su (los procesos root existentes no se verán afectados).</string>
<string name="settings_language">Idioma</string>
<string name="system_default">Predeterminado del sistema</string>
<string name="settings_legacyui">Usar interfaz antigua</string>
<string name="settings_legacyui_summary">Cambia al estilo de interfaz de usuario anterior.</string>
<string name="settings_banner">Activar banners</string>
<string name="settings_banner_summary">Mostrar banners de fondo para los módulos.</string>
<string name="use_webuix">Usar WebUI X</string>
<string name="use_webuix_summary">Usar WebUI X en lugar de WebUI, que soporta más APIs.</string>
<string name="use_webuix_eruda">Inyectar Eruda en WebUI X</string>
<string name="use_webuix_eruda_summary">Inyecta una consola de depuración en WebUI X para facilitar la depuración. Requiere que la depuración web esté activada.</string>
<string name="customization">Personalización</string>
<string name="developer">Desarrollador</string>
<string name="sucompat_disabled">SUCOMPAT DESHABILITADO</string>
<string name="zygisk_required">Se requiere Zygisk</string>
<string name="zygisk_status">Inyección Zygisk</string>
<string name="home_superuser_count_singular">Superusuario</string>
<string name="home_superuser_count_plural">Superusuarios</string>
<string name="home_module_count_singular">Módulo</string>
<string name="home_module_count_plural">Módulos</string>
<string name="module_backup_message">Respaldar los módulos actualmente instalados.</string>
<string name="module_sort_enabled_first">Ordenar (Activados Primero)</string>
<string name="module_sort_action_first">Ordenar (Accionables primero)</string>
<string name="module_sort_webui_first">Ordenar (WrbUI primero)</string>
<string name="settings_global_namespace_mode">Usar el Espacio de Montaje Aislado Global</string>
<string name="settings_global_namespace_mode_summary">Todas las sesiones root usan el espacio de montaje aislado global</string>
</resources>

View File

@@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">مشکلی دارید؟</string>
<string name="issue_report_body">با یک اشکال مواجه شدید یا بازخوردی دارید؟</string>
<string name="issue_report_body_2">هر چه سریعتر گزارش دهید!</string>
<string name="issue_report_github">گزارش در گیت‌هاب</string>
<string name="issue_report_telegram">تماس از طریق تلگرام</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">تأیید</string>
<string name="app_name">KernelSU Next</string>
<string name="home">خانه</string>
<string name="home_not_installed">نصب نشده</string>
<string name="home_click_to_install">برای نصب کلیک کنید</string>
<string name="lkm_mode_deprecated">حالت LKM اکنون منسوخ شده است!</string>
<string name="lkm_alternative_suggestion">کرنل GKI نصب کنید یا KernelSU را به صورت دستی بسازید.</string>
<string name="home_working">درحال کارکردن</string>
<string name="home_working_version">نسخه: %d</string>
<string name="home_module_update_count">بروزرسانی ها: %d</string>
<string name="home_failure">امضای KernelSU Next v2 در کرنل یافت نشد!
[KSU_NEXT || != size/hash!]</string>
<string name="home_failure_tip">از توسعه‌دهنده‌ی کرنل خود بخواهید که KernelSU Next را برای دستگاهتون بسازد!</string>
<string name="home_kernel">نسخه کرنل</string>
<string name="hook_mode">حالت هوک</string>
<string name="enable">فعال کردن</string>
<string name="disable">غیرفعال کردن</string>
<string name="enabled">فعال شده</string>
<string name="disabled">غیرفعال شده</string>
<string name="susfs_supported">پشتیبانی شده</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">نسخه SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">نسخه اندروید</string>
<string name="home_manager_version">نسخه مدیریت</string>
<string name="home_abi">رابطه باینری</string>
<string name="home_selinux_status">وضعیت SELinux</string>
<string name="selinux_status_disabled">غیرفعال شده</string>
<string name="selinux_status_enforcing">درحال اجرا</string>
<string name="selinux_status_permissive">مجاز</string>
<string name="selinux_status_unknown">ناشناخته</string>
<string name="superuser">کاربر روت</string>
<string name="module_failed_to_enable">ماژول فعال نشد: %s</string>
<string name="module_failed_to_disable">ماژول غیرفعال نشد: %s</string>
<string name="module_empty">ماژولی نصب نشده</string>
<string name="module">ماژول</string>
<string name="module_install_prompt_with_name">ماژول‌های زیر نصب خواهند شد: %1$s</string>
<string name="module_sort_a_to_z">مرتب‌سازی (الف → ی)</string>
<string name="module_sort_z_to_a">مرتب‌سازی (ی → الف)</string>
<string name="module_size_low_to_high">مرتب‌سازی (کم → زیاد)</string>
<string name="module_size_high_to_low">مرتب‌سازی (زیاد → کم)</string>
<string name="uninstall">حذف نصب</string>
<string name="restore">بازیابی</string>
<string name="module_install">نصب</string>
<string name="install">نصب</string>
<string name="reboot">راه‌اندازی مجدد</string>
<string name="uninstalled">حذف نصب شد</string>
<string name="settings">تنظیمات</string>
<string name="reboot_userspace">راه‌اندازی مجدد نرم</string>
<string name="reboot_recovery">راه‌اندازی مجدد به ریکاوری</string>
<string name="reboot_bootloader">راه‌اندازی مجدد به بوتلودر</string>
<string name="reboot_download">راه‌اندازی مجدد به دانلود</string>
<string name="reboot_edl">راه‌اندازی مجدد به EDL</string>
<string name="about">درباره</string>
<string name="module_uninstall_confirm">آیا مطمئن هستید که می‌خواهید ماژول را حذف نصب کنید %s؟</string>
<string name="module_uninstall_success">%s حذف نصب شد</string>
<string name="module_uninstall_failed">حذف نصب انجام نشد: %s</string>
<string name="module_restore_confirm">آیا مطمئن هستید که می‌خواهید ماژول را بازیابی کنید %s؟</string>
<string name="module_restore_success">%s بازیابی شد</string>
<string name="module_restore_failed">بازیابی نشد: %s</string>
<string name="module_version">نسخه</string>
<string name="module_author">نویسنده</string>
<string name="module_id">آیدی</string>
<string name="module_version_code">کد</string>
<string name="module_update_json">لینک بروزرسانی</string>
<string name="module_update_json_empty">خالی</string>
<string name="enable_developer_options">فعال کردن گزینه توسعه دهندگان</string>
<string name="enable_developer_options_summary">نمایش تنظیمات پنهان و اطلاعات اشکال‌زدایی که فقط برای توسعه‌دهندگان مرتبط است.</string>
<string name="module_overlay_fs_not_available">ماژول‌ها در دسترس نیستند زیرا OverlayFS توسط کرنل غیرفعال شده است!</string>
<string name="refresh">ریفرش</string>
<string name="show_system_apps">نمایش برنامه‌های سیستمی</string>
<string name="hide_system_apps">مخفی کردن برنامه‌های سیستمی</string>
<string name="export_log">خروجی گرفتن از لاگ‌ها</string>
<string name="safe_mode">حالت امن</string>
<string name="reboot_to_apply">برای اعمال شدن، راه‌اندازی مجدد کنید</string>
<string name="module_magisk_conflict">ماژول‌ها به دلیل تداخل با Magisk در دسترس نیستند!</string>
<string name="home_mount_system">سیستم نصب</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">غیرقابل دسترس</string>
<string name="use_overlay_fs">از OverlayFS استفاده کنید</string>
<string name="use_overlay_fs_summary">برای سیستم مانت KernelSU Next، بین استفاده از OverlayFS به جای Magic Mount یکی را انتخاب کنید.</string>
<string name="reboot_required">راه‌اندازی مجدد مورد نیاز است</string>
<string name="reboot_message">تغییرات پس از راه‌اندازی مجدد سیستم اعمال می‌شوند. آیا می‌خواهید اکنون سیستم را مجدداً راه‌اندازی کنید؟</string>
<string name="module_restore">بازیابی ماژول</string>
<string name="module_restore_message">ماژول‌ها را از نسخه پشتیبان اخیر بازیابی کنید.</string>
<string name="backup_restore">پشتیبان گیری &amp; بازیابی</string>
<string name="module_backup">پشتیبان گیری ماژول</string>
<string name="allowlist_restore">بازیابی لیست مجاز</string>
<string name="allowlist_restore_message">لیست مجاز را از نسخه پشتیبان اخیر بازیابی کنید.</string>
<string name="allowlist_backup">پشتیبان گیری لیست مجاز</string>
<string name="allowlist_backup_message">از لیست مجوزهای پیکربندی‌شده‌ی فعلی پشتیبان تهیه کنید.</string>
<string name="warning">هشدار</string>
<string name="warning_message">این ویژگی هنوز در مرحله بتا و در حال توسعه است. لطفاً قبل از ادامه، از ماژول‌های خود نسخه پشتیبان تهیه کنید. فقط در صورتی از این ویژگی استفاده کنید که خطرات احتمالی را درک می‌کنید. با احتیاط عمل کنید.</string>
<string name="proceed">ادامه</string>
<string name="cancel">لغو</string>
<string name="later">بعداً</string>
<string name="lkm_warning_message">پچ LKM به اجزای متن‌باز وابسته است. آیا می‌خواهید ادامه دهید؟</string>
<string name="home_next_kernelsu">🔥 نسخه بعدی</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">شاخه آزمایشی بعدی. آن را در گیت‌هاب بررسی کنید!</string>
<string name="home_experimental_kernelsu">⚠️ هشدار توسعه آزمایشی!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next یک نسخه غیر رسمی است که همیشه در حال توسعه آزمایشی فعال است. این نسخه به همین شکل ارائه می‌شود و هیچ تضمینی برای پایداری، عملکرد یا قابلیت اطمینان آن وجود ندارد.</string>
<string name="home_experimental_kernelsu_body_point_1"> • با مسئولیت خودتان استفاده کنید: ممکن است خرابی، رفتار غیرمنتظره یا مشکلات سیستم رخ دهد.</string>
<string name="home_experimental_kernelsu_body_point_2"> • بدون ضمانت: توسعه‌دهندگان هیچ مسئولیتی در قبال از دست رفتن داده‌ها، آسیب سیستم یا سایر عواقب ناشی از استفاده از آن ندارند.</string>
<string name="home_experimental_kernelsu_body_point_3"> • فقط برای اهداف آزمایشی: برای کاربرانی در نظر گرفته شده است که خطرات را درک می‌کنند و در عیب‌یابی مشکلات راحت هستند.</string>
<string name="about_source_code">نمایش کد منبع در %1$s</string>
<string name="profile">پروفایل برنامه</string>
<string name="profile_default">پیش‌فرض</string>
<string name="profile_template">الگو</string>
<string name="profile_custom">سفارشی</string>
<string name="profile_name">نام پروفایل</string>
<string name="profile_namespace">فضای نام mount</string>
<string name="profile_namespace_inherited">به ارث رسیده</string>
<string name="profile_namespace_global">جهانی</string>
<string name="profile_namespace_individual">فردی</string>
<string name="profile_groups">گروه‌ها</string>
<string name="profile_capabilities">قابلیت‌ها</string>
<string name="profile_selinux_context">زمینه SELinux</string>
<string name="profile_umount_modules">ماژول‌های نصب‌شده</string>
<string name="failed_to_update_app_profile">به‌روزرسانی نمایه برنامه برای %s ناموفق بود</string>
<string name="require_kernel_version">نسخه فعلی KernelSU Next %1$d برای عملکرد صحیح مدیریت، بسیار ضعیف است. لطفاً به نسخه %2$d یا بالاتر ارتقا دهید!</string>
<string name="settings_umount_modules_default">ماژول‌های نصب‌شده</string>
<string name="settings_umount_modules_default_summary">مقدار پیش‌فرض جهانی برای \"ماژول‌های نصب‌شده\" در پروفایل برنامه. در صورت فعال بودن، تمام تغییرات ماژول در سیستم را برای برنامه‌هایی که مجموعه پروفایل ندارند، حذف می‌کند.</string>
<string name="settings_susfs_toggle">هوک kprobes را مخفی کنید</string>
<string name="settings_susfs_toggle_summary">این گزینه هوک kprobes ایجاد شده توسط ksu را غیرفعال می‌کند و در عوض، هوک non-kprobes تعبیه شده را فعال می‌کند و همان عملکردی را که برای یک کرنل غیر GKI اعمال می‌شود، پیاده‌سازی می‌کند، کرنلی که از kprobe پشتیبانی نمی‌کند.</string>
<string name="profile_umount_modules_summary">فعال کردن این گزینه به KernelSU Next اجازه می‌دهد تا هرگونه فایل تغییر یافته توسط ماژول‌های این برنامه را بازیابی کند.</string>
<string name="profile_selinux_domain">دامنه</string>
<string name="profile_selinux_rules">قوانین</string>
<string name="module_update">بروزرسانی</string>
<string name="module_update_available">بروزرسانی</string>
<string name="module_updated">بروزرسانی شده</string>
<string name="module_downloading">درحال دانلود ماژول: %s</string>
<string name="module_start_downloading">شروع دانلود: %s</string>
<string name="new_version_available">نسخه جدید %s در دسترس است، برای ارتقا کلیک کنید.</string>
<string name="launch_app">اجرا</string>
<string name="close">بستن</string>
<string name="force_stop_app">توقف اجباری</string>
<string name="restart_app">راه‌اندازی مجدد</string>
<string name="settings_amoled_mode">حالت آمولد</string>
<string name="settings_amoled_mode_summary">یک تم مشکی خالص که برای صفحات آمولد مفید است را فعال کنید تا خستگی چشم کاهش یابد و باتری ذخیره شود.</string>
<string name="restart_required">راه‌اندازی مجدد مورد نیاز است</string>
<string name="restart_app_message">برای اعمال این تغییر، برنامه باید مجدداً راه‌اندازی شود.</string>
<string name="failed_to_update_sepolicy">به‌روزرسانی قوانین SELinux برای %s ناموفق بود</string>
<string name="su_not_allowed">نتوانستم به کاربر روت دسترسی به %s را بدم</string>
<string name="module_changelog">تغییرات</string>
<string name="settings_profile_template">الگوی پروفایل برنامه</string>
<string name="settings_profile_template_summary">مدیریت قالب محلی و آنلاین پروفایل برنامه</string>
<string name="app_profile_template_create">ایجاد الگو</string>
<string name="app_profile_template_edit">ویرایش الگو</string>
<string name="app_profile_template_id">آیدی</string>
<string name="app_profile_template_id_invalid">آیدی الگو نامعتبر است</string>
<string name="app_profile_template_name">نام</string>
<string name="app_profile_template_description">توضیحات</string>
<string name="app_profile_template_save">ذخیره</string>
<string name="app_profile_template_delete">حذف</string>
<string name="app_profile_template_view">مشاهده الگو</string>
<string name="app_profile_template_readonly">فقط خواندنی</string>
<string name="app_profile_template_id_exist">آیدی الگو از قبل وجود دارد!</string>
<string name="app_profile_import_export">ورودی/خروجی</string>
<string name="app_profile_import_from_clipboard">وارد کردن از کلیپ بورد</string>
<string name="app_profile_export_to_clipboard">خروجی گرفتن به کلیپ بورد</string>
<string name="app_profile_template_export_empty">الگوی محلی برای خروجی گرفتن پیدا نشد!</string>
<string name="app_profile_template_import_success">با موفقیت وارد شد</string>
<string name="app_profile_template_sync">همگام‌سازی قالب‌های آنلاین</string>
<string name="app_profile_template_save_failed">ذخیره الگو انجام نشد</string>
<string name="app_profile_template_import_empty">کلیپ بورد خالی است!</string>
<string name="module_changelog_failed">دریافت گزارش تغییرات ناموفق بود: %s</string>
<string name="settings_check_update">بررسی برای بروزرسانی</string>
<string name="settings_check_update_summary">بررسی خودکار به‌روزرسانی‌ها هنگام باز کردن برنامه</string>
<string name="grant_root_failed">دادن دسترسی روت ناموفق بود!</string>
<string name="action">اکشن</string>
<string name="webui">WebUI</string>
<string name="open">باز</string>
<string name="enable_web_debugging">اشکال‌زدایی WebView را فعال کنید</string>
<string name="enable_web_debugging_summary">می‌تواند برای اشکال‌زدایی رابط کاربری WebUI استفاده شود. لطفاً فقط در صورت نیاز فعال کنید.</string>
<string name="direct_install">نصب مستقیم (پیشنهادی)</string>
<string name="select_file">انتخاب فایل</string>
<string name="install_inactive_slot">نصب روی اسلات غیرفعال (بعد از OTA)</string>
<string name="install_inactive_slot_warning">دستگاه شما پس از راه‌اندازی مجدد **مجبور** خواهد بود که در اسلات غیرفعال فعلی بوت شود!\nفقط پس از انجام OTA از این گزینه استفاده کنید.\nادامه می‌دهید؟</string>
<string name="install_next">بعدی</string>
<string name="select_file_tip">تصویر پارتیشن %1$s توصیه می‌شود</string>
<string name="select_kmi">انتخاب KMI</string>
<string name="shrink_sparse_image">تصویر پراکنده را به حداقل برسانید</string>
<string name="shrink_sparse_image_message">تصویر پراکنده‌ای که ماژول در آن قرار دارد را به اندازه واقعی آن تغییر اندازه دهید. توجه داشته باشید که این کار ممکن است باعث شود ماژول به طور غیرعادی کار کند، بنابراین لطفاً فقط در صورت لزوم (مانند پشتیبان‌گیری) از آن استفاده کنید.</string>
<string name="settings_uninstall">حذف نصب</string>
<string name="settings_uninstall_temporary">حذف نصب موقت</string>
<string name="settings_uninstall_permanent">حذف نصب دائم</string>
<string name="settings_restore_stock_image">بازنشانی image استوک</string>
<string name="settings_uninstall_temporary_message">KernelSU را موقتاً حذف نصب کنید، سپس پس از راه‌اندازی مجدد بعدی، سیستم را به حالت اولیه بازگردانید.</string>
<string name="settings_uninstall_permanent_message">حذف کامل و دائمی KernelSU Next (روت و تمام ماژول‌ها).</string>
<string name="settings_restore_stock_image_message">بازیابی فایل ایمیج کارخانه (در صورت وجود نسخه پشتیبان) که معمولاً قبل از OTA استفاده می‌شود؛ اگر نیاز به حذف نصب KernelSU دارید، لطفاً از گزینه «حذف دائمی» استفاده کنید.</string>
<string name="flashing">درحال فلش کردن</string>
<string name="flash_success">فلش با موفقیت انجام شد</string>
<string name="flash_failed">فلش نشد</string>
<string name="selected_lkm">LKM انتخاب شده: %s</string>
<string name="save_log">ذخیره لاگ‌ها</string>
<string name="log_saved">لاگ‌ها ذخیره شدند</string>
<string name="send_log">اشتراک گذاری لاگ‌ها</string>
<string name="settings_disable_su">غیرفعال کردن سازگاری با su</string>
<string name="settings_disable_su_summary">به طور موقت توانایی هر برنامه‌ای را برای به دست آوردن امتیازات روت از طریق دستور SU غیرفعال کنید (فرآیندهای روت موجود تحت تأثیر قرار نمی‌گیرند)</string>
<string name="settings_language">زبان</string>
<string name="system_default">پیش فرض سیستم</string>
<string name="settings_legacyui">استفاده از Legacy UI</string>
<string name="settings_legacyui_summary">به سبک رابط کاربری قبلی تغییر دهید.</string>
<string name="settings_banner">فعال کردن بنرها</string>
<string name="settings_banner_summary">نمایش بنرهای پس‌زمینه برای ماژول‌ها.</string>
<string name="use_webuix">استفاده از WebUI X</string>
<string name="use_webuix_summary">به جای WebUI از WebUI X استفاده کنید که از APIهای بیشتری پشتیبانی می‌کند.</string>
<string name="use_webuix_eruda">تزریق Eruda به WebUI X</string>
<string name="use_webuix_eruda_summary">یک کنسول اشکال‌زدایی به WebUI X تزریق کنید تا اشکال‌زدایی آسان‌تر شود. لازم است اشکال‌زدایی وب فعال باشد.</string>
<string name="customization">سفارشی‌سازی</string>
<string name="developer">توسعه دهنده</string>
<string name="sucompat_disabled">SUCOMPAT غیرفعال شده</string>
<string name="zygisk_required">نیازمند Zygisk</string>
<string name="zygisk_status">تزریق Zygisk</string>
<string name="home_superuser_count_singular">کاربر روت</string>
<string name="home_superuser_count_plural">کاربر های روت</string>
<string name="home_module_count_singular">ماژول</string>
<string name="home_module_count_plural">ماژول ها</string>
<string name="module_backup_message">از ماژول‌های نصب‌شده‌ی فعلی پشتیبان تهیه کنید.</string>
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
<string name="module_sort_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI first)</string>
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
</resources>

View File

@@ -1,197 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">مشکلی دارید؟</string>
<string name="issue_report_body">با خطا مواجه شده‌اید یا نظری دارید؟</string>
<string name="issue_report_body_2">هرچه زودتر گزارش دهید!</string>
<string name="issue_report_github">گزارش در گیت‌هاب</string>
<string name="issue_report_telegram">تماس از طریق تلگرام</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">تأیید</string>
<string name="app_name" translatable="false">KernelSU Next</string>
<string name="home">خانه</string>
<string name="home_not_installed">نصب نشده</string>
<string name="home_click_to_install">برای نصب کلیک کنید</string>
<string name="home_working">در حال کار</string>
<string name="home_working_version">نسخه: %d</string>
<string name="home_superuser_count">کاربران ویژه: %d</string>
<string name="home_module_count">ماژول‌ها: %d</string>
<string name="home_failure">امضای KernelSU Next v2 در هسته یافت نشد! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">از توسعه‌دهنده هسته خود بخواهید KernelSU Next را یکپارچه کند!</string>
<string name="home_kernel">نسخه هسته</string>
<string name="enabled">فعال</string>
<string name="disabled">غیرفعال</string>
<string name="susfs_supported">پشتیبانی‌شده</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">نسخه SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">نسخه اندروید</string>
<string name="home_manager_version">نسخه مدیر</string>
<string name="home_selinux_status">وضعیت SELinux</string>
<string name="selinux_status_disabled">غیرفعال</string>
<string name="selinux_status_enforcing">اجباری</string>
<string name="selinux_status_permissive">مجاز</string>
<string name="selinux_status_unknown">ناشناخته</string>
<string name="superuser">کاربر ویژه</string>
<string name="module_failed_to_enable">فعال‌سازی ماژول شکست خورد: %s</string>
<string name="module_failed_to_disable">غیرفعال‌سازی ماژول شکست خورد: %s</string>
<string name="module_empty">هیچ ماژولی نصب نشده</string>
<string name="module">ماژول</string>
<string name="module_install_prompt_with_name">ماژول(های) زیر نصب خواهد شد: %1$s</string>
<string name="module_sort_a_to_z">مرتب‌سازی (الف-ی)</string>
<string name="module_sort_z_to_a">مرتب‌سازی (ی-الف)</string>
<string name="uninstall">حذف نصب</string>
<string name="restore">بازیابی</string>
<string name="module_install">نصب</string>
<string name="install">نصب</string>
<string name="reboot">راه‌اندازی مجدد</string>
<string name="settings">تنظیمات</string>
<string name="reboot_userspace">راه‌اندازی نرم</string>
<string name="reboot_recovery">راه‌اندازی به حالت ریکاوری</string>
<string name="reboot_bootloader">راه‌اندازی به حالت بوت‌لودر</string>
<string name="reboot_download">راه‌اندازی به حالت دانلود</string>
<string name="reboot_edl">راه‌اندازی به حالت EDL</string>
<string name="about">درباره</string>
<string name="module_uninstall_confirm">آیا مطمئن هستید که می‌خواهید ماژول %s را حذف کنید؟</string>
<string name="module_uninstall_success">ماژول %s حذف شد</string>
<string name="module_uninstall_failed">حذف ماژول شکست خورد: %s</string>
<string name="module_restore_confirm">آیا مطمئن هستید که می‌خواهید ماژول %s را بازیابی کنید؟</string>
<string name="module_restore_success">ماژول %s بازیابی شد</string>
<string name="module_restore_failed">بازیابی ماژول شکست خورد: %s</string>
<string name="module_version">نسخه</string>
<string name="module_author">سازنده</string>
<string name="module_id">شناسه</string>
<string name="module_version_code">کد نسخه</string>
<string name="module_update_json">به‌روزرسانی JSON</string>
<string name="module_update_json_empty">خالی</string>
<string name="enable_developer_options">فعال‌سازی گزینه‌های توسعه‌دهنده</string>
<string name="enable_developer_options_summary">نمایش تنظیمات مخفی و اطلاعات اشکال‌زدایی که فقط برای توسعه‌دهندگان مفید است.</string>
<string name="module_overlay_fs_not_available">ماژول‌ها به دلیل غیرفعال بودن OverlayFS توسط هسته در دسترس نیستند.</string>
<string name="refresh">تازه‌سازی</string>
<string name="show_system_apps">نمایش برنامه‌های سیستمی</string>
<string name="hide_system_apps">پنهان کردن برنامه‌های سیستمی</string>
<string name="export_log">صدور گزارش‌ها</string>
<string name="safe_mode">حالت ایمن</string>
<string name="reboot_to_apply">برای اعمال تغییرات راه‌اندازی مجدد کنید</string>
<string name="module_magisk_conflict">ماژول‌ها به دلیل تداخل با Magisk در دسترس نیستند!</string>
<string name="home_mount_system">نصب سیستم</string>
<string name="home_magic_mount">نصب جادویی</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">در دسترس نیست</string>
<string name="use_overlay_fs">استفاده از OverlayFS</string>
<string name="use_overlay_fs_summary">تغییر بین استفاده از OverlayFS و نصب جادویی برای سیستم نصب KernelSU Next.</string>
<string name="reboot_required">نیاز به راه‌اندازی مجدد</string>
<string name="reboot_message">تغییرات پس از راه‌اندازی مجدد سیستم اعمال می‌شوند. آیا می‌خواهید اکنون راه‌اندازی کنید؟</string>
<string name="module_restore">بازیابی ماژول</string>
<string name="module_restore_message">بازیابی ماژول‌ها از آخرین نسخه پشتیبان.</string>
<string name="backup_restore">پشتیبان‌گیری و بازیابی</string>
<string name="module_backup">پشتیبان‌گیری از ماژول</string>
<string name="module_backup_message">پشتیبان‌گیری از ماژول‌های نصب‌شده کنونی.</string>
<string name="allowlist_restore">بازیابی لیست مجاز</string>
<string name="allowlist_restore_message">بازیابی لیست مجاز از آخرین نسخه پشتیبان.</string>
<string name="allowlist_backup">پشتیبان‌گیری از لیست مجاز</string>
<string name="allowlist_backup_message">پشتیبان‌گیری از لیست مجاز کنونی.</string>
<string name="warning">هشدار</string>
<string name="warning_message">این ویژگی هنوز در مرحله آزمایشی و در حال توسعه است. لطفاً پیش از ادامه، از ماژول‌های خود نسخه پشتیبان تهیه کنید. این ویژگی را تنها در صورتی استفاده کنید که خطرات احتمالی را درک کرده باشید. با احتیاط ادامه دهید.</string>
<string name="proceed">ادامه</string>
<string name="cancel">لغو</string>
<string name="later">بعداً</string>
<string name="home_next_kernelsu">🔥 ساخت بعدی</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">شاخه آزمایشی بعدی. آن را در گیت‌هاب بررسی کنید!</string>
<string name="home_experimental_kernelsu">⚠️ هشدار توسعه آزمایشی!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next نسخه‌ای غیررسمی است که همیشه در حال توسعه آزمایشی فعال است. این نسخه همان‌گونه که هست ارائه می‌شود، بدون تضمین پایداری، عملکرد یا قابلیت اطمینان.</string>
<string name="home_experimental_kernelsu_body_point_1"> • استفاده با مسئولیت خودتان: ممکن است با خرابی، رفتار غیرمنتظره یا مشکلات سیستمی مواجه شوید.</string>
<string name="home_experimental_kernelsu_body_point_2"> • بدون گارانتی: توسعه‌دهندگان مسئول هیچ‌گونه از دست دادن داده، آسیب به سیستم یا سایر پیامدها نیستند.</string>
<string name="home_experimental_kernelsu_body_point_3"> • فقط برای آزمایش: برای کاربرانی که خطرات را درک کرده و با عیب‌یابی راحت هستند.</string>
<string name="about_source_code"><![CDATA[مشاهده کد منبع در %1$s]]></string>
<string name="profile" translatable="false">پروفایل برنامه</string>
<string name="profile_default">پیش‌فرض</string>
<string name="profile_template">الگو</string>
<string name="profile_custom">سفارشی</string>
<string name="profile_name">نام پروفایل</string>
<string name="profile_namespace">فضای نصب</string>
<string name="profile_namespace_inherited">ارثی</string>
<string name="profile_namespace_global">جهانی</string>
<string name="profile_namespace_individual">فردی</string>
<string name="profile_groups">گروه‌ها</string>
<string name="profile_capabilities">قابلیت‌ها</string>
<string name="profile_selinux_context">زمینه SELinux</string>
<string name="profile_umount_modules">حذف ماژول‌ها</string>
<string name="failed_to_update_app_profile">به‌روزرسانی پروفایل برنامه برای %s شکست خورد</string>
<string name="require_kernel_version">نسخه کنونی KernelSU Next %1$d برای عملکرد صحیح مدیر بسیار پایین است. لطفاً به نسخه %2$d یا بالاتر ارتقا دهید!</string>
<string name="settings_umount_modules_default">حذف پیش‌فرض ماژول‌ها</string>
<string name="settings_umount_modules_default_summary">مقدار پیش‌فرض جهانی برای «حذف ماژول‌ها» در پروفایل برنامه. اگر فعال باشد، تمام تغییرات سیستمی ماژول‌ها برای برنامه‌هایی که پروفایل ندارند حذف می‌شود.</string>
<string name="settings_susfs_toggle">مخفی کردن قلاب‌های kprobe</string>
<string name="settings_susfs_toggle_summary">این گزینه قلاب‌های kprobe ایجادشده توسط ksu را غیرفعال کرده و به‌جای آن، قلاب‌های غیر kprobe داخلی را فعال می‌کند که همان عملکرد را برای هسته‌های غیر GKI که از kprobe پشتیبانی نمی‌کنند، پیاده‌سازی می‌کند.</string>
<string name="profile_umount_modules_summary">فعال کردن این گزینه به KernelSU Next اجازه می‌دهد فایل‌های تغییر یافته توسط ماژول‌ها را برای این برنامه بازیابی کند.</string>
<string name="profile_selinux_domain">دامنه</string>
<string name="profile_selinux_rules">قوانین</string>
<string name="module_update">به‌روزرسانی</string>
<string name="module_downloading">در حال دانلود ماژول: %s</string>
<string name="module_start_downloading">شروع دانلود: %s</string>
<string name="new_version_available">نسخه جدید %s در دسترس است، برای ارتقا کلیک کنید.</string>
<string name="launch_app">اجرا</string>
<string name="close">بستن</string>
<string name="force_stop_app">توقف اجباری</string>
<string name="restart_app">راه‌اندازی مجدد</string>
<string name="failed_to_update_sepolicy">به‌روزرسانی قوانین SELinux برای %s شکست خورد</string>
<string name="su_not_allowed">اعطای دسترسی ویژه برای %s مجاز نیست</string>
<string name="module_changelog">تغییرات</string>
<string name="settings_profile_template">الگوی پروفایل برنامه</string>
<string name="settings_profile_template_summary">مدیریت الگوهای محلی و آنلاین پروفایل برنامه</string>
<string name="app_profile_template_create">ایجاد الگو</string>
<string name="app_profile_template_edit">ویرایش الگو</string>
<string name="app_profile_template_id">شناسه</string>
<string name="app_profile_template_id_invalid">شناسه الگو نامعتبر است</string>
<string name="app_profile_template_name">نام</string>
<string name="app_profile_template_description">توضیحات</string>
<string name="app_profile_template_save">ذخیره</string>
<string name="app_profile_template_delete">حذف</string>
<string name="app_profile_template_view">مشاهده الگو</string>
<string name="app_profile_template_readonly">فقط خواندنی</string>
<string name="app_profile_template_id_exist">شناسه الگو قبلاً وجود دارد!</string>
<string name="app_profile_import_export">واردات/صادرات</string>
<string name="app_profile_import_from_clipboard">واردات از کلیپ‌بورد</string>
<string name="app_profile_export_to_clipboard">صادرات به کلیپ‌بورد</string>
<string name="app_profile_template_export_empty">هیچ الگوی محلی برای صادرات یافت نشد!</string>
<string name="app_profile_template_import_success">با موفقیت وارد شد</string>
<string name="app_profile_template_sync">همگام‌سازی الگوهای آنلاین</string>
<string name="app_profile_template_save_failed">ذخیره الگو شکست خورد</string>
<string name="app_profile_template_import_empty">کلیپ‌بورد خالی است!</string>
<string name="module_changelog_failed">دریافت تغییرات شکست خورد: %s</string>
<string name="settings_check_update">بررسی به‌روزرسانی</string>
<string name="settings_check_update_summary">بررسی خودکار به‌روزرسانی‌ها هنگام باز کردن برنامه.</string>
<string name="grant_root_failed">اعطای دسترسی ریشه شکست خورد!</string>
<string name="action">اقدام</string>
<string name="open">باز کردن</string>
<string name="enable_web_debugging">فعال‌سازی اشکال‌زدایی وب‌ویو</string>
<string name="enable_web_debugging_summary">می‌تواند برای اشکال‌زدایی رابط وب استفاده شود. لطفاً فقط در صورت نیاز فعال کنید.</string>
<string name="direct_install">نصب مستقیم (توصیه‌شده)</string>
<string name="select_file">انتخاب فایل</string>
<string name="install_inactive_slot">نصب در اسلات غیرفعال (پس از OTA)</string>
<string name="install_inactive_slot_warning">دستگاه شما پس از راه‌اندازی مجدد **اجباراً** به اسلات غیرفعال کنونی بوت خواهد شد!\nفقط پس از انجام OTA از این گزینه استفاده کنید.\nادامه می‌دهید؟</string>
<string name="install_next">بعدی</string>
<string name="select_file_tip">تصویر پارتیشن %1$s توصیه می‌شود</string>
<string name="select_kmi">انتخاب KMI</string>
<string name="shrink_sparse_image">کاهش اندازه تصویر پراکنده</string>
<string name="shrink_sparse_image_message">تغییر اندازه تصویر پراکنده‌ای که ماژول در آن قرار دارد به اندازه واقعی آن. توجه داشته باشید که این ممکن است باعث عملکرد غیرعادی ماژول شود، بنابراین فقط در صورت نیاز (مانند پشتیبان‌گیری) استفاده کنید.</string>
<string name="settings_uninstall">حذف نصب</string>
<string name="settings_uninstall_temporary">حذف نصب موقت</string>
<string name="settings_uninstall_permanent">حذف نصب دائمی</string>
<string name="settings_restore_stock_image">بازیابی تصویر اصلی</string>
<string name="settings_uninstall_temporary_message">حذف موقت KernelSU Next، بازگشت به حالت اولیه پس از راه‌اندازی بعدی.</string>
<string name="settings_uninstall_permanent_message">حذف کامل و دائمی KernelSU Next (ریشه و همه ماژول‌ها).</string>
<string name="settings_restore_stock_image_message">بازیابی تصویر کارخانه‌ای (در صورت وجود نسخه پشتیبان)، معمولاً قبل از OTA استفاده می‌شود؛ اگر نیاز به حذف KernelSU Next دارید، لطفاً از «حذف نصب دائمی» استفاده کنید.</string>
<string name="flashing">در حال فلش</string>
<string name="flash_success">فلش موفق</string>
<string name="flash_failed">فلش ناموفق</string>
<string name="selected_lkm">LKM انتخاب‌شده: %s</string>
<string name="save_log">ذخیره گزارش‌ها</string>
<string name="log_saved">گزارش‌ها ذخیره شدند</string>
<string name="send_log">اشتراک گزارش‌ها</string>
<string name="settings_disable_su">غیرفعال کردن سازگاری su</string>
<string name="settings_disable_su_summary">غیرفعال کردن موقت توانایی هر برنامه برای کسب دسترسی ریشه از طریق دستور su (فرآیندهای ریشه موجود تحت تأثیر قرار نمی‌گیرند).</string>
<string name="settings_language">زبان</string>
</resources>

View File

@@ -0,0 +1,238 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">Un problème ?</string>
<string name="issue_report_body">Vous avez rencontré un bug ou avez un commentaire ?</string>
<string name="issue_report_body_2">Signalez-le dès que possible !</string>
<string name="issue_report_github">Reportez sur GitHub</string>
<string name="issue_report_telegram">Contact par Telegram</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Confirmer</string>
<string name="app_name">KernelSU Next</string>
<string name="home">Accueil</string>
<string name="home_not_installed">Pas installé</string>
<string name="home_click_to_install">Cliquez pour installer</string>
<string name="lkm_mode_deprecated">Le mode LKM est désormais obsolète !</string>
<string name="lkm_alternative_suggestion">Installez un noyau GKI ou intégrez KernelSU Next a votre appareil.</string>
<string name="home_working">En fonctionnement</string>
<string name="home_working_version">Version : %d</string>
<string name="home_module_update_count">Mises à jour : %d</string>
<string name="home_failure">La signature suivante de la v2 KernelSU Next est introuvable dans le noyau! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">Demandez à votre développeur de noyau d\'intégrer KernelSU Next !</string>
<string name="home_kernel">Version du noyau</string>
<string name="hook_mode">Méthode d\'interception</string>
<string name="enable">Activer</string>
<string name="disable">Désactiver</string>
<string name="enabled">Activé</string>
<string name="disabled">Désactivé</string>
<string name="susfs_supported">Supporté</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">Version de SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Version d\'Android</string>
<string name="home_manager_version">Version du gestionnaire</string>
<string name="home_abi">IBA</string>
<string name="home_selinux_status">Statut de SELinux</string>
<string name="selinux_status_disabled">Désactivé</string>
<string name="selinux_status_enforcing">Strict</string>
<string name="selinux_status_permissive">Permissif</string>
<string name="selinux_status_unknown">Inconnu</string>
<string name="superuser">Super utilisateur</string>
<string name="module_failed_to_enable">Échec de l\'activation du module : %s</string>
<string name="module_failed_to_disable">Échec de la désactivation du module : %s</string>
<string name="module_empty">Aucun module installé</string>
<string name="module">Module</string>
<string name="module_install_prompt_with_name">Les modules suivants seront installés : %1$s</string>
<string name="module_sort_a_to_z">Trier (A → Z)</string>
<string name="module_sort_z_to_a">Trier (Z → A)</string>
<string name="module_size_low_to_high">Trier (Léger → Lourd)</string>
<string name="module_size_high_to_low">Trier (Lourd → Léger)</string>
<string name="uninstall">Désinstaller</string>
<string name="restore">Restaurer</string>
<string name="module_install">Installer</string>
<string name="install">Installer</string>
<string name="reboot">Redémarrer </string>
<string name="uninstalled">Désinstallé</string>
<string name="settings">Paramètres</string>
<string name="reboot_userspace">Redémarrage rapide</string>
<string name="reboot_recovery">Redémarrer en mode Recovery</string>
<string name="reboot_bootloader">Redémarrage dans le bootloader</string>
<string name="reboot_download">Redémarrer pour télécharger</string>
<string name="reboot_edl">Redémarrer en mode EDL</string>
<string name="about">À propos</string>
<string name="module_uninstall_confirm">Êtes-vous sûr de vouloir désinstaller le module %s\ ?</string>
<string name="module_uninstall_success">%s désinstallé</string>
<string name="module_uninstall_failed">Échec de la désinstallation : %s</string>
<string name="module_restore_confirm">Voulez-vous vraiment restaurer le module %s?</string>
<string name="module_restore_success">%s restauré</string>
<string name="module_restore_failed">Échec de la restauration : %s</string>
<string name="module_version">Version</string>
<string name="module_author">Auteur</string>
<string name="module_id">ID</string>
<string name="module_version_code">Code</string>
<string name="module_update_json">Mise à jour Json</string>
<string name="module_update_json_empty">Vide</string>
<string name="enable_developer_options">Activer les options de développeur</string>
<string name="enable_developer_options_summary">Afficher les paramètres cachés et les informations de débogage uniquement pour les développeurs.</string>
<string name="module_overlay_fs_not_available">Les modules sont indisponibles car OverlayFS est désactivé par le noyau !</string>
<string name="refresh">Actualiser</string>
<string name="show_system_apps">Afficher les applications système</string>
<string name="hide_system_apps">Masquer les applis système</string>
<string name="export_log">Exporter les logs</string>
<string name="safe_mode">Mode sans échec</string>
<string name="reboot_to_apply">Redémarrer pour prendre effet</string>
<string name="module_magisk_conflict">Les modules sont indisponibles en raison d\'un conflit avec Magisk!</string>
<string name="home_mount_system">Monter le système</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Indisponible</string>
<string name="use_overlay_fs">Utiliser OverlayFS</string>
<string name="use_overlay_fs_summary">Basculer entre l\'utilisation de OverlayFS sur Magic Mount pour le système de montage de KernelSU Next.</string>
<string name="reboot_required">Redémarrage nécessaire</string>
<string name="reboot_message">Les changements prendront effet après le redémarrage du système. Voulez-vous redémarrer maintenant ?</string>
<string name="module_restore">Rétablir le module</string>
<string name="module_restore_message">Restaurer les modules de la sauvegarde récente.</string>
<string name="backup_restore">Sauvegarder &amp; Restaurer</string>
<string name="module_backup">Modules de sauvegarde</string>
<string name="allowlist_restore">Restaurer la liste d\'autorisations</string>
<string name="allowlist_restore_message">Restaurer la liste d\'autorisations à partir de la sauvegarde récente.</string>
<string name="allowlist_backup">Sauvegarde de la liste d\'autorisations</string>
<string name="allowlist_backup_message">Sauvegarde de la liste d\'autorisations configurée.</string>
<string name="warning">Attention</string>
<string name="warning_message">Cette fonctionnalité est encore en version bêta et en cours de développement. Veillez à sauvegarder vos modules avant de procéder. N\'utilisez cette fonctionnalité que si vous comprenez les risques potentiels. Procédez avec prudence.</string>
<string name="proceed">Procéder</string>
<string name="cancel">Annuler</string>
<string name="later">Plus tard</string>
<string name="lkm_warning_message">Le correctif LKM repose sur des composants en source fermée. Voulez-vous continuer ?</string>
<string name="home_next_kernelsu">🔥 Prochaine version</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Prochaine branche expérimentale. Consultez-la sur GitHub !</string>
<string name="home_experimental_kernelsu">⚠️ Avertissement concernant le développement expérimental !</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next est une version non officielle qui fait toujours l\'objet d\'un développement expérimental actif. Elle est fournie telle quelle, sans garantie de stabilité, de performance ou de fiabilité.</string>
<string name="home_experimental_kernelsu_body_point_1"> • L\'utilisation est à vos risques et périls : des pannes, des comportements inattendus ou des problèmes de système peuvent survenir.</string>
<string name="home_experimental_kernelsu_body_point_2"> • Aucune garantie : les développeurs ne sont pas responsables des pertes de données, des dommages du système ou d\'autres conséquences résultant de son utilisation.</string>
<string name="home_experimental_kernelsu_body_point_3"> • À des fins de test uniquement : destiné aux utilisateurs qui comprennent les risques et sont à l\'aise avec le dépannage des problèmes.</string>
<string name="about_source_code">Afficher le code source sur %1$s</string>
<string name="profile">App Profile</string>
<string name="profile_default">Défaut</string>
<string name="profile_template">Modèle</string>
<string name="profile_custom">Personnaliser</string>
<string name="profile_name">Nom du profil</string>
<string name="profile_namespace">Espace de noms du montage</string>
<string name="profile_namespace_inherited">Hériter</string>
<string name="profile_namespace_global">Global</string>
<string name="profile_namespace_individual">Individuel</string>
<string name="profile_groups">Groupes</string>
<string name="profile_capabilities">Fonctionnalités</string>
<string name="profile_selinux_context">Contexte SELinux</string>
<string name="profile_umount_modules">Démonter les modules</string>
<string name="failed_to_update_app_profile">Échec de la modification du profil d\'application de %s</string>
<string name="require_kernel_version">La version actuelle de KernelSU (%d) est trop ancienne pour que le gestionnaire fonctionne correctement. Veuillez passer à la version %d ou à une version supérieure!</string>
<string name="settings_umount_modules_default">Démonter les modules</string>
<string name="settings_umount_modules_default_summary">La valeur par défaut globale pour « Démonter les modules » dans le profil de l\'application. Si activé, cela supprimera toutes les modifications de modules sur le système pour les applications qui n\'ont pas de profil défini.</string>
<string name="settings_susfs_toggle">Cacher l\'interception kprobes</string>
<string name="settings_susfs_toggle_summary">Cette option désactive l\'interception kprobes créé par ksu et, à la place, active l\'interception non-kpropes intégré, implémentant les mêmes fonctionnalités qui seraient appliquées à un noyau non GKI, qui ne supporte pas kprobe.</string>
<string name="profile_umount_modules_summary">Activer cette option permettra à KernelSU Next de restaurer tous les fichiers modifiés par les modules pour cette application.</string>
<string name="profile_selinux_domain">Domaine</string>
<string name="profile_selinux_rules">Règles</string>
<string name="module_update">Mettre à jour</string>
<string name="module_update_available">Mettre à jour</string>
<string name="module_updated">Mise à jour</string>
<string name="module_downloading">Téléchargement du module : %s</string>
<string name="module_start_downloading">Démarrage du téléchargement de %s</string>
<string name="new_version_available">La nouvelle version %s est disponible, appuyez ici pour mettre à jour.</string>
<string name="launch_app">Lancer</string>
<string name="close">Fermer</string>
<string name="force_stop_app">Forcer l\'arrêt</string>
<string name="restart_app">Redémarrer</string>
<string name="settings_amoled_mode">Mode AMOLED</string>
<string name="settings_amoled_mode_summary">Activez un thème noir pur et utile pour les écrans AMOLED pour réduire la fatigue oculaire et économiser la batterie.</string>
<string name="restart_required">Redémarrage nécessaire</string>
<string name="restart_app_message">L\'application doit redémarrer pour que ce changement prenne effet.</string>
<string name="failed_to_update_sepolicy">Échec de la mise à jour des règles SELinux pour %s</string>
<string name="su_not_allowed">Impossible d\'autoriser l\'accès Super-utilisateur à %s</string>
<string name="module_changelog">Journal de modifications</string>
<string name="settings_profile_template">Modèles de profils d\'application</string>
<string name="settings_profile_template_summary">Gérer le modèle local et en ligne du profil de l\'application</string>
<string name="app_profile_template_create">Créer un modèle</string>
<string name="app_profile_template_edit">Modifier le modèle</string>
<string name="app_profile_template_id">ID</string>
<string name="app_profile_template_id_invalid">ID du modèle invalide</string>
<string name="app_profile_template_name">Nom</string>
<string name="app_profile_template_description">Description</string>
<string name="app_profile_template_save">Sauvegarder</string>
<string name="app_profile_template_delete">Supprimer</string>
<string name="app_profile_template_view">Voir le modèle</string>
<string name="app_profile_template_readonly">En lecture seule</string>
<string name="app_profile_template_id_exist">L\'ID du modèle existe déjà !</string>
<string name="app_profile_import_export">Importer/Exporter</string>
<string name="app_profile_import_from_clipboard">Importer depuis le presse-papiers</string>
<string name="app_profile_export_to_clipboard">Exporter dans le presse-papiers</string>
<string name="app_profile_template_export_empty">Impossible de trouver un modèle local à exporter !</string>
<string name="app_profile_template_import_success">Importé avec succès</string>
<string name="app_profile_template_sync">Synchroniser les modèles en ligne</string>
<string name="app_profile_template_save_failed">Échec de la sauvegarde du modèle</string>
<string name="app_profile_template_import_empty">Le presse-papiers est vide !</string>
<string name="module_changelog_failed">La récupération du journal des modifications a échoué : %s</string>
<string name="settings_check_update">Vérifier les mises à jour</string>
<string name="settings_check_update_summary">Vérifier automatiquement les mises à jour à l\'ouverture de l\'application</string>
<string name="grant_root_failed">Échec de l\'octroi des privilèges root!</string>
<string name="action">Action</string>
<string name="webui">WebUI</string>
<string name="open">Ouvrir</string>
<string name="enable_web_debugging">Activer le débogage WebView</string>
<string name="enable_web_debugging_summary">Peut être utilisé pour déboguer WebUI, n\'activez cette option que si nécessaire.</string>
<string name="direct_install">Installation directe (Recommandé)</string>
<string name="select_file">Sélectionner un fichier</string>
<string name="install_inactive_slot">Installer dans un slot inactif (After OTA)</string>
<string name="install_inactive_slot_warning">Votre appareil sera **FORCÉ** à démarrer sur l\'emplacement inactif actuel après un redémarrage!
\nN\'utilisez cette option qu\'une fois la mise à jour OTA terminée.
\nContinuer?</string>
<string name="install_next">Suivant</string>
<string name="select_file_tip">L\'image de la partition %1$s est recommandée</string>
<string name="select_kmi">Sélectionnez un KMI</string>
<string name="shrink_sparse_image">Minimiser la taille de l\'image sparse</string>
<string name="shrink_sparse_image_message">Redimensionne l\'image sparse où le module est situé à sa taille réelle. Notez que cela peut entraîner un dysfonctionnement du module, veuillez utiliser cette option uniquement lorsque cela est nécessaire (par exemple pour la sauvegarde de l\'appareil).</string>
<string name="settings_uninstall">Désinstaller</string>
<string name="settings_uninstall_temporary">Désinstaller temporairement</string>
<string name="settings_uninstall_permanent">Désinstaller définitivement</string>
<string name="settings_restore_stock_image">Restaurer l\'image d\'origine</string>
<string name="settings_uninstall_temporary_message">Désinstallez temporairement KernelSU Next, restaurez l\'état d\'origine après le prochain redémarrage.</string>
<string name="settings_uninstall_permanent_message">Désinstallation complète et permanente de KernelSU Next (Root et de tous les modules).</string>
<string name="settings_restore_stock_image_message">Restaurer l\'image d\'usine d\'origine (si une sauvegarde existe), généralement utilisée avant OTA; si vous avez besoin de désinstaller KernelSU Next, veuillez utiliser \"Désinstaller définitivement\".</string>
<string name="flashing">Flash en cours</string>
<string name="flash_success">Flash réussi</string>
<string name="flash_failed">Échec du flash</string>
<string name="selected_lkm">LKM sélectionné: %s</string>
<string name="save_log">Enregistrer les journaux (logs)</string>
<string name="log_saved">Journaux (logs) enregistrés</string>
<string name="send_log">Partager les journaux (logs)</string>
<string name="settings_disable_su">Désactiver la compatibilité su</string>
<string name="settings_disable_su_summary">Désactivez temporairement la capacité de n\'importe quelle application à obtenir les privilèges root via la commande su (Les processus root existants ne seront pas affectés).</string>
<string name="settings_language">Langue</string>
<string name="system_default">Valeurs par défaut du système</string>
<string name="settings_legacyui">Utiliser l\'ancienne interface utilisateur</string>
<string name="settings_legacyui_summary">Basculez vers le style de l\'interface utilisateur précédent.</string>
<string name="settings_banner">Activer les bannières</string>
<string name="settings_banner_summary">Afficher les bannières d\'arrière-plan pour les modules.</string>
<string name="use_webuix">Utiliser WebUI X</string>
<string name="use_webuix_summary">Utiliser WebUI X au lieu de WebUI, qui prend en charge d\'avantage d\'API.</string>
<string name="use_webuix_eruda">Injecter Eruda dans WebUI X</string>
<string name="use_webuix_eruda_summary">Injecter une console de débogage dans WebUI X pour déboguer plus facilement. Le débogage web doit être activé.</string>
<string name="customization">Customisation</string>
<string name="developer">Développeur</string>
<string name="sucompat_disabled">SUCOMPAT DÉACTIVÉ</string>
<string name="zygisk_required">Zygisk requis</string>
<string name="zygisk_status">Injection de Zygisk</string>
<string name="home_superuser_count_singular">Super-utilisateur</string>
<string name="home_superuser_count_plural">Super-utilisateurs</string>
<string name="home_module_count_singular">Module</string>
<string name="home_module_count_plural">Modules</string>
<string name="module_backup_message">Sauvegarder les modules actuellement installés.</string>
<string name="module_sort_enabled_first">Trier (Activé en premier)</string>
<string name="module_sort_action_first">Trier (Action en premier)</string>
<string name="module_sort_webui_first">Trier (WebUI en premier)</string>
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
</resources>

View File

@@ -1,188 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">Un souci ?</string>
<string name="issue_report_body">Vous avez rencontré un bug ou avez des retours ?</string>
<string name="issue_report_body_2">Signalez-le dès que possible !</string>
<string name="issue_report_github">Signaler sur GitHub</string>
<string name="issue_report_telegram">Contacter via Telegram</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Confirmer</string>
<string name="app_name" translatable="false">KernelSU Next</string>
<string name="home">Menu</string>
<string name="home_not_installed">Non installé</string>
<string name="home_click_to_install">Cliquer pour installer</string>
<string name="home_working">Fonctionnel</string>
<string name="home_working_version">Version: %d</string>
<string name="home_superuser_count">Superutilisateurs: %d</string>
<string name="home_module_count">Modules: %d</string>
<string name="home_failure">Signature KernelSU Next v2 introuvable dans le kernel! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">Demandez au développeur de votre kernel d\'intégrer KernelSU Next!</string>
<string name="home_kernel">Version du kernel</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">Version de SuSFS</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Version d\'Android</string>
<string name="home_manager_version">Version du manager</string>
<string name="home_selinux_status">Statut SELinux</string>
<string name="selinux_status_disabled">Désactivé</string>
<string name="selinux_status_enforcing">Appliqué</string>
<string name="selinux_status_permissive">Permissif</string>
<string name="selinux_status_unknown">Inconnu</string>
<string name="superuser">Super Utilisateur</string>
<string name="module_failed_to_enable">Échec de l\'activation du module: %s</string>
<string name="module_failed_to_disable">Échec de la désactivation du module: %s</string>
<string name="module_empty">Aucun module installé</string>
<string name="module">Module</string>
<string name="module_install_prompt_with_name">Voulez-vous continuer à installer le module %1$s?</string>
<string name="module_sort_a_to_z">Trier (A-Z)</string>
<string name="module_sort_z_to_a">Trier (Z-A)</string>
<string name="uninstall">Désinstaller</string>
<string name="restore">Restaurer</string>
<string name="module_install">Installer</string>
<string name="install">Installer</string>
<string name="reboot">Redémarrer</string>
<string name="settings">Paramètres</string>
<string name="reboot_userspace">Redémarrage logiciel</string>
<string name="reboot_recovery">Redémarrer en mode Recovery</string>
<string name="reboot_bootloader">Redémarrer en mode Bootloader</string>
<string name="reboot_download">Redémarrer en mode téléchargement</string>
<string name="reboot_edl">Redémarrer en mode EDL</string>
<string name="about">À propos</string>
<string name="module_uninstall_confirm">Êtes-vous sûr de vouloir désinstaller le module %s?</string>
<string name="module_uninstall_success">%s a été désinstallé</string>
<string name="module_uninstall_failed">Échec de la désinstallation: %s</string>
<string name="module_restore_confirm">Êtes-vous sûr de vouloir restaurer le module %s?</string>
<string name="module_restore_success">%s a été restauré</string>
<string name="module_restore_failed">Échec de la restoration: %s</string>
<string name="module_version">Version</string>
<string name="module_author">Auteur</string>
<string name="enable_developer_options">Activer les options pour les développeurs</string>
<string name="enable_developer_options_summary">Afficher des paramètres cachés et des information de débogage seulement utiles pour les développeurs.</string>
<string name="module_overlay_fs_not_available">Les modules sont indisponibles car OverlayFS est désactivé par le kernel.</string>
<string name="refresh">Rafraîchir</string>
<string name="show_system_apps">Montrer les apps système</string>
<string name="hide_system_apps">Cacher les apps système</string>
<string name="export_log">Exporter les logs</string>
<string name="safe_mode">Mode sécurisé</string>
<string name="reboot_to_apply">Redémarrer pour appliquer les changements</string>
<string name="module_magisk_conflict">Les modules sont indisponibles en raison d\'un conflit avec Magisk!</string>
<string name="home_mount_system">Système de module</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Indisponible</string>
<string name="use_overlay_fs">Utiliser OverlayFS</string>
<string name="use_overlay_fs_summary">Alterner entre l\utilisation dOverlayFS et de Magic Mount pour le système de montage de KernelSU Next.</string>
<string name="reboot_required">Redémarrage requis</string>
<string name="reboot_message">Les changements ne seront effectifs qu\'après un redémarrage. Voulez-vous redémarrer maintenant?</string>
<string name="module_restore">Restaurer des modules</string>
<string name="module_restore_message">Restaurer des modules depuis une sauvegarde récente</string>
<string name="backup_restore">Sauvegarde et restoration</string>
<string name="module_backup">Sauvegarder les modules</string>
<string name="module_backup_message">Sauvegarder les modules installés</string>
<string name="allowlist_restore">Restorer la liste d\'autorisation</string>
<string name="allowlist_restore_message">Restorer la liste d\'autorisation depuis une sauvegarde récente ?</string>
<string name="allowlist_backup">Sauvegarder la liste d\'autorisation</string>
<string name="allowlist_backup_message">Sauvegarder la liste d\'autorisation actuelle ?</string>
<string name="warning">Avertissement</string>
<string name="warning_message">Cette fonctionnalité est encore en version bêta et en cours de développement. Veuillez sauvegarder vos modules avant de continuer. Utilisez cette fonctionnalité uniquement si vous comprenez les risques potentiels. Procédez avec prudence.</string>
<string name="proceed">Continuer</string>
<string name="cancel">Annuler</string>
<string name="later">Plus tard</string>
<string name="home_next_kernelsu">🔥 Next build</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Branche expérimentale Next. Allez la voir sur Github!</string>
<string name="home_experimental_kernelsu">⚠️ Attention, développement expérimental!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next est une version non-officielle, toujours en cours de développement. KernelSU Next vous est donc proposé tel quel, sans garantie de stabilité, de performance, ou d\'efficiacité.</string>
<string name="home_experimental_kernelsu_body_point_1"> • Soyez donc en connaissance des risques : vous pourriez faire face à des crashs, des réactions inattendues ou encore des erreurs système.</string>
<string name="home_experimental_kernelsu_body_point_2"> • Aucune garantie : Les développeurs ne seront tenus responsables d\'aucune perte de données, de dégâts au système ou d\'autres conséquences résultant de l\'utilisation de KernelSU Next.</string>
<string name="home_experimental_kernelsu_body_point_3"> • Uniquement à but de tests : KernelSU Next est prévue pour des utilisateurs avertis, qui comprennent les risques et qui sont à l\'aise avec le fait de localiser un problème.</string>
<string name="about_source_code"><![CDATA[Voir le code source sur %1$s]]></string>
<string name="profile" translatable="false">Profil d\'application</string>
<string name="profile_default">Par défaut</string>
<string name="profile_template">Modèle</string>
<string name="profile_custom">Custom</string>
<string name="profile_name">Nom du modèle</string>
<string name="profile_namespace">Monter le profil</string>
<string name="profile_namespace_inherited">Hérité</string>
<string name="profile_namespace_global">Global</string>
<string name="profile_namespace_individual">Individuel</string>
<string name="profile_groups">Groupes</string>
<string name="profile_capabilities">Capacités</string>
<string name="profile_selinux_context">Contexte SELinux</string>
<string name="profile_umount_modules">Démonter les modules</string>
<string name="failed_to_update_app_profile">Échec de la mise à jour du profil d\'application pour %s</string>
<string name="require_kernel_version">La version actuelle de KernelSU Next %1$d Est trop ancienne pour que le gestionnaire fonctionne correctement. Merci de mettre à jour vers la version %2$d ou supérieur!</string>
<string name="settings_umount_modules_default">Démonter les modules par défaut</string>
<string name="settings_umount_modules_default_summary">Valeur globale par défaut pour \"Démonter les modules\" Dans le profil d\'application. Si activé, toutes les modifications systèmes effectuées par des modules seront annulées pour les applications n\'ayant pas de profil sélectionné.</string>
<string name="settings_susfs_toggle">Cacher les hooks kprobe</string>
<string name="settings_susfs_toggle_summary">Désactive les hooks kprobe créés par KSU et, à la place, active les hooks non-kprobe intégrés, implémentant les mêmes fonctionnalités qui seraient appliquées à un kernel non-GKI, qui ne supportent pas les kprobes.</string>
<string name="profile_umount_modules_summary">Activer cette option permettra à KernelSU Next de restaurer n\'importe quel fichier modifié par les modules pour cette application.</string>
<string name="profile_selinux_domain">Domaine</string>
<string name="profile_selinux_rules">Règles</string>
<string name="module_update">Mise à jour</string>
<string name="module_downloading">Téléchargement du module : %s</string>
<string name="module_start_downloading">Démarrage du téléchargement : %s</string>
<string name="new_version_available">Une nouvelle version (%s) est disponible, appuyer pour mettre à jour.</string>
<string name="launch_app">Lancer</string>
<string name="close">Fermer</string>
<string name="force_stop_app">Forcer l\'arrêt</string>
<string name="restart_app">Redémarrer</string>
<string name="failed_to_update_sepolicy">Échec de la mise à jour des règles SELinux pour: %s</string>
<string name="module_changelog">Notes de mise à jour</string>
<string name="settings_profile_template">Modèle de profil d\'application</string>
<string name="settings_profile_template_summary">Gérer les profils d\'applications locaux et en ligne</string>
<string name="app_profile_template_create">Créer un template</string>
<string name="app_profile_template_edit">Éditer le template</string>
<string name="app_profile_template_id">ID</string>
<string name="app_profile_template_id_invalid">ID du template invalide</string>
<string name="app_profile_template_name">Nom</string>
<string name="app_profile_template_description">Description</string>
<string name="app_profile_template_save">Sauvegarder</string>
<string name="app_profile_template_delete">Supprimer</string>
<string name="app_profile_template_view">Voir le modèle</string>
<string name="app_profile_template_readonly">Lecture seule</string>
<string name="app_profile_template_id_exist">L\'identifiant du template existe déjà!</string>
<string name="app_profile_import_export">Importer/Exporter</string>
<string name="app_profile_import_from_clipboard">Importer depuis le presse-papier</string>
<string name="app_profile_export_to_clipboard">Exporter vers le presse-papier</string>
<string name="app_profile_template_export_empty">Impossible de trouver le modèle local à exporter!</string>
<string name="app_profile_template_import_success">Importé avec succès</string>
<string name="app_profile_template_sync">Synchroniser les modèles en ligne</string>
<string name="app_profile_template_save_failed">Échec de la sauvegarde du modèle</string>
<string name="app_profile_template_import_empty">Le presse-papier est vide!</string>
<string name="module_changelog_failed">Échec de la récupération des notes de mise à jour: %s</string>
<string name="settings_check_update">Vérifier les mises à jour</string>
<string name="settings_check_update_summary">Vérifier les mises à jour à l\'ouverture de l\'application</string>
<string name="grant_root_failed">Échec de l\'accord du statut root!</string>
<string name="action">Action</string>
<string name="open">Ouvrir</string>
<string name="enable_web_debugging">Activer le débogage de WebView</string>
<string name="enable_web_debugging_summary">Peut être utilisé pour déboguer la WebUI. Merci de ne l\'activer qu\'en cas de nécéssité.</string>
<string name="direct_install">Installation directe (recommandé)</string>
<string name="select_file">Sélectionner un fichier</string>
<string name="install_inactive_slot">Installer sur un slot inactif (après OTA)</string>
<string name="install_inactive_slot_warning">Cela **FORCERA** votre appareil à démarrer sur le slot inactif après un redémarrage !\nN\'utiliser cette option qu\'après une mise à jour OTA.\nContinuer ?</string>
<string name="install_next">Suivant</string>
<string name="select_file_tip">%1$s Partitionner l\'image est recommandé.</string>
<string name="select_kmi">Sélectionner le KMI</string>
<string name="shrink_sparse_image">Minimiser l\'espace disponible réservé</string>
<string name="shrink_sparse_image_message">Redimensionne l\'image où se trouve le module à sa taille réelle. Notez que cela peut entraîner un fonctionnement anormal des modules. Veuillez donc l\'utiliser uniquement en cas de nécessité (par exemple, pour une sauvegarde).</string>
<string name="settings_uninstall">Désinstaller</string>
<string name="settings_uninstall_temporary">Désinstaller temporairement</string>
<string name="settings_uninstall_permanent">Désinstaller de façon permanente</string>
<string name="settings_restore_stock_image">Restaurer l\'image stock</string>
<string name="settings_uninstall_temporary_message">Désinstalle temporairement KernelSU Next, qui sera restauré au prochain redémarrage.</string>
<string name="settings_uninstall_permanent_message">Désinstallation de KernelSU Next (Root et les modules) complètement et de façon définitive.</string>
<string name="settings_restore_stock_image_message">Restaure l\'image stock (si une sauvegarde existe), habituellement utilisée avant une mise à jour OTA; Si vous avez besoin de désinstaller KernelSU Next, Merci de sélectionner \"Désinstaller de façon permanente\".</string>
<string name="flashing">En cours de flash...</string>
<string name="flash_success">Flash réussi!</string>
<string name="flash_failed">Flash échoué</string>
<string name="selected_lkm">LKM sélectionné: %s</string>
<string name="save_log">Enregistrer les logs</string>
<string name="log_saved">Logs Enregistrés</string>
<string name="send_log">Partager les logs</string>
<string name="settings_disable_su">Désactiver la compatibilité su</string>
<string name="settings_disable_su_summary">Désactive temporairement la possibilité d\'obtenir les permissions root en utilisant la commande su pour toutes les application (les processus root actifs ne seront pas affectés).</string>
</resources>

View File

@@ -0,0 +1,238 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">समस्या आ रही है?</string>
<string name="issue_report_body">क्या आपको कोई बग मिला या आपके पास कोई प्रतिक्रिया है?</string>
<string name="issue_report_body_2">जितनी जल्दी हो सके इसकी रिपोर्ट करें!</string>
<string name="issue_report_github">गिटहब पर रिपोर्ट करे</string>
<string name="issue_report_telegram">टेलीग्राम के माध्यम से संपर्क करें</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">पुष्टि करें</string>
<string name="app_name">KernelSU Next</string>
<string name="home">होम</string>
<string name="home_not_installed">इन्स्टॉल नहीं है</string>
<string name="home_click_to_install">इंस्टॉल करने के लिए क्लिक करें</string>
<string name="lkm_mode_deprecated">LKM मोड अब अप्रचलित हो गया है!</string>
<string name="lkm_alternative_suggestion">GKI कर्नल अधिष्ठापित करें या KernelSU Next को अपने डिवाइस पर इन्स्टॉल करें।</string>
<string name="home_working">काम कर रहा है</string>
<string name="home_working_version">वर्जन: %d</string>
<string name="home_module_update_count">अपडेट्स: %d</string>
<string name="home_failure">KernelSU Next v2 सिग्नेचर कर्नेल में नहीं मिला!
[ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">अपने कर्नल डेवलपर से KernelSU नेक्स्ट को एकीकृत करने के लिए कहें!</string>
<string name="home_kernel">कर्नल वर्जन</string>
<string name="hook_mode">हुक मोड</string>
<string name="enable">सक्षम करें</string>
<string name="disable">अक्षम करें</string>
<string name="enabled">सक्षम है</string>
<string name="disabled">निष्क्रिय है</string>
<string name="susfs_supported">समर्थित</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">SuSFS वर्जन</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">एंड्रॉयड वर्जन</string>
<string name="home_manager_version">मैनेजर वर्जन</string>
<string name="home_abi"></string>
<string name="home_selinux_status">SELinux स्थिति</string>
<string name="selinux_status_disabled">निष्क्रिय है</string>
<string name="selinux_status_enforcing">एनफोर्सिंग</string>
<string name="selinux_status_permissive">परमिसीव</string>
<string name="selinux_status_unknown">अज्ञात</string>
<string name="superuser">सुपरयूजर</string>
<string name="module_failed_to_enable">%s: मॉड्यूल चालू करने में विफल |</string>
<string name="module_failed_to_disable">%s: मॉड्यूल बंद करने में विफल |</string>
<string name="module_empty">कोई मॉड्यूल इंस्टाल नहीं हुआ |</string>
<string name="module">मॉड्यूल</string>
<string name="module_install_prompt_with_name">निम्नलिखित मॉड्यूल इंस्टाल किए जाएंगे: %1$s</string>
<string name="module_sort_a_to_z">क्रमबद्ध करें (A → Z)</string>
<string name="module_sort_z_to_a">क्रमबद्ध करें (Z → A)</string>
<string name="module_size_low_to_high">क्रमबद्ध करें (न्यूनतम → उच्चतम)</string>
<string name="module_size_high_to_low">क्रमबद्ध करें (उच्चतम → न्यूनतम)</string>
<string name="uninstall">अनइंस्टॉल करें</string>
<string name="restore">पहले जैसा करें</string>
<string name="module_install">इंस्टॉल करें</string>
<string name="install">इंस्टॉल करें</string>
<string name="reboot">रिबूट</string>
<string name="uninstalled">अनइंस्टॉल किया गया</string>
<string name="settings">सेटिंग्स</string>
<string name="reboot_userspace">सॉफ्ट रिबूट</string>
<string name="reboot_recovery">रिकवरी में रिबूट करें</string>
<string name="reboot_bootloader">बूटलोडर में रिबूट करें</string>
<string name="reboot_download">डाउनलोड में रिबूट करें</string>
<string name="reboot_edl">EDL मोड में रिबूट करें</string>
<string name="about">इसके बारे में</string>
<string name="module_uninstall_confirm">क्या आप सच में %s मॉड्यूल को अनइंस्टॉल करना चाहते हैं?</string>
<string name="module_uninstall_success">%s अनइंस्टॉल सफल हुआ |</string>
<string name="module_uninstall_failed">%s अनइंस्टल करने में असफल |</string>
<string name="module_restore_confirm">क्या आप सच में %s मॉड्यूल को पहले जैसा करना चाहते हैं?</string>
<string name="module_restore_success">%s मॉड्यूल को पहले जैसा किया गया |</string>
<string name="module_restore_failed">पुनर्स्थापित करने में विफल: %s</string>
<string name="module_version">वर्जन</string>
<string name="module_author">रचयिता</string>
<string name="module_id">आइडी</string>
<string name="module_version_code">कोड</string>
<string name="module_update_json">UpdateJson</string>
<string name="module_update_json_empty">खाली</string>
<string name="enable_developer_options">डेवलपर विकल्प सक्षम करें</string>
<string name="enable_developer_options_summary">Show hidden settings and debug info relevant only for developers.</string>
<string name="module_overlay_fs_not_available">Modules are unavailable as OverlayFS is disabled by the kernel!</string>
<string name="refresh">रीफ्रेश करें</string>
<string name="show_system_apps">सिस्टम ऐप्स दिखाएँ।</string>
<string name="hide_system_apps">सिस्टम ऐप्स छिपाएं</string>
<string name="export_log">लॉग एक्सपोर्ट करें</string>
<string name="safe_mode">सुरक्षित मोड</string>
<string name="reboot_to_apply">प्रभाव में होने के लिए रीबूट करें</string>
<string name="module_magisk_conflict">मॉड्यूल बंद कर दिए गए हैं क्योंकि यह मैजिसक के साथ टकरा रहे है!</string>
<string name="home_mount_system">माउंट सिस्टम</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">अनुपलब्ध</string>
<string name="use_overlay_fs">OverlayFS का उपयोग करें</string>
<string name="use_overlay_fs_summary">Toggle between using OverlayFS over Magic Mount for KernelSU Next\'s mount system.</string>
<string name="reboot_required">रिबूट करना जरूरी है!</string>
<string name="reboot_message">सिस्टम रीस्टार्ट के बाद यह परिवर्तन प्रभावी होगा। क्या आप अभी रीबूट करना चाहते हैं?</string>
<string name="module_restore">Restore module</string>
<string name="module_restore_message">Restore modules from recent backup.</string>
<string name="backup_restore">बैकअप &amp; रिस्टोर</string>
<string name="module_backup">Backup module</string>
<string name="allowlist_restore">Restore allowlist</string>
<string name="allowlist_restore_message">Restore allowlist from recent backup.</string>
<string name="allowlist_backup">Backup allowlist</string>
<string name="allowlist_backup_message">Backup currently configured allowlist.</string>
<string name="warning">चेतावनी</string>
<string name="warning_message">This feature is still in beta and under development. Please ensure you backup your modules before proceeding. Only use this feature if you understand the potential risks. Proceed with caution.</string>
<string name="proceed">आगे बढ़ें</string>
<string name="cancel">रद्द करें</string>
<string name="later">बाद में</string>
<string name="lkm_warning_message">The LKM patch relies on closed source components. Do you want to continue?</string>
<string name="home_next_kernelsu">🔥 Next build</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Next experimental branch. Check it out on GitHub!</string>
<string name="home_experimental_kernelsu">⚠️ प्रायोगिक विकास की चेतावनी!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next एक गैर-आधिकारिक संस्करण है जो हमेशा सक्रिय प्रयोगात्मक विकास के अंतर्गत रहता है। इसे वैसे ही उपलब्ध कराया जाता है, जिसमें स्थिरता, प्रदर्शन या विश्वसनीयता की कोई गारंटी नहीं होती।</string>
<string name="home_experimental_kernelsu_body_point_1"> • अपने जोखिम पर उपयोग करें: क्रैश, अप्रत्याशित व्यवहार या सिस्टम समस्याएं हो सकती हैं।</string>
<string name="home_experimental_kernelsu_body_point_2"> • कोई वारंटी नहीं: डेवलपर्स इसके उपयोग से होने वाली किसी भी डेटा हानि, सिस्टम क्षति या अन्य परिणामों के लिए जिम्मेदार नहीं हैं।</string>
<string name="home_experimental_kernelsu_body_point_3"> • केवल परीक्षण के उद्देश्य से: उन उपयोगकर्ताओं के लिए जो जोखिमों को समझते हैं और समस्याओं का निवारण करने में सहज हैं।</string>
<string name="about_source_code">%1$s पर स्रोत कोड देखें</string>
<string name="profile">ऐप प्रोफ़ाइल</string>
<string name="profile_default">डिफ़ॉल्ट</string>
<string name="profile_template">टेम्पलेट</string>
<string name="profile_custom">कस्टम</string>
<string name="profile_name">प्रोफ़ाइल नाम</string>
<string name="profile_namespace">Namespace माउंट करें</string>
<string name="profile_namespace_inherited">इनहेरिट किया गया</string>
<string name="profile_namespace_global">ग्लोबल</string>
<string name="profile_namespace_individual">विशिष्ट</string>
<string name="profile_groups">ग्रुप्स</string>
<string name="profile_capabilities">क्षमताएं</string>
<string name="profile_selinux_context">SELinux कॉन्टेक्स्ट</string>
<string name="profile_umount_modules">मॉड्यूल्स यूमाउंट करें</string>
<string name="failed_to_update_app_profile">%s के लिए ऐप प्रोफ़ाइल अपडेट करने में विफल</string>
<string name="require_kernel_version">मैनेजर के ठीक से काम करने के लिए वर्तमान KernelSU Next वर्जन %1$d बहुत कम है। कृपया वर्जन %2$d या उच्चतर में अपग्रेड करें!</string>
<string name="settings_umount_modules_default">मॉड्यूल्स यूमाउंट करें</string>
<string name="settings_umount_modules_default_summary">ऐप प्रोफाइल में \"अनमाउंट मॉड्यूल\" के लिए ग्लोबल डिफ़ॉल्ट वैल्यू। यदि चालू किया गया है, तो यह एप्लीकेशंस के लिऐ सिस्टम के सभी मॉड्यूल मोडिफिकेशन को हटा देगा जिनकी प्रोफ़ाइल सेट नहीं है।</string>
<string name="settings_susfs_toggle">Kprobes हुक को छिपाएं
</string>
<string name="settings_susfs_toggle_summary">यह विकल्प KSU द्वारा निर्मित kprobes हुक को निष्क्रिय कर देता है, तथा इसके स्थान पर एम्बेडेड non-kprobes हुक को सक्रिय कर देता है, तथा उसी कार्यक्षमता को क्रियान्वित करता है जो non-GKI कर्नल पर लागू होती है, जो kprobe का समर्थन नहीं करता है।</string>
<string name="profile_umount_modules_summary">इस विकल्प को चालू करने से KernelSU Next इस एप्लिकेशन के लिए मॉड्यूल द्वारा किसी भी मोडिफाइड फ़ाइल को रिस्टोर कर सकता है।</string>
<string name="profile_selinux_domain">डोमेन</string>
<string name="profile_selinux_rules">नियम</string>
<string name="module_update">अपडेट</string>
<string name="module_update_available">अपडेट</string>
<string name="module_updated">अपडेट किया गया</string>
<string name="module_downloading">%s मॉड्यूल डाउनलोड हो रहा है</string>
<string name="module_start_downloading">%s की डाउनलोडिंग स्टार्ट करें</string>
<string name="new_version_available">नया वर्जन: %s उपलब्ध है,अपग्रेड के लिए क्लिक करें|</string>
<string name="launch_app">लॉन्च</string>
<string name="close">बंद</string>
<string name="force_stop_app">ज़बरदस्ती रोकें</string>
<string name="restart_app">रिस्टार्ट करें</string>
<string name="settings_amoled_mode">AMOLED मोड</string>
<string name="settings_amoled_mode_summary">आंखों पर पड़ने वाले तनाव को कम करने और बैटरी बचाने के लिए AMOLED स्क्रीन के लिए उपयोगी काले रंग की थीम को सक्षम करें।</string>
<string name="restart_required">पुनः आरंभ की आवश्यकता है</string>
<string name="restart_app_message">इस बदलाव के लिए ऐप को दोबारा शुरू करना होगा।</string>
<string name="failed_to_update_sepolicy">%s के लिए SELinux नियमों को अपटेड करने में विफल</string>
<string name="su_not_allowed">%s को सुपरयूज़र एक्सेस नहीं दिया जा सका</string>
<string name="module_changelog">चेंजलॉग</string>
<string name="settings_profile_template">ऐप प्रोफ़ाइल नमूना</string>
<string name="settings_profile_template_summary">ऐप प्रोफ़ाइल के स्थानीय और ऑनलाइन नमूनों का प्रबंधन करें</string>
<string name="app_profile_template_create">नया टेम्प्लेट बनाएं</string>
<string name="app_profile_template_edit">टेम्पलेट एडिट करें</string>
<string name="app_profile_template_id">आइडी</string>
<string name="app_profile_template_id_invalid">अमान्य नमूना ID</string>
<string name="app_profile_template_name">नाम</string>
<string name="app_profile_template_description">विवरण</string>
<string name="app_profile_template_save">सेव</string>
<string name="app_profile_template_delete">डिलीट</string>
<string name="app_profile_template_view">नमूना देखें</string>
<string name="app_profile_template_readonly">केवल पढ़ने के लिए</string>
<string name="app_profile_template_id_exist">नमूना ID पहले से मौजूद है!</string>
<string name="app_profile_import_export">आयात/निर्यात</string>
<string name="app_profile_import_from_clipboard">क्लिपबोर्ड से इम्पोर्ट करें</string>
<string name="app_profile_export_to_clipboard">क्लिपबोर्ड को निर्यात करें</string>
<string name="app_profile_template_export_empty">एक्सपोर्ट करने के लिए कोई स्थानीय नमूना नहीं मिला!</string>
<string name="app_profile_template_import_success">सफलतापूर्वक आयात किया गया</string>
<string name="app_profile_template_sync">ऑनलाइन नमूने सिंक करें</string>
<string name="app_profile_template_save_failed">नमूना सहेजने में विफल रहा</string>
<string name="app_profile_template_import_empty">क्लिपबोर्ड खाली है!</string>
<string name="module_changelog_failed">Fetch changelog failed: %s</string>
<string name="settings_check_update">अपडेट के लिए चेक करें</string>
<string name="settings_check_update_summary">ऐप खोलने पर अपने आप अपडेट जांचें</string>
<string name="grant_root_failed">रूट एक्सेस देने में विफल!</string>
<string name="action">एक्शन</string>
<string name="webui">WebUI</string>
<string name="open">खोलें</string>
<string name="enable_web_debugging"></string>
<string name="enable_web_debugging_summary">Can be used to debug WebUI. Please enable only when needed.</string>
<string name="direct_install">सीधा इंस्टॉल करें (सिफारिश की जाती है)</string>
<string name="select_file">फाइल चुनें</string>
<string name="install_inactive_slot">निष्क्रिय स्लॉट में इंस्टॉल करें (OTA के बाद)</string>
<string name="install_inactive_slot_warning">Your device will be **FORCED** to boot to the current inactive slot after a reboot!\nOnly use this option after OTA is done.\nContinue?</string>
<string name="install_next">अगला</string>
<string name="select_file_tip">%1$s partition image की सिफारिश की जाती है</string>
<string name="select_kmi">KMI चुनें</string>
<string name="shrink_sparse_image">Minimize sparse image</string>
<string name="shrink_sparse_image_message">Resize the sparse image where the module is located to its actual size. Note that this may cause the module to work abnormally, so please only use when necessary (Such as for backup).</string>
<string name="settings_uninstall">अनइंस्टॉल करें</string>
<string name="settings_uninstall_temporary">कुछ समय के लिए हटाएं</string>
<string name="settings_uninstall_permanent">हमेशा के लिए हटाएं</string>
<string name="settings_restore_stock_image">Restore stock image</string>
<string name="settings_uninstall_temporary_message">KernelSU Next को अभी के लिए हटाया जाएगा, अगली बार डिवाइस चालू होने पर यह वापस आ जाएगा।</string>
<string name="settings_uninstall_permanent_message">KernelSU Next को रूट और सभी मॉड्यूल के साथ पूरी तरह से हमेशा के लिए हटाया जा रहा है।</string>
<string name="settings_restore_stock_image_message">Restore the stock factory image (If a backup exists), usually used before OTA; if you need to uninstall KernelSU Next, please use \"Uninstall permanently\".</string>
<string name="flashing">फ़्लैश हो रहा है</string>
<string name="flash_success">फ्लैश सफल रहा</string>
<string name="flash_failed">फ्लैश असफल रहा</string>
<string name="selected_lkm">चुना गया LKM: %s</string>
<string name="save_log">लॉग सहेजें</string>
<string name="log_saved">Logs saved</string>
<string name="send_log">लॉग शेयर करें</string>
<string name="settings_disable_su">SU compatibility अस्थायी रूप से बंद करें</string>
<string name="settings_disable_su_summary">Temporarily disable the ability of any app to gain root privileges via the su command (Existing root processes won\'t be affected).</string>
<string name="settings_language">भाषा</string>
<string name="system_default">सिस्टम डिफ़ॉल्ट</string>
<string name="settings_legacyui">Use legacy UI</string>
<string name="settings_legacyui_summary">Switch to the previous user interface style.</string>
<string name="settings_banner">Enable banners</string>
<string name="settings_banner_summary">Show background banners for modules.</string>
<string name="use_webuix">WebUI X का उपयोग करें</string>
<string name="use_webuix_summary">WebUI के बजाय WebUI X का उपयोग करें, जो अधिक API का समर्थन करता है।</string>
<string name="use_webuix_eruda">Eruda को WebUI X में इंजेक्ट करें</string>
<string name="use_webuix_eruda_summary">डीबगिंग को आसान बनाने के लिए WebUI X में डीबग कंसोल इंजेक्ट करें। वेब डीबगिंग चालू होना आवश्यक है।</string>
<string name="customization">कस्टमाइजेशन</string>
<string name="developer">डेवलपर</string>
<string name="sucompat_disabled">SUCOMPAT DISABLED</string>
<string name="zygisk_required">Zygisk आवश्यक है!</string>
<string name="zygisk_status">Zygisk इंजेक्शन</string>
<string name="home_superuser_count_singular">सुपरयूजर</string>
<string name="home_superuser_count_plural">सुपरयूजरस</string>
<string name="home_module_count_singular">मॉड्यूल</string>
<string name="home_module_count_plural">मॉड्यूलस</string>
<string name="module_backup_message">Backup currently installed modules.</string>
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
<string name="module_sort_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI first)</string>
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
</resources>

View File

@@ -0,0 +1,236 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">Having trouble?</string>
<string name="issue_report_body">Encountered a bug or have feedback?</string>
<string name="issue_report_body_2">Report it as soon as possible!</string>
<string name="issue_report_github">Report on GitHub</string>
<string name="issue_report_telegram">Contact via Telegram</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Confirm</string>
<string name="app_name">KernelSU Next</string>
<string name="home">Home</string>
<string name="home_not_installed">Not installed</string>
<string name="home_click_to_install">Click to install</string>
<string name="lkm_mode_deprecated">LKM mode is now deprecated!</string>
<string name="lkm_alternative_suggestion">Install GKI kernel or integrate KernelSU Next to your device.</string>
<string name="home_working">Working</string>
<string name="home_working_version">Version: %d</string>
<string name="home_module_update_count">Updates: %d</string>
<string name="home_failure">KernelSU Next v2 signature not found in kernel! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">Ask your kernel developer to integrate KernelSU Next!</string>
<string name="home_kernel">Kernel version</string>
<string name="hook_mode">Hook mode</string>
<string name="enable">Enable</string>
<string name="disable">Disable</string>
<string name="enabled">Enabled</string>
<string name="disabled">Disabled</string>
<string name="susfs_supported">Supported</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">SuSFS version</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Android version</string>
<string name="home_manager_version">Manager version</string>
<string name="home_abi">ABI</string>
<string name="home_selinux_status">SELinux status</string>
<string name="selinux_status_disabled">Disabled</string>
<string name="selinux_status_enforcing">Enforcing</string>
<string name="selinux_status_permissive">Permissive</string>
<string name="selinux_status_unknown">Unknown</string>
<string name="superuser">Superuser</string>
<string name="module_failed_to_enable">Failed to enable module: %s</string>
<string name="module_failed_to_disable">Failed to disable module: %s</string>
<string name="module_empty">No module installed</string>
<string name="module">Module</string>
<string name="module_install_prompt_with_name">The following modules will be installed: %1$s</string>
<string name="module_sort_a_to_z">Sort (A → Z)</string>
<string name="module_sort_z_to_a">Sort (Z → A)</string>
<string name="module_size_low_to_high">Sort (Low → High)</string>
<string name="module_size_high_to_low">Sort (High → Low)</string>
<string name="uninstall">Uninstall</string>
<string name="restore">Restore</string>
<string name="module_install">Install</string>
<string name="install">Install</string>
<string name="reboot">Reboot</string>
<string name="uninstalled">Uninstalled</string>
<string name="settings">Settings</string>
<string name="reboot_userspace">Soft reboot</string>
<string name="reboot_recovery">Reboot to Recovery</string>
<string name="reboot_bootloader">Reboot to Bootloader</string>
<string name="reboot_download">Reboot to Download</string>
<string name="reboot_edl">Reboot to EDL</string>
<string name="about">About</string>
<string name="module_uninstall_confirm">Are you sure you want to uninstall module %s?</string>
<string name="module_uninstall_success">%s uninstalled</string>
<string name="module_uninstall_failed">Failed to uninstall: %s</string>
<string name="module_restore_confirm">Are you sure you want to restore module %s?</string>
<string name="module_restore_success">%s restored</string>
<string name="module_restore_failed">Failed to restore: %s</string>
<string name="module_version">Version</string>
<string name="module_author">Author</string>
<string name="module_id">ID</string>
<string name="module_version_code">Code</string>
<string name="module_update_json">UpdateJson</string>
<string name="module_update_json_empty">Empty</string>
<string name="enable_developer_options">Enable developer options</string>
<string name="enable_developer_options_summary">Show hidden settings and debug info relevant only for developers.</string>
<string name="module_overlay_fs_not_available">Modules are unavailable as OverlayFS is disabled by the kernel!</string>
<string name="refresh">Refresh</string>
<string name="show_system_apps">Show system apps</string>
<string name="hide_system_apps">Hide system apps</string>
<string name="export_log">Export logs</string>
<string name="safe_mode">Safe mode</string>
<string name="reboot_to_apply">Reboot to take effect</string>
<string name="module_magisk_conflict">Modules are unavailable due to a conflict with Magisk!</string>
<string name="home_mount_system">Mount system</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Unavailable</string>
<string name="use_overlay_fs">Use OverlayFS</string>
<string name="use_overlay_fs_summary">Toggle between using OverlayFS over Magic Mount for KernelSU Next\'s mount system.</string>
<string name="reboot_required">Reboot required</string>
<string name="reboot_message">The changes will take effect after the system restart. Do you want to reboot now?</string>
<string name="module_restore">Restore module</string>
<string name="module_restore_message">Restore modules from recent backup.</string>
<string name="backup_restore">Backup &amp; Restore</string>
<string name="module_backup">Backup module</string>
<string name="allowlist_restore">Restore allowlist</string>
<string name="allowlist_restore_message">Restore allowlist from recent backup.</string>
<string name="allowlist_backup">Backup allowlist</string>
<string name="allowlist_backup_message">Backup currently configured allowlist.</string>
<string name="warning">Warning</string>
<string name="warning_message">This feature is still in beta and under development. Please ensure you backup your modules before proceeding. Only use this feature if you understand the potential risks. Proceed with caution.</string>
<string name="proceed">Proceed</string>
<string name="cancel">Cancel</string>
<string name="later">Later</string>
<string name="lkm_warning_message">The LKM patch relies on closed source components. Do you want to continue?</string>
<string name="home_next_kernelsu">🔥 Next build</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Next experimental branch. Check it out on GitHub!</string>
<string name="home_experimental_kernelsu">⚠️ Experimental development warning!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">KernelSU Next is a non-official version that is always under active experimental development. It\'s provided as-is, with no guarantees of stability, performance, or reliability.</string>
<string name="home_experimental_kernelsu_body_point_1"> • Use at your own risk: crashes, unexpected behavior, or system issues may occur.</string>
<string name="home_experimental_kernelsu_body_point_2"> • No warranty: the developers aren\'t responsible for any data loss, system damage, or other consequences resulting from its use.</string>
<string name="home_experimental_kernelsu_body_point_3"> • For testing purposes only: intended for users who understand the risks and are comfortable troubleshooting issues.</string>
<string name="about_source_code">View source code at %1$s</string>
<string name="profile">App Profile</string>
<string name="profile_default">Default</string>
<string name="profile_template">Template</string>
<string name="profile_custom">Custom</string>
<string name="profile_name">Profile name</string>
<string name="profile_namespace">Mount namespace</string>
<string name="profile_namespace_inherited">Inherited</string>
<string name="profile_namespace_global">Global</string>
<string name="profile_namespace_individual">Individual</string>
<string name="profile_groups">Groups</string>
<string name="profile_capabilities">Capabilities</string>
<string name="profile_selinux_context">SELinux context</string>
<string name="profile_umount_modules">Umount modules</string>
<string name="failed_to_update_app_profile">Failed to update App Profile for %s</string>
<string name="require_kernel_version">The current KernelSU Next version %1$d is too low for the manager to work properly. Please upgrade to version %2$d or higher!</string>
<string name="settings_umount_modules_default">Umount modules</string>
<string name="settings_umount_modules_default_summary">The global default value for \"Umount modules\" in App Profile. If enabled, it will remove all module modifications to the system for apps that don\'t have a profile set.</string>
<string name="settings_susfs_toggle">Hide kprobes hook</string>
<string name="settings_susfs_toggle_summary">This option disables the kprobes hook created by ksu and, instead, activates the embedded non-kprobes hook, implementing the same functionality that would be applied to a non-GKI kernel, which doesn\'t support kprobe.</string>
<string name="profile_umount_modules_summary">Enabling this option will allow KernelSU Next to restore any modified files by the modules for this app.</string>
<string name="profile_selinux_domain">Domain</string>
<string name="profile_selinux_rules">Rules</string>
<string name="module_update">Update</string>
<string name="module_update_available">Update</string>
<string name="module_updated">Updated</string>
<string name="module_downloading">Downloading module: %s</string>
<string name="module_start_downloading">Start downloading: %s</string>
<string name="new_version_available">New version %s is available, click to upgrade.</string>
<string name="launch_app">Launch</string>
<string name="close">Close</string>
<string name="force_stop_app">Force stop</string>
<string name="restart_app">Restart</string>
<string name="settings_amoled_mode">AMOLED mode</string>
<string name="settings_amoled_mode_summary">Enable a pure black theme useful for AMOLED screens to reduce eye strain and save battery.</string>
<string name="restart_required">Restart required</string>
<string name="restart_app_message">The app needs to restart for this change to take effect.</string>
<string name="failed_to_update_sepolicy">Failed to update SELinux rules for %s</string>
<string name="su_not_allowed">Couldn\'t grant Superuser access to %s</string>
<string name="module_changelog">Changelog</string>
<string name="settings_profile_template">App Profile template</string>
<string name="settings_profile_template_summary">Manage local and online template of App Profile</string>
<string name="app_profile_template_create">Create template</string>
<string name="app_profile_template_edit">Edit template</string>
<string name="app_profile_template_id">ID</string>
<string name="app_profile_template_id_invalid">Invalid template ID</string>
<string name="app_profile_template_name">Name</string>
<string name="app_profile_template_description">Description</string>
<string name="app_profile_template_save">Save</string>
<string name="app_profile_template_delete">Delete</string>
<string name="app_profile_template_view">View template</string>
<string name="app_profile_template_readonly">Read only</string>
<string name="app_profile_template_id_exist">Template ID already exists!</string>
<string name="app_profile_import_export">Import/Export</string>
<string name="app_profile_import_from_clipboard">Import from clipboard</string>
<string name="app_profile_export_to_clipboard">Export to clipboard</string>
<string name="app_profile_template_export_empty">Cannot find local template to export!</string>
<string name="app_profile_template_import_success">Imported successfully</string>
<string name="app_profile_template_sync">Sync online templates</string>
<string name="app_profile_template_save_failed">Failed to save template</string>
<string name="app_profile_template_import_empty">Clipboard is empty!</string>
<string name="module_changelog_failed">Fetch changelog failed: %s</string>
<string name="settings_check_update">Check for updates</string>
<string name="settings_check_update_summary">Automatically check for updates when opening the app</string>
<string name="grant_root_failed">Failed to grant root!</string>
<string name="action">Action</string>
<string name="webui">WebUI</string>
<string name="open">Open</string>
<string name="enable_web_debugging">Enable WebView debugging</string>
<string name="enable_web_debugging_summary">Can be used to debug WebUI. Please enable only when needed.</string>
<string name="direct_install">Direct install (Recommended)</string>
<string name="select_file">Select a file</string>
<string name="install_inactive_slot">Install to inactive slot (After OTA)</string>
<string name="install_inactive_slot_warning">Your device will be **FORCED** to boot to the current inactive slot after a reboot!\nOnly use this option after OTA is done.\nContinue?</string>
<string name="install_next">Next</string>
<string name="select_file_tip">%1$s partition image is recommended</string>
<string name="select_kmi">Select KMI</string>
<string name="shrink_sparse_image">Minimize sparse image</string>
<string name="shrink_sparse_image_message">Resize the sparse image where the module is located to its actual size. Note that this may cause the module to work abnormally, so please only use when necessary (Such as for backup).</string>
<string name="settings_uninstall">Uninstall</string>
<string name="settings_uninstall_temporary">Uninstall temporarily</string>
<string name="settings_uninstall_permanent">Uninstall permanently</string>
<string name="settings_restore_stock_image">Restore stock image</string>
<string name="settings_uninstall_temporary_message">Temporarily uninstall KernelSU Next, restore to original state after next reboot.</string>
<string name="settings_uninstall_permanent_message">Uninstalling KernelSU Next (Root and all modules) completely and permanently.</string>
<string name="settings_restore_stock_image_message">Restore the stock factory image (If a backup exists), usually used before OTA; if you need to uninstall KernelSU Next, please use \"Uninstall permanently\".</string>
<string name="flashing">Flashing</string>
<string name="flash_success">Flash success</string>
<string name="flash_failed">Flash failed</string>
<string name="selected_lkm">Selected LKM: %s</string>
<string name="save_log">Save logs</string>
<string name="log_saved">Logs saved</string>
<string name="send_log">Share logs</string>
<string name="settings_disable_su">Disable su compatibility</string>
<string name="settings_disable_su_summary">Temporarily disable the ability of any app to gain root privileges via the su command (Existing root processes won\'t be affected).</string>
<string name="settings_language">Language</string>
<string name="system_default">System default</string>
<string name="settings_legacyui">Use legacy UI</string>
<string name="settings_legacyui_summary">Switch to the previous user interface style.</string>
<string name="settings_banner">Enable banners</string>
<string name="settings_banner_summary">Show background banners for modules.</string>
<string name="use_webuix">Use WebUI X</string>
<string name="use_webuix_summary">Use WebUI X instead of WebUI, which supports more APIs.</string>
<string name="use_webuix_eruda">Inject Eruda into WebUI X</string>
<string name="use_webuix_eruda_summary">Inject a debug console into WebUI X to make debugging easier. Requires web debugging to be on.</string>
<string name="customization">Customization</string>
<string name="developer">Developer</string>
<string name="sucompat_disabled">SUCOMPAT DISABLED</string>
<string name="zygisk_required">Zygisk required</string>
<string name="zygisk_status">Zygisk injection</string>
<string name="home_superuser_count_singular">Superuser</string>
<string name="home_superuser_count_plural">Superusers</string>
<string name="home_module_count_singular">Module</string>
<string name="home_module_count_plural">Modules</string>
<string name="module_backup_message">Backup currently installed modules.</string>
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
<string name="module_sort_action_first">Sort (Action first)</string>
<string name="module_sort_webui_first">Sort (WebUI first)</string>
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
</resources>

View File

@@ -1,197 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="issue_report_title">Problémája van?</string>
<string name="issue_report_body">Hibát észlelt, vagy van visszajelzése?</string>
<string name="issue_report_body_2">Jelentse mielőbb!</string>
<string name="issue_report_github">Report on GitHub</string>
<string name="issue_report_telegram">Kapcsolatfelvétel Telegramon keresztül</string>
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
<string name="confirm">Megerősítés</string>
<string name="app_name" translatable="false">KernelSU Next</string>
<string name="home">Kezdőlap</string>
<string name="home_not_installed">Nincs telepítve</string>
<string name="home_click_to_install">Kattintson a telepítéshez</string>
<string name="home_working">Működik</string>
<string name="home_working_version">Verzió: %d</string>
<string name="home_superuser_count">Superuserek: %d</string>
<string name="home_module_count">Modulok: %d</string>
<string name="home_failure">KernelSU Next v2 aláírás nem található a kernelben! [ !KSU_NEXT || != size/hash ]</string>
<string name="home_failure_tip">Kérje meg kernel fejlesztőjét, hogy integrálja a KernelSU Next-et!</string>
<string name="home_kernel">Kernel verzió</string>
<string name="enabled">Bekapcsolva</string>
<string name="disabled">Kikapcsolva</string>
<string name="susfs_supported">Támogatott</string>
<string name="home_susfs">SuSFS: %s</string>
<string name="home_susfs_version">SuSFS verzió</string>
<string name="home_susfs_sus_su">SuS SU</string>
<string name="home_android">Android verzió</string>
<string name="home_manager_version">Manager verzió</string>
<string name="home_selinux_status">SELinux státusz</string>
<string name="selinux_status_disabled">Letiltva</string>
<string name="selinux_status_enforcing">Kényszerítve</string>
<string name="selinux_status_permissive">Megengedő</string>
<string name="selinux_status_unknown">Ismeretlen</string>
<string name="superuser">Superuser</string>
<string name="module_failed_to_enable">Nem sikerült bekapcsolni a(z) %s modult</string>
<string name="module_failed_to_disable">Nem sikerült kikapcsolni a(z) %s modult</string>
<string name="module_empty">Nincs telepített modul</string>
<string name="module">Modul</string>
<string name="module_install_prompt_with_name">A következő modul(ok) lesznek telepítve: %1$s</string>
<string name="module_sort_a_to_z">Rendezés (A-Z)</string>
<string name="module_sort_z_to_a">Rendezés (Z-A)</string>
<string name="uninstall">Eltávolítás</string>
<string name="restore">Visszaállítás</string>
<string name="module_install">Telepítés</string>
<string name="install">Telepítés</string>
<string name="reboot">Újraindítás</string>
<string name="settings">Beállítások</string>
<string name="reboot_userspace">Lágy újraindítás</string>
<string name="reboot_recovery">Újraindítás Recovery módba</string>
<string name="reboot_bootloader">Újraindítás Bootloader módba</string>
<string name="reboot_download">Újraindítás Download módba</string>
<string name="reboot_edl">Újraindítás EDL módba</string>
<string name="about">Információ</string>
<string name="module_uninstall_confirm">Biztosan eltávolítja a(z) %s modult?</string>
<string name="module_uninstall_success">%s eltávolítva</string>
<string name="module_uninstall_failed">Nem sikerült eltávolítani az %s modult</string>
<string name="module_restore_confirm">Biztosan vissza szeretné állítan a(z) %s modult?</string>
<string name="module_restore_success">%s visszaállítva</string>
<string name="module_restore_failed">Nem sikerült visszaállítani a(z) %s modult</string>
<string name="module_version">Verzió</string>
<string name="module_author">Készítő</string>
<string name="module_id">Azonosító</string>
<string name="module_version_code">Kód</string>
<string name="module_update_json">UpdateJson</string>
<string name="module_update_json_empty">Üres</string>
<string name="enable_developer_options">Engedélyezze a fejlesztői beállításokat</string>
<string name="enable_developer_options_summary">Csak a fejlesztők számára releváns rejtett beállítások és hibakeresési információk megjelenítése.</string>
<string name="module_overlay_fs_not_available">A modulok nem érhetők el, mert az OverlayFS-t a kernel letiltotta.</string>
<string name="refresh">Frissítés</string>
<string name="show_system_apps">Rendszeralkalmazások megjelenítése</string>
<string name="hide_system_apps">Rendszeralkalmazások elrejtése</string>
<string name="export_log">Naplók exportálása</string>
<string name="safe_mode">Biztonságos mód</string>
<string name="reboot_to_apply">Indítsa újra a változtatások érvénybe lépéséhez</string>
<string name="module_magisk_conflict">A modulok a Magiskkel való konfliktus miatt nem érhetők el!</string>
<string name="home_mount_system">Csatolási rendszer</string>
<string name="home_magic_mount">Magic Mount</string>
<string name="home_overlayfs_mount">OverlayFS</string>
<string name="unavailable">Nem elérhető</string>
<string name="use_overlay_fs">Használja az OverlayFS-t</string>
<string name="use_overlay_fs_summary">Váltás az OverlayFS és a Magic Mount módszerek között a KernelSU Next csatolási rendszerében.</string>
<string name="reboot_required">Újraindítás szükséges</string>
<string name="reboot_message">A változtatások a rendszer újraindítása után lépnek életbe. Szeretné most újraindítani?</string>
<string name="module_restore">Modul visszaállítása</string>
<string name="module_restore_message">Modulok visszaállítása biztonsági mentésből</string>
<string name="backup_restore">Mentés &amp; Visszaállítás</string>
<string name="module_backup">Modul biztonsági mentése</string>
<string name="module_backup_message">Biztonsági mentés a jelenleg telepített modulokról.</string>
<string name="allowlist_restore">Engedélyezőlista visszaállítása</string>
<string name="allowlist_restore_message">Engedélyezőlista visszaállítása biztonsági mentésből.</string>
<string name="allowlist_backup">Az engedélyezési lista biztonsági mentése</string>
<string name="allowlist_backup_message">A jelenleg konfigurált engedélyezési lista biztonsági mentése.</string>
<string name="warning">Figyelem</string>
<string name="warning_message">Ez a funkció még béta állapotban van, és fejlesztés alatt áll. Kérjük, a folytatás előtt készítsen biztonsági másolatot a modulokról. Csak akkor használja ezt a funkciót, ha tisztában van a lehetséges kockázatokkal. Óvatosan járjon el.</string>
<string name="proceed">Folytatás</string>
<string name="cancel">Mégse</string>
<string name="later">Később</string>
<string name="home_next_kernelsu">🔥 Next build</string>
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
<string name="home_next_kernelsu_body">Next kísérleti branch. Nézze meg a GitHubon!</string>
<string name="home_experimental_kernelsu">⚠️ Figyelmeztetés kísérleti fejlesztésre!</string>
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
<string name="home_experimental_kernelsu_body">A KernelSU Next egy nem hivatalos verzió, amely folyamatosan kísérleti fejlesztés alatt áll. Az alkalmazás \"ahogy most van\", úgy kerül biztosításra, stabilitás, teljesítmény vagy megbízhatóság tekintetében semmilyen garancia nélkül.</string>
<string name="home_experimental_kernelsu_body_point_1">• Saját felelősségre használja: összeomlások, váratlan viselkedés vagy rendszerproblémák fordulhatnak elő.</string>
<string name="home_experimental_kernelsu_body_point_2">• Nincs garancia: a fejlesztők nem vállalnak felelősséget a használatából eredő adatvesztésért, rendszerkárosodásért vagy egyéb következményekért.</string>
<string name="home_experimental_kernelsu_body_point_3">• Csak tesztelési célokra: azoknak a felhasználóknak készült, akik megértik a kockázatokat, és jártasak a hibaelhárításban.</string>
<string name="about_source_code"><![CDATA[Tekintse meg a forráskódot: %1$s]]></string>
<string name="profile" translatable="false">App Profil</string>
<string name="profile_default">Alapértelmezett</string>
<string name="profile_template">Sablon</string>
<string name="profile_custom">Egyedi</string>
<string name="profile_name">Profil neve</string>
<string name="profile_namespace">Csatolási névtér</string>
<string name="profile_namespace_inherited">Örökölt</string>
<string name="profile_namespace_global">Globális</string>
<string name="profile_namespace_individual">Egyedi</string>
<string name="profile_groups">Csoportok</string>
<string name="profile_capabilities">Adottságok</string>
<string name="profile_selinux_context">SELinux környezet</string>
<string name="profile_umount_modules">Modulok lecsatolása</string>
<string name="failed_to_update_app_profile">Nem sikerült frissíteni a(z) %s alkalmazásprofilját</string>
<string name="require_kernel_version">A jelenlegi KernelSU Next verzió (%1$d) túl alacsony ahhoz, hogy a kezelő megfelelően működjön. Kérjük, frissítsen a(z) %2$d vagy újabb verzióra!</string>
<string name="settings_umount_modules_default">Modulok lecsatolása</string>
<string name="settings_umount_modules_default_summary">A „Modulok lecsatolása” globális alapértelmezett értéke az alkalmazásprofilban. Ha engedélyezve van, eltávolítja a rendszer összes modul-módosítását az olyan alkalmazások esetében, amelyekhez nincs beállítva profil.</string>
<string name="settings_susfs_toggle">A kprobe hook-ok elrejtése</string>
<string name="settings_susfs_toggle_summary">Ez az opció letiltja a ksu által létrehozott kprobe hook-okat, és ehelyett aktiválja a beágyazott, nem kprobe hook-okat, megvalósítva ugyanazt a funkcionalitást, amelyet egy nem GKI kernel esetében alkalmaznának, amely nem támogatja a kprobe-ot.</string>
<string name="profile_umount_modules_summary">Az opció engedélyezése lehetővé teszi, hogy a KernelSU Next visszaállítsa az alkalmazás moduljai által módosított fájlokat.</string>
<string name="profile_selinux_domain">Domain</string>
<string name="profile_selinux_rules">Szabályok</string>
<string name="module_update">Frissítés</string>
<string name="module_downloading">%s modul letöltése</string>
<string name="module_start_downloading">Letöltés indítása: %s</string>
<string name="new_version_available">Új verzió (%s) elérhető, kattintson a frissítéshez.</string>
<string name="launch_app">Indítás</string>
<string name="close">Bezár</string>
<string name="force_stop_app">Kényszer leállítás</string>
<string name="restart_app">Újraindítás</string>
<string name="failed_to_update_sepolicy">Nem sikerült frissíteni a SELinux szabályait a következőhöz: %s</string>
<string name="su_not_allowed">Superuser megadása nem engedélyezett a következőhöz: %s</string>
<string name="module_changelog">Változásnapló</string>
<string name="settings_profile_template">Alkalmazásprofil sablon</string>
<string name="settings_profile_template_summary">Az alkalmazásprofil helyi és online sablonjának kezelése</string>
<string name="app_profile_template_create">Sablon létrehozása</string>
<string name="app_profile_template_edit">Sablon szerkesztése</string>
<string name="app_profile_template_id">Azonosító</string>
<string name="app_profile_template_id_invalid">Érvénytelen sablonazonosító</string>
<string name="app_profile_template_name">Név</string>
<string name="app_profile_template_description">Leírás</string>
<string name="app_profile_template_save">Mentés</string>
<string name="app_profile_template_delete">Törlés</string>
<string name="app_profile_template_view">Sablon megtekintése</string>
<string name="app_profile_template_readonly">Csak olvasható</string>
<string name="app_profile_template_id_exist">A sablonazonosító már létezik!</string>
<string name="app_profile_import_export">Importálás/Exportálás</string>
<string name="app_profile_import_from_clipboard">Importálás a vágólapról</string>
<string name="app_profile_export_to_clipboard">Exportálás vágólapra</string>
<string name="app_profile_template_export_empty">Nem található az exportálandó helyi sablon!</string>
<string name="app_profile_template_import_success">Sikeresen importálva</string>
<string name="app_profile_template_sync">Online sablonok szinkronizálása</string>
<string name="app_profile_template_save_failed">Nem sikerült menteni a sablont</string>
<string name="app_profile_template_import_empty">A vágólap üres!</string>
<string name="module_changelog_failed">A változásnapló lekérése nem sikerült: %s</string>
<string name="settings_check_update">Ellenőrizze a frissítéseket</string>
<string name="settings_check_update_summary">Az alkalmazás megnyitásakor automatikusan ellenőrizze a frissítéseket.</string>
<string name="grant_root_failed">Nem sikerült a root jog megadása!</string>
<string name="action">Tevékenység</string>
<string name="open">Megnyitás</string>
<string name="enable_web_debugging">WebView hibakeresés engedélyezése</string>
<string name="enable_web_debugging_summary">A WebUI hibakeresésére. Kérjük, csak akkor engedélyezze, ha szükséges.</string>
<string name="direct_install">Közvetlen telepítés (ajánlott)</string>
<string name="select_file">Fájl kiválasztása a patcheléshez</string>
<string name="install_inactive_slot">Telepítés inaktív slotba (OTA után)</string>
<string name="install_inactive_slot_warning">Eszköze újraindítás után **KÉNYSZERÍTVE** lesz, hogy a jelenleg inaktív slotból induljon el! Ezt az opciót csak az OTA befejezése után használja. Folytatja?</string>
<string name="install_next">Következő</string>
<string name="select_file_tip">%1$s partíciókép javasolt</string>
<string name="select_kmi">Válassza ki a megfelelő KMI-t</string>
<string name="shrink_sparse_image">Sparse image minimalizálása</string>
<string name="shrink_sparse_image_message">Méretezze át a sparse imaget, ahol a modul található, a tényleges méretre. Vegye figyelembe, hogy ez a modul rendellenes működését okozhatja, ezért kérjük, csak akkor használja, ha szükséges (például biztonsági mentéshez).</string>
<string name="settings_uninstall">Eltávolítás</string>
<string name="settings_uninstall_temporary">Ideiglenes eltávolítás</string>
<string name="settings_uninstall_permanent">Végleges eltávolítás</string>
<string name="settings_restore_stock_image">Gyári képfájl visszaállítása</string>
<string name="settings_uninstall_temporary_message">A KernelSU ideiglenes eltávolítása, a következő újraindítás után állítsa vissza az eredeti állapotot.</string>
<string name="settings_uninstall_permanent_message">A KernelSU Next (Root és az összes modul) teljes és végleges eltávolítása.</string>
<string name="settings_restore_stock_image_message">Állítsa vissza a gyári készletképet (ha létezik biztonsági másolat), amelyet általában az OTA előtt használnak; Ha el kell távolítania a KernelSU Next-t, használja a „Végleges eltávolítás” lehetőséget.</string>
<string name="flashing">Telepítés</string>
<string name="flash_success">Sikeres telepítés</string>
<string name="flash_failed">A telepítés nem sikerült</string>
<string name="selected_lkm">A kiválasztott LKM: %s</string>
<string name="save_log">Mentse a naplókat</string>
<string name="log_saved">A naplók mentve</string>
<string name="send_log">Naplók megosztása</string>
<string name="settings_disable_su">Kapcsolja ki a su kompatibilitást</string>
<string name="settings_disable_su_summary">Ideiglenesen tiltsa le bármely alkalmazás azon képességét, hogy root jogosultságokat szerezzen a su paranccsal (a már meglévő folyamatokat ez nem érinti).</string>
<string name="settings_language">Nyelv</string>
</resources>

Some files were not shown because too many files have changed in this diff Show More