Compare commits

...

401 Commits

Author SHA1 Message Date
topjohnwu
ff4ca74cfe Ban all unwrap usage in codebase 2025-12-08 23:31:04 -08:00
topjohnwu
200665c48a Make jni_hooks.hpp a normal C++ header
[skip ci]
2025-12-07 02:44:19 -08:00
topjohnwu
dd42aa99ea Refactor gen_jni_hooks.py
[skip ci]
2025-12-07 02:25:50 -08:00
Wang Han
0936cdb192 Update nativeForkAndSpecialize signature for A16 QPR2
67a4b1b2fe
2025-12-07 00:18:50 -08:00
topjohnwu
871643dce2 Enable CI for API 36.1 2025-12-07 00:18:50 -08:00
topjohnwu
a510554b21 Disable Zygisk upon incomplete JNI hook
Do not enable Zygisk unless ALL replacements are hooked properly.
This allow Zygisk tests to fail when new signature is introduced.
2025-12-07 00:18:50 -08:00
Arbri çoçka
9cc830c565 Update strings.xml values_sq 2025-12-05 16:22:03 -08:00
hajs1664
ddbac50645 update korean translation 2025-12-05 11:15:21 -08:00
南宫雪珊
b5138a4af0 Update unpack boot image help message 2025-12-05 11:14:45 -08:00
topjohnwu
64752f38e8 Do not unwrap when getting decoder and encoder
Or else things will crash mysteriously when unexpected input occurs
2025-12-05 03:40:18 -08:00
topjohnwu
9ac4b5ce7d Add proper lzma format detection 2025-12-05 03:40:18 -08:00
topjohnwu
505053f9b4 Properly support AVD with minor SDK version 2025-12-04 20:55:46 -08:00
topjohnwu
ccb264f33a Release Magisk v30.6
[skip ci]
2025-12-01 15:46:33 -08:00
topjohnwu
84f7d75d30 Update release.sh
Strip out all canary build logic
2025-12-01 15:27:01 -08:00
南宫雪珊
9a776c22d9 Revert "Use rootfs for magisktmp if possible" 2025-12-01 11:45:34 -08:00
topjohnwu
363566d0d5 Release Magisk v30.5
[skip ci]
2025-12-01 01:52:46 -08:00
topjohnwu
d9dc459bf4 Update system_properties
Fix #9408
2025-12-01 00:25:39 -08:00
topjohnwu
5d6b703622 Move occupy and unoccupy out of base crate 2025-11-29 00:13:41 -08:00
topjohnwu
f7ce9c38e1 Run through clippy and rustfmt 2025-11-29 00:13:41 -08:00
LoveSy
bdbfb40383 Use rootfs for magisktmp if possible 2025-11-29 00:13:41 -08:00
topjohnwu
283fc0f46f Update cargo dependencies 2025-11-28 21:00:48 -08:00
topjohnwu
2c24a41bf2 Update gradle dependencies 2025-11-27 03:36:49 -08:00
topjohnwu
97c93a1f4d Smaller release binary size 2025-11-27 02:00:54 -08:00
topjohnwu
8d534e6de8 Update cxx-rs 2025-11-25 02:29:45 -08:00
topjohnwu
3a60ef2039 Update to ONDK r29.3 2025-11-21 13:28:46 -08:00
Wang Han
52d7eff03f Fix splice direction for ptmx out stream 2025-11-19 15:14:59 -08:00
topjohnwu
020e23ea13 Disable help triggers on subcommands 2025-11-03 16:16:49 -08:00
topjohnwu
1599bfc2c5 Update dependencies 2025-11-02 13:52:32 -08:00
Wang Han
c8d51b38ba Enhance fdt_header validation for empty dtb 2025-11-02 02:42:48 -08:00
Wang Han
f741a4aeb8 Free regex resources in plt_hook_commit
Free regex resources for registered and ignored hooks before clearing the lists.
2025-11-02 01:59:03 -08:00
topjohnwu
4ee2235961 Update dependencies 2025-10-20 10:30:09 -07:00
topjohnwu
536e50c6e0 Support optional trailing positional arguments 2025-10-19 17:15:30 -07:00
topjohnwu
57d9fc6099 Support short only options and switches 2025-10-19 17:15:30 -07:00
topjohnwu
52d8910bdd Cleanup code for EarlyExit during help triggers 2025-10-19 17:15:30 -07:00
topjohnwu
c94bd49a89 Update default help triggers 2025-10-19 17:15:30 -07:00
topjohnwu
b72ba6759e Vendor argh sources
Further customization will come in future commits
2025-10-19 17:15:30 -07:00
topjohnwu
5bcb55b7fc Format Rust imports with rustfmt 2025-10-19 17:15:30 -07:00
topjohnwu
0dc8231585 Make all dependencies workspace = true 2025-10-19 17:15:30 -07:00
Wang Han
470acc93c9 Remove clickable attribute from item_module_md2.xml 2025-10-19 14:02:02 -07:00
Wang Han
0edb80b10f Set module card as non clickable
It's so easy to mis-click card.
2025-10-19 14:02:02 -07:00
topjohnwu
bcc6296d94 Build debug without debug-info 2025-10-03 00:16:17 -07:00
topjohnwu
c3db2e368d Release Magisk v30.4
[skip ci]
2025-10-02 04:30:47 -07:00
topjohnwu
d37da5ca66 Cleanup code 2025-10-02 04:18:20 -07:00
topjohnwu
aac52176ed Support API level as floating point 2025-10-02 04:10:22 -07:00
topjohnwu
78e2fc37e5 Add easy knobs to disable security checks 2025-10-02 04:09:46 -07:00
Wang Han
ca2e40593f Make fetchUpdate safe 2025-10-02 04:03:44 -07:00
LoveSy
c07fdc87e3 Handle second splice() failure gracefully 2025-10-02 04:03:27 -07:00
topjohnwu
7270f5e413 Several minor fixes/improvements 2025-10-02 04:03:08 -07:00
topjohnwu
07cc85ccb1 Default initialize before swap in move constructor
Fix #9373, fix #9384, fix #9400, fix #9404
2025-10-02 04:03:08 -07:00
topjohnwu
d6f17c42d5 Fix logging implementation error 2025-10-02 04:03:08 -07:00
Wang Han
d60806f429 Only reset NB prop when zygisk is enabled 2025-10-02 03:19:32 -07:00
Mohammad Hasan Keramat J
8836a09c8c core: Update Persian translation 2025-09-30 00:21:44 -07:00
topjohnwu
f16e93c7db Release Magisk v30.3
[skip ci]
2025-09-29 21:35:45 -07:00
Thonsi
1b0ddec66e Remove unused code 2025-09-29 02:33:02 -07:00
topjohnwu
cd8820f563 Refactor code for more readability 2025-09-29 01:41:55 -07:00
topjohnwu
b70192ca3e Sync libsepol with upstream AOSP 2025-09-29 01:18:52 -07:00
LoveSy
d42ec5da9a Fix pattern matching for CANARY version 2025-09-29 01:18:52 -07:00
topjohnwu
742913ebcb Support installing Magisk on vendor_boot
Close #9238, fix #8835
2025-09-28 01:10:11 -07:00
topjohnwu
ed206c6480 Upgrade cargo dependencies 2025-09-26 23:37:45 -07:00
topjohnwu
f9a8052583 Improve build.py
Close #8988
2025-09-26 17:00:58 -07:00
topjohnwu
f4fdd516f9 Upgrade gradle dependencies 2025-09-24 03:18:35 -07:00
topjohnwu
5925a71f94 Upgrade cargo dependencies 2025-09-24 03:05:18 -07:00
topjohnwu
3cda9beb93 Cleanup unused bindings 2025-09-24 02:38:18 -07:00
topjohnwu
8b7d1ffcdd Migrate magisk_main to Rust 2025-09-18 03:22:44 -07:00
topjohnwu
8d02d0632e Fix comments 2025-09-18 03:22:44 -07:00
topjohnwu
dd743f6f7e Improve Encodable/Decodable impls 2025-09-18 01:17:28 -07:00
topjohnwu
cf483ad4d2 Migrate connect_daemon to Rust 2025-09-15 14:25:18 -07:00
topjohnwu
4aed644e08 Directly accept RequestCode for connect_daemon 2025-09-15 14:25:18 -07:00
topjohnwu
0acc39cec0 Use bitflags to implement BootState 2025-09-15 14:25:18 -07:00
topjohnwu
8b3a44344f Move bootstages into its own module 2025-09-15 14:25:18 -07:00
topjohnwu
8b49eda85a Migrate daemon_entry to Rust 2025-09-15 14:25:18 -07:00
topjohnwu
7057d4c7f1 Migrate setup_magisk_env to Rust 2025-09-15 14:25:18 -07:00
Radoš Milićev
aab8344058 Update Serbian 2025-09-14 18:42:22 -07:00
topjohnwu
7cccf83b37 Remove unused poll_ctrl implementation 2025-09-14 01:59:04 -07:00
topjohnwu
f10ad93c4e Move more code of daemon_entry into Rust 2025-09-13 01:21:33 -07:00
topjohnwu
f143b5df15 Do not mount directories as mirror
Mounting real directories into worker will cause init to start tracking
the mount point through dev.mnt. This causes issues, so we are forced
to recursively reconstruct the mirror directory structure from scratch.

Fix #9316
2025-09-12 22:01:08 -07:00
topjohnwu
71213cc6f4 Fix path tracking in module.rs 2025-09-12 22:01:08 -07:00
topjohnwu
e2a1774e5b Make logging.rs use nix 2025-09-11 01:17:34 -07:00
topjohnwu
0222527a1e Use bitflags macro 2025-09-11 01:17:34 -07:00
topjohnwu
312bfe1bab Do not leak base::ffi to external crates 2025-09-11 01:17:34 -07:00
topjohnwu
48c62a1dae Disable exit on error for cmdline_logging 2025-09-11 01:17:34 -07:00
rikka
cfc2bcb665 Fix zygisk native bridge library name concatenation order 2025-09-11 01:16:54 -07:00
topjohnwu
94b1ff674f Allow calling remove_all on non-existence file 2025-09-10 03:44:39 -07:00
topjohnwu
111136733a Migrate away from unsafe set_len of Utf8CStr 2025-09-09 22:19:05 -07:00
topjohnwu
c8caaa98f5 Enable mount for nix 2025-09-09 20:17:09 -07:00
topjohnwu
8d28f10a3f Enable zerocopy for nix 2025-09-09 12:04:46 -07:00
topjohnwu
177a456d8b Enable term for nix 2025-09-09 12:04:31 -07:00
topjohnwu
ef4e230258 Use nix for libc functions 2025-09-08 23:59:29 -07:00
topjohnwu
17082af438 Simplify OsError 2025-09-08 11:25:20 -07:00
topjohnwu
1df5b34175 Stop differentiate Error vs ErrorCxx 2025-09-08 11:25:18 -07:00
topjohnwu
ea5fe7525d Simplify LibcReturn 2025-09-08 10:55:57 -07:00
topjohnwu
a75c335261 Update cargo dependencies 2025-09-08 02:24:01 -07:00
topjohnwu
3903f42cf6 Support specify ABI for clippy 2025-09-08 02:23:49 -07:00
topjohnwu
fb0c4ea838 Fallback to userspace copy if splice failed
Fix #9032
2025-09-03 16:10:18 -07:00
topjohnwu
bc89c60977 Run cargo fmt 2025-09-02 22:06:08 -07:00
topjohnwu
bd657c354c Reduce FFI across C++/Rust 2025-09-02 22:06:08 -07:00
MONA
675b5f9565 feat(i18n): Add Hinglish translation 2025-09-02 01:27:58 -07:00
MONA
1b2c43268e feat(i18n): Add Hinglish translation 2025-09-02 01:27:58 -07:00
topjohnwu
653730d75e Make cxx binding generate less code 2025-08-29 01:44:06 -07:00
topjohnwu
d472e9c36e Update cargo dependencies 2025-08-28 22:01:35 -07:00
topjohnwu
484d53ef7e Update to ONDK r29.2 2025-08-28 16:15:59 -07:00
topjohnwu
c4e2985677 Migrate resetprop to Rust 2025-08-27 22:48:48 -07:00
topjohnwu
42d9f87bc9 Cleanup resetprop code 2025-08-27 22:48:48 -07:00
topjohnwu
2e4fa6864c Make Utf8CStr a first class citizen in C++ codebase
Utf8CStr is in many cases a better string view class than
std::string_view, because it provides "view" access to a string buffer
that is guaranteed to be null terminated. It also has the additional
benefit of being UTF-8 verified and can seemlessly cross FFI boundaries.

We would want to start use more Utf8CStr in our existing C++ codebase.
2025-08-27 22:48:48 -07:00
topjohnwu
e2abb648ac Update system_properties 2025-08-27 10:12:51 -07:00
topjohnwu
3599dcedfb Make argh directly parse into Utf8CString 2025-08-27 01:26:41 -07:00
topjohnwu
ea72666df8 Only specify ADB port for tests 2025-08-25 15:34:04 -07:00
topjohnwu
bd2a47ba18 Merge libbase cpp files 2025-08-25 01:31:47 -07:00
topjohnwu
b861671391 Cleanup libbase 2025-08-25 01:31:47 -07:00
topjohnwu
e91fc75d86 Consolidate for_each implementation into Rust 2025-08-25 01:31:47 -07:00
LoveSy
78f5cd55c7 Use lzma-rust2 for xz and lzma compression and decompression 2025-08-24 00:23:55 -07:00
topjohnwu
9787a69528 Make all decoders Read instead of Write
Most libraries only implement Read for decoders
2025-08-24 00:23:55 -07:00
topjohnwu
87b8fe374d Fix magiskboot cli parsing 2025-08-23 20:31:15 -07:00
topjohnwu
7b706bb0cb Cleanup and fix compress/decompress command 2025-08-23 20:31:15 -07:00
topjohnwu
c1491b8d2b Fix LoggedResult implementation error 2025-08-23 15:25:52 -07:00
LoveSy
5cbaf2ae11 Use super let to simplify code 2025-08-22 12:05:44 -07:00
topjohnwu
8ebc6207b4 Merge headers 2025-08-22 12:03:47 -07:00
topjohnwu
7848ee616b Cleanup magiskboot main function 2025-08-22 12:03:47 -07:00
topjohnwu
fd193c3cae Simplify ResultExt implementation
Also introduce OptionExt
2025-08-22 12:03:47 -07:00
topjohnwu
36d33c7a85 Make log_err directly return LoggedResult 2025-08-22 12:03:47 -07:00
topjohnwu
5caf28d27c Hide harmless error reporting 2025-08-22 12:03:47 -07:00
topjohnwu
2c39d0234d Fix compression format detection 2025-08-21 12:21:22 -07:00
topjohnwu
c313812129 Simplify magiskboot FFI 2025-08-21 12:21:22 -07:00
topjohnwu
af51880a81 Introduce CmdArgs for argument parsing in Rust 2025-08-21 12:21:22 -07:00
LoveSy
db8d832707 Move magiskboot cli to argh 2025-08-20 21:40:34 -07:00
Wang Han
8dc23d0ead Avoid triggering magisk --zygote-restart twice
We have already used on restart keyword to inject zygote restart, so
triggering it here on prop is not needed.
2025-08-20 12:34:39 -07:00
topjohnwu
b4287700d5 Increase timeout to 15 minutes 2025-08-20 11:23:18 -07:00
topjohnwu
8d10ab89f2 Set zygisk properties in Rust 2025-08-20 11:23:18 -07:00
topjohnwu
49fdc1addb Prevent setting zygisk prop twice 2025-08-20 11:23:18 -07:00
topjohnwu
1333d3b986 Fix canary emulator 2025-08-18 11:25:47 -07:00
残页
335146a6a2 Update supported API levels 2025-08-17 23:58:43 -07:00
topjohnwu
eaf9527971 Use AOSP ATD for API 36
[skip ci]
2025-08-15 17:25:41 -07:00
LoveSy
da937a88c8 if !restore { set_zygisk_prop(); } 2025-08-15 16:45:01 -07:00
topjohnwu
9476e7282d More borrowing, less copying 2025-08-08 21:06:41 -07:00
topjohnwu
251c3c3e0e Remove old ffi data structure 2025-08-08 21:06:41 -07:00
topjohnwu
cd0eca20b0 Migrate connect.cpp to Rust 2025-08-08 21:06:41 -07:00
topjohnwu
6839cb9ab2 Keep /system/xbin/su on emulators 2025-08-08 21:06:41 -07:00
topjohnwu
d11a3397d8 Reduce verbose logging in Zygisk 2025-08-08 21:06:41 -07:00
topjohnwu
975120d6a6 Release Magisk v30.2
[skip ci]
2025-08-06 03:32:32 -07:00
topjohnwu
e489b3b6dd Migrate load_modules to Rust 2025-08-05 11:24:55 -07:00
topjohnwu
589a270b8d Migrate disable/remove modules to Rust 2025-08-05 11:24:55 -07:00
topjohnwu
7961be5cfa Migrate prepare_modules to Rust 2025-08-05 11:24:55 -07:00
topjohnwu
959430e030 Fix systemless hosts installation 2025-08-05 09:44:51 -07:00
topjohnwu
2923c8ccd1 Add module upgrade test 2025-08-05 09:44:51 -07:00
topjohnwu
7df4a9d74f Add uninstaller.sh test 2025-08-05 09:44:51 -07:00
topjohnwu
bf4ed295da Update cargo dependencies 2025-08-02 13:43:27 -07:00
topjohnwu
a5fca960dc Update gradle and dependencies 2025-08-02 02:29:14 -07:00
topjohnwu
f99912b9db Update libsystem_properties 2025-07-21 13:47:30 -07:00
5ec1cff
a54bdb54e4 Skip avb 1,0 verify if tail contains avb 2.0 header
This way, magiskboot will not print "unexpected ASN.1 DER tag: expected SEQUENCE, got APPLICATION [1] (primitive)".
2025-07-21 00:51:14 -07:00
topjohnwu
cd9851a1fe Add regression test for #9179 2025-07-18 17:58:29 -07:00
Wang Han
9ca469898c Use worker for replace feature
This fixes https://github.com/topjohnwu/Magisk/issues/9179.
2025-07-18 16:57:20 -07:00
𝗛𝗼𝗹𝗶
0665549473 Update Turkish
Missing parts were filled in and made better
2025-07-14 10:46:05 -07:00
topjohnwu
9d7a14b335 Remove unnecessary return 2025-07-14 10:03:22 -07:00
Wang Han
62e29fee74 Treat bind mount failure same as C++ implementation
This fixes #9139 and #9174.
2025-07-14 00:27:24 -07:00
igor
e472db552b Update portuguese/english translations 2025-07-11 10:52:21 -07:00
topjohnwu
466e4bd4e1 Update cargo dependencies 2025-07-11 02:04:33 -07:00
topjohnwu
4cf525c588 Add Android canary builds into CI tests 2025-07-11 00:16:39 -07:00
topjohnwu
c8aec2510d Restrict sccache cache size 2025-07-11 00:16:39 -07:00
topjohnwu
ccbfe0e66e Update gradle dependencies 2025-07-10 15:55:14 -07:00
南宫雪珊
23ea28de6f scripts: fix modules_update dir context 2025-07-10 10:59:39 -07:00
topjohnwu
55c3ee3a6f Move Zygisk code out of module.cpp 2025-07-07 13:43:11 -07:00
vvb2060
2a42ca2b8f app: fix time i18n 2025-07-07 11:04:18 -07:00
topjohnwu
a897e82fa4 Remove release notes
They are embedded into GitHub releases
2025-07-07 10:37:45 -07:00
topjohnwu
ffa15831d3 Add release dates 2025-07-07 10:35:22 -07:00
topjohnwu
a344ebf28c Add v30.1 changelog 2025-07-03 18:02:27 -07:00
topjohnwu
78f7fa348e Release Magisk v30.1
[skip ci]
2025-07-03 03:10:10 -07:00
pndwal
d8c448b99d Update faq.md
Add information on restoring Magisk App functionality when stub and full apps conflict.
2025-07-03 02:51:01 -07:00
topjohnwu
d4b83b6a44 Fix app compilation 2025-07-03 02:42:08 -07:00
vvb2060
e5d36d1d24 app: support config restrict policy 2025-07-03 02:42:08 -07:00
vvb2060
ff18cb8e70 su: support drop capabilities 2025-07-03 02:42:08 -07:00
topjohnwu
37a9724a54 Apply clippy fix 2025-07-02 21:20:14 -07:00
topjohnwu
d660401063 Treat magisk symlinks differently 2025-07-02 21:20:14 -07:00
topjohnwu
88541d6f49 Fix file attribute copy in module mounting logic
Due to various reasons, we cannot directly mount module files in /data
into the real paths. Instead we bind mount the module root directory and
remount this mirror with specific mount-point flags. Relevant to this
bug, the module mount is mounted as read-only, which means the file
attribute copy operation could fail in certain configurations.

The fix here is to always copy file attributes into writable locations,
so either in the tmpfs worker directory, or in the module directory
under /data.

A new test case is added to make sure this regression will no longer
happen again in the future.

Fix #9139
2025-07-02 19:23:46 -07:00
topjohnwu
ecd6129fe5 Add systemless hosts test 2025-07-02 19:23:46 -07:00
topjohnwu
6dfe9df9e2 Run cargo fmt 2025-07-02 19:23:46 -07:00
topjohnwu
e81de7ec36 Release Magisk v30.0
[skip ci]
2025-07-01 10:14:43 -07:00
topjohnwu
c78da1ce24 Update v30.0 changelog 2025-07-01 10:00:38 -07:00
Wang Han
7b2d40987c Refactor magisk bins injection logic
Magisk binary mounting logic is not very clear now. In this commit, it
is rewritten in a more robust way. Now it has following cases in mind:
1) Device has a su binary, magisk need to overlay it
2) Choose the PATH with least files to reduce bind mount
3) Filter path which is not suitable
2025-07-01 02:16:16 -07:00
Wang Han
3a37e8c9c5 Don't clone attributes for magisk symlinks
This avoids use existing attributes for su, which will obviously break
magisk functions.
2025-07-01 02:16:16 -07:00
igor
58b405bce1 Update portuguese/english translation 2025-07-01 01:32:36 -07:00
Wang Han
810174ef73 Ignore set_context() error if magisktmp is /sbin
recreate_sbin() will bind mount original files in /sbin to tmpfs /sbin,
so we have no choice but just log here to let the loop continue.
2025-06-30 17:39:54 -07:00
topjohnwu
690a5ac033 Update to ONDK r28.5 2025-06-30 12:15:43 -07:00
topjohnwu
89aad31f7e Update gradle dependencies 2025-06-26 09:35:18 -07:00
topjohnwu
7124db98e3 Stop involving JSON in release script 2025-06-20 00:59:38 -07:00
topjohnwu
0860e859f7 Stop updating README for each release 2025-06-20 00:32:11 -07:00
topjohnwu
04008949b8 Deprecate canary channel 2025-06-20 00:22:17 -07:00
Wang Han
39f2940bd1 Skip symlink in restore_tmpcon()
If magisktmp is /sbin, there may exist files which is symlink to files in
root dir. As root is RO, setcontext will fail and break iterating loop.
2025-06-16 11:09:33 -07:00
topjohnwu
1460317ebd Cleanup C++ headers 2025-06-16 02:25:38 -07:00
topjohnwu
12340c9bd5 Update gradle version 2025-06-16 02:17:29 -07:00
topjohnwu
c4590fe2ba Reorganize buildSrc 2025-06-10 16:51:31 -07:00
topjohnwu
b36066bbcd Run clippy fix 2025-06-10 16:34:38 -07:00
topjohnwu
65d1c5827c Update dependencies 2025-06-10 16:33:06 -07:00
AshiVered
1d675c8b2e Update strings.xml
Improve Hebrew translations
2025-06-06 17:08:51 -07:00
Wang Han
0b494ed7df Avoid throwing error if chmod a symlink
It is possible that we want to clone attributes of a regular file to a
symlink. In this case, we don't need to error out if chmod fails. Just
skip it.
2025-06-06 17:08:34 -07:00
topjohnwu
48d9fc24eb Update release.sh 2025-06-05 11:00:27 -07:00
topjohnwu
83426f7f36 Update check update logic 2025-06-04 12:50:19 -07:00
Wang Han
0e86d4dbcb Fix file pointer leak on error path 2025-06-03 00:34:52 -07:00
Wang Han
5e050d7456 Check binary existence before injecting zygisk bins 2025-06-03 00:33:40 -07:00
topjohnwu
898580bf90 Update dependencies 2025-06-02 19:51:12 -07:00
topjohnwu
86621a4c46 Fix gradle cache 2025-05-30 11:11:53 -07:00
topjohnwu
a834e72b71 Use sccache for clippy 2025-05-30 11:11:45 -07:00
topjohnwu
d8cf42af16 Reduce unstable feature usage 2025-05-30 11:11:36 -07:00
topjohnwu
8c79d66b7b Update ONDK r28.4 2025-05-30 01:53:26 -07:00
Wang Han
fada8b148a Ensure manager can always bypass su access policy
This fixes https://github.com/topjohnwu/Magisk/issues/9050.
2025-05-21 16:14:46 -07:00
topjohnwu
dc0acea47c Remove C++ I/O streams 2025-05-20 03:26:00 -07:00
topjohnwu
78d1200608 Migrate all compression code to Rust 2025-05-20 03:26:00 -07:00
topjohnwu
527bbc0368 Migrate module mounting to Rust 2025-05-20 03:24:43 -07:00
topjohnwu
4c89c7e2b3 Directly use MagiskJson 2025-05-19 10:40:58 -07:00
topjohnwu
adbea7e313 Improve update check code 2025-05-19 10:23:15 -07:00
vvb2060
76962f965e app: use github api to check updates 2025-05-19 10:23:15 -07:00
topjohnwu
a4b8c5e46b Update app dependencies 2025-05-18 22:24:44 -07:00
The Ali Dev
83c707439c Add Urdu Translation 2025-05-18 22:21:05 -07:00
Radoš Milićev
25dd6121f4 Add author for Serbian translations to .xml files 2025-05-18 21:54:24 -07:00
Radoš Milićev
67f35ad027 Add Serbian latin (values-b+sr+Latn) 2025-05-18 21:54:24 -07:00
topjohnwu
0c4b8afbc5 Simplify JNI hooking code 2025-05-17 02:05:21 -07:00
topjohnwu
34b30d7ce1 Promite Magisk v29.0 to stable 2025-05-16 12:17:53 -07:00
topjohnwu
2215088973 Remove unused files in native directory 2025-05-15 13:48:12 -07:00
topjohnwu
8b7fb6cdde Improve scripts 2025-05-15 02:56:36 -07:00
topjohnwu
94c7dbedf2 Fix signing config
[skip ci]
2025-05-14 15:14:34 -07:00
topjohnwu
b1dc47a047 Release new canary build
[skip ci]
2025-05-14 01:41:38 -07:00
topjohnwu
62b1310d97 Release Magisk v29.0
[skip ci]
2025-05-14 01:26:05 -07:00
topjohnwu
0a86916d3a Fix cleanup 2025-05-14 01:23:54 -07:00
topjohnwu
9907ce57aa Add Magisk r29.0 release notes 2025-05-14 01:13:37 -07:00
topjohnwu
b92626cacc Use sudo instead of su 2025-05-13 17:26:09 -07:00
topjohnwu
5a762f0a8e Move all gradle files into folder app
Decouple java and native projects
2025-05-13 17:04:41 -07:00
topjohnwu
5dd7a7d804 Better ABI support for build.py 2025-05-13 14:35:57 -07:00
topjohnwu
7831f40691 Make tests more granular 2025-05-13 14:08:54 -07:00
topjohnwu
4f4b1ff885 Add sepolicy.rule patching tests 2025-05-13 14:08:54 -07:00
topjohnwu
97901979dd Test replace functionality 2025-05-13 14:08:54 -07:00
topjohnwu
287316842c Fix Android M sepolicy reading 2025-05-13 12:28:10 -07:00
topjohnwu
608786e8f3 Print verbose logs in avd_test.sh and cuttlefish.sh 2025-05-11 02:18:36 -07:00
topjohnwu
9684a35cab Use rust::String::c_str to ensure nil termination 2025-05-09 16:02:46 -07:00
Radoš Milićev
e3e4202954 Update translation of core strings 2025-05-09 11:06:03 -07:00
Radoš Milićev
23c2054d46 Translate stub strings 2025-05-09 11:06:03 -07:00
Wang Han
a20a2a8fa0 Recognize Samsung custom policy version path 2025-05-09 11:03:58 -07:00
topjohnwu
a2896be4a6 Cargo fmt
[skip ci]
2025-05-08 23:29:27 -07:00
LoveSy
e9220a28d9 Use splice to pump tty to avoid userspace copying 2025-05-08 23:20:46 -07:00
vvb2060
cf12087e21 app: disable multiArch 2025-05-08 21:02:26 -07:00
topjohnwu
00c1b36837 Support generating files for C++ IDE 2025-05-07 22:18:44 -07:00
topjohnwu
03e034795d Implement Ord and PartialOrd for Utf8CStr familiy 2025-05-05 11:33:33 -07:00
LoveSy
79c0fafe43 Fix cleanup pre-init mount 2025-05-05 11:00:39 -07:00
vvb2060
d499819ba0 app: ignore androidx meta prop file 2025-05-02 16:40:37 -07:00
vvb2060
86da917174 core: fix mkdirs 2025-05-02 16:39:46 -07:00
ZGX089
30bd7d6555 feat: Improve Arabic translation (stub)
Fixed typos, Grammatical errors and changed/fixed other strings.
2025-05-01 13:47:46 -07:00
ZGX089
e5a12f0f5f feat: Improve Arabic translation
Fix Grammatical errors, typos, and changed/fixed other strings.
2025-05-01 13:47:46 -07:00
topjohnwu
c85a8434c6 Update dependencies 2025-04-29 16:22:45 -07:00
topjohnwu
427a1ca4e5 Release new canary build
[skip ci]
2025-04-29 11:54:17 -07:00
topjohnwu
22884e173a Implement reboot in Rust 2025-04-28 17:22:14 -07:00
topjohnwu
d1829308e9 Move more daemon_start code into Rust 2025-04-28 17:22:14 -07:00
topjohnwu
73840f8721 Migrate selinux.cpp to selinux.rs 2025-04-28 17:22:14 -07:00
topjohnwu
c7d1af9805 Stop using PathBuf in package.rs 2025-04-28 17:22:14 -07:00
topjohnwu
4ad26d3dfb Better path methods 2025-04-28 17:22:14 -07:00
topjohnwu
0c70b7670c Cleanup dir implementations 2025-04-28 17:22:14 -07:00
topjohnwu
f44d044095 Remove Utf8CStrBuffer 2025-04-28 17:22:14 -07:00
topjohnwu
5c1cb13472 Remove AsUtf8CStr trait 2025-04-28 17:22:14 -07:00
topjohnwu
3327fc668e Remove FsPath and FsPathMnt trait
Directly use Utf8CStr
2025-04-28 17:22:14 -07:00
topjohnwu
610945ac54 Remove open_fd macro 2025-04-28 17:22:14 -07:00
Howard Wu
ddf5474917 apt-get update before install to fix ci 2025-04-28 11:16:14 -07:00
Howard Wu
6ba1685ade Fix some seopt log 2025-04-22 03:25:21 -07:00
topjohnwu
e02b5f7868 Rename cstr_buf to cstr::buf 2025-04-22 03:21:00 -07:00
topjohnwu
ab2e5d1e7e Make FsPathBuf a trait and rename to FsPathBuilder 2025-04-22 03:21:00 -07:00
topjohnwu
f3fef7bfe4 Make FsPath a trait 2025-04-22 03:21:00 -07:00
topjohnwu
c34c7838bb Cleanup cstr implementation 2025-04-22 03:21:00 -07:00
topjohnwu
c8a16b0e0c Remove unused code 2025-04-16 17:13:03 -07:00
topjohnwu
14f9ed91a1 Remove unused methods 2025-04-15 11:35:31 -07:00
topjohnwu
7a207d4ccf Only accept UTF-8 directory entries 2025-04-15 10:26:22 -07:00
topjohnwu
92a42d901f Move most implementation into Directory 2025-04-15 10:26:22 -07:00
topjohnwu
084d89fcce Create Utf8CStrBuffer type 2025-04-15 10:26:22 -07:00
topjohnwu
55b036c071 Introduce BorrowedDirectory 2025-04-15 10:26:22 -07:00
topjohnwu
30e79310ab Make pointers NonNull after error check 2025-04-15 00:18:48 -07:00
topjohnwu
f063fa5054 Cleanup xwrap implementation 2025-04-15 00:18:48 -07:00
topjohnwu
7bd901273c Provide richer error messages
Make sure most syscall/libc calls results are mapped to OsResult
that can produce more detailed error messages.
2025-04-15 00:18:48 -07:00
topjohnwu
c1e061603b Specify ADB_SERIAL for emulator 2025-04-13 21:43:11 -07:00
topjohnwu
cb08504fe5 Update cargo dependencies 2025-04-11 14:48:16 -07:00
topjohnwu
c0a1fb77be Code cleanup 2025-04-11 14:48:01 -07:00
LoveSy
4864c1112a no pty for -c by default, and add -i to force pty 2025-04-11 13:21:10 -07:00
LoveSy
9ddeab034b Fix wrong tty pump
See #1463
2025-04-11 13:21:10 -07:00
LoveSy
c4847ed288 Move pts to rust, and avoid using thread 2025-04-11 13:21:10 -07:00
topjohnwu
b8f1523fb2 Minor code reorg
[skip ci]
2025-04-08 17:20:22 -07:00
topjohnwu
fb7fa8a6b3 Update to ONDK r29.1 2025-04-08 12:11:59 -07:00
topjohnwu
9c7d359093 Optimize and format imports
[skip ci]
2025-04-08 09:57:09 -07:00
topjohnwu
eb54bc1fd7 Cleanup unused code 2025-04-08 02:33:52 -07:00
topjohnwu
d4a0286e13 Migrate magiskinit selinux.cpp to Rust 2025-04-08 02:33:52 -07:00
Steven Xu
83e66767ff refactor: use empty navOptions 2025-04-02 09:13:32 -07:00
Steven Xu
7dc010749b feat: remove animation settings button transition 2025-04-02 09:13:32 -07:00
Steven Xu
8e8d013b1b feat: remove log overscroll 2025-04-02 09:13:32 -07:00
Steven Xu
bba0373808 feat: remove navigation transition when clicking buttons on the bottom bar 2025-04-02 09:13:32 -07:00
topjohnwu
1fa318dc8c Use Rust elf-cleaner implementation 2025-04-01 18:32:54 -07:00
cheesetosti
6edc5e2037 Update install.md
fixed grammar n stuff
2025-04-01 12:13:29 -07:00
topjohnwu
1523ed9f78 Always go through rustup proxies 2025-04-01 10:01:35 -07:00
topjohnwu
8e604d2ab8 Update cuttlefish CI 2025-03-28 00:12:31 -07:00
topjohnwu
2aba7247a9 Skip stub APK install on emulator
Reduce test flakiness
2025-03-26 13:15:12 -07:00
topjohnwu
e66fe8533e API 36 does not support wait_for_bootanim 2025-03-26 13:15:12 -07:00
vvb2060
b03fbb3917 avd_test: upgrade to android16 beta3 2025-03-26 13:15:12 -07:00
vvb2060
c2ece62e4c native: delete global 16k option
NDK 28 enable 16 KiB page size compatibility option by default, delete the global option to restore 4k alignment for 32-bit arch.
2025-03-26 13:15:12 -07:00
vvb2060
8c972dcf34 app: target sdk 36 2025-03-26 13:15:12 -07:00
topjohnwu
50af14f2a3 Move all MagiskInit entrypoints into init.rs 2025-03-24 17:26:03 -07:00
topjohnwu
e0a356b319 Introduce mount helper methods 2025-03-24 17:26:03 -07:00
topjohnwu
c09a792958 Reorganize magiskinit code 2025-03-24 17:26:03 -07:00
topjohnwu
0bbfe7f44d Fix 2SI on legacy SAR devices 2025-03-24 17:26:03 -07:00
topjohnwu
a396abf565 Minor changes
[skip ci]
2025-03-22 01:16:51 -07:00
topjohnwu
1e3edb8883 Release new canary build
[skip ci]
2025-03-21 10:37:49 -07:00
topjohnwu
3b8b61bf35 Remove ZipUtils.kt 2025-03-20 14:54:25 -07:00
topjohnwu
6f90456036 Properly buffer I/O 2025-03-20 13:16:39 -07:00
topjohnwu
f56fd4e215 Always close outputStream in processFile
Fix #8735
2025-03-19 17:57:31 -07:00
topjohnwu
aa35aac5d5 Update dependencies 2025-03-19 15:55:06 -07:00
topjohnwu
1f162b819d Update ONDK r29.0 2025-03-19 10:55:08 -07:00
Wang Han
52ef1d1cb2 Simplify matching selinux context of child zygote (#8845) 2025-03-11 01:27:15 -07:00
John Wu
f14e3a89cc Enable optimize_for_size for Rust std (#8844) 2025-03-10 15:50:43 -07:00
topjohnwu
95d3eac2e0 Cleanup xwrap functions 2025-03-09 01:10:41 -08:00
Wang Han
8e73536e02 Remove unused hasGMS variable 2025-03-09 00:16:25 -08:00
LoveSy
12a0870bc9 Replace bzip2 with bz2-rs 2025-03-08 14:37:17 -08:00
topjohnwu
6ff82c4e86 Introduce FsPathFollow
Make sure all operations of FsPath do not follow symlinks, and provide
a way to explicitly switch over to a set of operations that DO follow
symlinks by FsPath::follow_link.
2025-03-07 15:51:51 -08:00
LoveSy
c64de35375 Move magiskpolicy cli to argh 2025-03-07 14:29:30 -08:00
topjohnwu
ee5283f4e8 Update release script 2025-03-07 14:14:06 -08:00
LoveSy
bd0e954fea Replace zlib with zlib-rs 2025-03-07 11:40:02 -08:00
topjohnwu
675471a49e Upgrade argh to stable release 2025-03-07 02:38:36 -08:00
topjohnwu
c90e73ccec Migration to Edition 2024 2025-03-07 02:35:25 -08:00
topjohnwu
a43c1267d8 Update Cargo.toml 2025-03-07 02:35:25 -08:00
vvb2060
e8958c6b5c get_secontext: ignore ENODATA 2025-03-06 20:03:36 -08:00
LoveSy
e8a3bf82c6 set exit code of log ExitOnError to -1 2025-03-06 20:03:15 -08:00
topjohnwu
27fd79176a Update ONDK to r28.3 2025-03-06 17:41:28 -08:00
topjohnwu
28d86a3454 Update rustup_wrapper
[skip ci]
2025-03-06 16:12:35 -08:00
topjohnwu
c6c1a17ae6 Address several clippy warnings 2025-03-03 02:15:14 -08:00
topjohnwu
2b47d47215 Also run clippy with release mode
[skip ci]
2025-03-02 23:14:46 -08:00
David K.
0e82df9e10 Support zImage compression types other than gzip.
Instead of just searching for the gzip magic, it now incrementally searches the kernel for the first thing that `check_fmt_lg` doesn't report as `UNKNOWN`.
2025-03-02 13:35:13 -08:00
topjohnwu
893821ad88 Skip all tests on master push 2025-03-02 02:30:11 -08:00
topjohnwu
6b80fbfa99 Fix cache save condition 2025-03-02 02:30:11 -08:00
topjohnwu
8c3c7d0194 Build on master push 2025-03-02 01:51:42 -08:00
topjohnwu
b94a3d9f2f Do not store cache on pull request 2025-03-02 01:51:42 -08:00
Wang Han
442d0b5ddc Delete bootctl binary if execution fails
New devices may use AIDL bootctrl HAL, so if bootctl hal-info fails,
simply remove the temp file and return.
2025-03-01 22:43:55 -08:00
topjohnwu
494615d9a0 Support ./build.py emulator with an APK argument 2025-02-28 17:17:24 -08:00
vvb2060
afbfb81837 docs: add avd_magisk.sh to faq 2025-02-28 17:17:24 -08:00
vvb2060
3ed4e258a3 avd_magisk: add general usage 2025-02-28 17:17:24 -08:00
vvb2060
dddd41c95b avd_magisk: support rootfs without sbin 2025-02-28 17:17:24 -08:00
topjohnwu
5f2ca81e86 Update AGP 2025-02-28 13:19:16 -08:00
topjohnwu
c9eac0c438 Introduce new sepolicy strategy for legacy devices
The existing sepolicy patching strategy looks like this:

1. 2SI: use LD_PRELOAD to hijack `security_load_policy`
2. Split policy: devices using split policy implies it also needs to
   do early mount, which means fstab is stored in device tree.
   So we do the following:
   - Hijack the fstab node in the device tree in sysfs
   - Wait for init to mount selinuxfs for us
   - Hijack selinuxfs to intercept sepolicy loading
3. Monolithic policy: directly patch `/sepolicy`

Method #1 and #2 both has the magiskinit pre-init daemon handling
the sepolicy patching and loading process, while method #3 gives us
zero control over sepolicy loading process. Downsides:

a. Pre-init daemon bypasses the need to guess which sepolicy init
   will load, because the original init will literally send the stock
   sepolicy file directly to us with this approach.
b. If we want to add more features/functionalities during the sepolicy
   patching process, we will leave out devices using method #3

In order to solve these issues, we completely redesign the sepolicy
patching strategy for non-2SI devices. Instead of limiting usage of
pre-init daemon to early mount devices, we always intercept the
sepolicy loading process regardless of the Android version and device
setup. This will give us a unified implementation for sepolicy patching,
and will make it easier to develop further new features down the line.
2025-02-28 09:39:10 -08:00
topjohnwu
b6b34f7612 Fix overlay.d context preservation 2025-02-27 01:57:25 -08:00
LoveSy
e55c413261 Correctly handle truncated dtb 2025-02-23 20:31:55 -08:00
topjohnwu
0399cde50a Cleanup logcat.log for each invocation 2025-02-18 01:04:19 -08:00
topjohnwu
019eb03823 Hide or remove mut constructors for Utf8CStr 2025-02-17 11:38:11 -08:00
topjohnwu
363410e1c0 Introduce cstr_buf helper functions 2025-02-17 11:32:21 -08:00
topjohnwu
fc2ef21660 Introduce path! macro for FsPath 2025-02-17 01:46:19 -08:00
topjohnwu
18cb659ff3 Run clippy through build.py 2025-02-17 01:31:59 -08:00
topjohnwu
63231d97ce Properly handle db downgrades 2025-02-16 17:01:36 -08:00
topjohnwu
9ac81a8a25 Skip module tests on API < 26 2025-02-16 16:20:09 -08:00
topjohnwu
79af2787ae Workaround potential OOM when signing APKs 2025-02-16 16:20:09 -08:00
topjohnwu
f5f9b285c0 Add module tests 2025-02-16 16:20:09 -08:00
topjohnwu
6c05f2ae85 Test processing Shamiko module zip 2025-02-16 16:20:09 -08:00
topjohnwu
29043e1684 Consolidate setup methods 2025-02-16 16:20:09 -08:00
topjohnwu
b73d4a7022 Fix log_ok() 2025-02-16 12:01:25 -08:00
topjohnwu
ad95e8951b Skip download in lsposed setup test
Download the zip during build time
2025-02-16 01:26:40 -08:00
topjohnwu
bf591fca12 Fix Utf8CString constructor and add more comments 2025-02-16 01:17:48 -08:00
topjohnwu
dcf027884d Update FsPathBuf 2025-02-15 18:27:45 -08:00
topjohnwu
584f3820fe Make all Utf8CStrWrite Utf8CStrBuf 2025-02-15 18:27:45 -08:00
topjohnwu
3c7c46307a Partially cleanup MagiskInit code 2025-02-15 18:27:45 -08:00
vvb2060
4d80361805 core: search for first available dir in PATH 2025-02-15 15:08:26 -08:00
LoveSy
9a74e19117 Add log_ok() for log().ok() 2025-02-14 14:24:13 -08:00
LoveSy
b1e17706a4 Format code 2025-02-14 14:24:13 -08:00
LoveSy
caad129d69 Move MagiskInit::patch_sepolicy to rust 2025-02-14 14:24:13 -08:00
LoveSy
da58571ce5 Remove redundant rust export 2025-02-14 14:24:13 -08:00
LoveSy
2aa7f1c094 Move MagiskInit::check_two_stage to rust 2025-02-14 14:24:13 -08:00
LoveSy
823e31a91b Use linker to link vfprintf as tiny_vfprintf 2025-02-14 14:24:13 -08:00
LoveSy
fb926ae302 Move MagiskInit::redirect_second_stage to rust 2025-02-14 14:24:13 -08:00
LoveSy
e0489eeffd Move MagiskInit::first_stage to rust 2025-02-14 14:24:13 -08:00
LoveSy
dc9d5a4cac Move MagiskInit::second_stage to rust 2025-02-14 14:24:13 -08:00
LoveSy
143743d0b0 Refactor init.cpp to init.rs 2025-02-14 14:24:13 -08:00
LoveSy
563f0d5ad5 Move BootConfig::print to rust 2025-02-14 14:24:13 -08:00
LoveSy
c99f4a591b Move MagiskInit::exec_init to rust 2025-02-14 14:24:13 -08:00
LoveSy
449204e380 Move MagiskInit::prepare_data to rust 2025-02-14 14:24:13 -08:00
LoveSy
a85c4c6528 Move MagiskInit::MagiskInit to rust 2025-02-14 14:24:13 -08:00
LoveSy
d203a6fff6 Move MagiskInit to rust 2025-02-14 14:24:13 -08:00
LoveSy
6c612d66d7 Move BootConfig to rust 2025-02-14 14:24:13 -08:00
topjohnwu
540253a55b Remove unnecessary FFI 2025-02-14 11:24:46 -08:00
topjohnwu
15b7c4ccd1 Fix tmpfs mounts in avd_magisk.sh 2025-02-14 10:17:31 -08:00
topjohnwu
442d5335ea Consolidate get_module_fds implementation
Close #8767
2025-02-12 02:55:27 +08:00
topjohnwu
8a80eea597 Directly deal with Rust &str in sepolicy.cpp 2025-02-12 01:26:06 +08:00
Wang Han
5e35703091 Ensure target path exists before mknod
Co-authored-by: LoveSy <shana@zju.edu.cn>
2025-02-12 01:13:56 +08:00
topjohnwu
b7ca73f431 Remove an additional unique_ptr indirection 2025-02-05 14:18:16 +08:00
Wang Han
a14fc90f07 Fix fetching notification settings from db (#8761)
Co-authored-by: LoveSy <shana@zju.edu.cn>
2025-02-04 17:42:21 +08:00
LoveSy
c913f7ec74 Make sepolicy a shared type between rust and cxx 2025-02-04 00:36:11 +08:00
topjohnwu
7f6c9e8411 Fix zygisk module load 2025-02-03 23:21:51 +08:00
topjohnwu
bb02ea3a20 Fix file descriptor IPC 2025-02-03 18:21:03 +08:00
LoveSy
3981c9665e Replace rust inner functions to try blocks 2025-02-02 22:09:55 +08:00
topjohnwu
88628fdf3c Make sure IPC is arch agnostic 2025-02-02 22:08:41 +08:00
topjohnwu
0469817781 Cleanup code and bindings 2025-02-02 22:08:41 +08:00
topjohnwu
a786801141 Implement su_daemon in Rust 2025-02-02 22:08:41 +08:00
topjohnwu
ab86732c89 Implement simple serialization over IPC 2025-02-02 22:08:41 +08:00
topjohnwu
59622d1688 Use static methods in cxx-rs 2025-02-02 02:46:33 +08:00
LoveSy
58a25a3e2b Fix su with tty 2025-02-01 16:50:53 +08:00
topjohnwu
15dca29a87 Update cxx-rs 2025-02-01 02:02:29 +08:00
Wang Han
46980819c0 Expose safe mode option on 28+ 2025-01-31 12:20:02 +08:00
topjohnwu
4fb6a7268c Fix SDK 27 and 28 tests 2025-01-31 02:52:27 +08:00
topjohnwu
c05e963f37 Address clippy warnings 2025-01-31 02:52:27 +08:00
topjohnwu
7f7f625864 Code reorganization 2025-01-31 02:52:27 +08:00
topjohnwu
b25aa8295a Move bootstage into Rust 2025-01-31 02:52:27 +08:00
topjohnwu
15a605765c Fully implement daemon side of Zygisk in Rust 2025-01-31 02:52:27 +08:00
topjohnwu
b575c95710 Implement fd I/O on Rust side 2025-01-31 02:52:27 +08:00
topjohnwu
a48a9c858a Migrate zygisk handler to Rust 2025-01-31 02:52:27 +08:00
topjohnwu
0d8d6290a3 Move module list into MagiskD 2025-01-31 02:52:27 +08:00
topjohnwu
4dcd733ddd Minor code cleanup 2025-01-31 02:52:27 +08:00
334 changed files with 20984 additions and 15794 deletions

6
.gitattributes vendored
View File

@@ -12,13 +12,11 @@
# Denote all files that are truly binary and should not be modified.
tools/** binary
tools/rustup-wrapper/** -binary
tools/elf-cleaner/** -binary
*.jar binary
*.exe binary
*.apk binary
*.png binary
*.jpg binary
*.ttf binary
# Help GitHub detect languages
native/jni/external/** linguist-vendored
native/jni/systemproperties/** linguist-language=C++

View File

@@ -26,6 +26,15 @@ runs:
- name: Cache sccache
uses: actions/cache@v4
if: ${{ github.event_name != 'pull_request' }}
with:
path: .sccache
key: sccache-${{ runner.os }}-${{ github.sha }}
restore-keys: sccache-${{ runner.os }}-
- name: Restore sccache
uses: actions/cache/restore@v4
if: ${{ github.event_name == 'pull_request' }}
with:
path: .sccache
key: sccache-${{ runner.os }}-${{ github.sha }}
@@ -36,7 +45,7 @@ runs:
env:
SCCACHE_DIRECT: false
SCCACHE_DIR: ${{ github.workspace }}/.sccache
SCCACHE_CACHE_SIZE: 2G
SCCACHE_CACHE_SIZE: ${{ inputs.is-asset-build == 'true' && '2G' || '300M' }}
SCCACHE_IDLE_TIMEOUT: 0
run: |
bash $GITHUB_ACTION_PATH/sccache.sh
@@ -55,18 +64,18 @@ runs:
- name: Cache Gradle dependencies
uses: actions/cache@v4
if: inputs.is-asset-build == 'true'
if: ${{ inputs.is-asset-build == 'true' && github.event_name != 'pull_request' }}
with:
path: |
.gradle/caches
.gradle/wrapper
!.gradle/caches/build-cache-*
key: gradle-cache-${{ hashFiles('gradle/**') }}
key: gradle-cache-${{ hashFiles('app/gradle/**') }}
restore-keys: gradle-cache-
- name: Restore Gradle dependencies
uses: actions/cache/restore@v4
if: inputs.is-asset-build == 'false'
if: ${{ inputs.is-asset-build == 'false' || github.event_name == 'pull_request' }}
with:
path: |
.gradle/caches
@@ -78,19 +87,17 @@ runs:
- name: Cache Gradle build cache
uses: actions/cache@v4
if: inputs.is-asset-build == 'true'
if: ${{ inputs.is-asset-build == 'true' && github.event_name != 'pull_request' }}
with:
path: |
.gradle/caches/build-cache-*
path: .gradle/caches/build-cache-*
key: gradle-build-cache-${{ github.sha }}
restore-keys: gradle-build-cache-
- name: Restore Gradle build cache
uses: actions/cache/restore@v4
if: inputs.is-asset-build == 'false'
if: ${{ inputs.is-asset-build == 'false' || github.event_name == 'pull_request' }}
with:
path: |
.gradle/caches/build-cache-*
path: .gradle/caches/build-cache-*
key: gradle-build-cache-${{ github.sha }}
restore-keys: gradle-build-cache-
enableCrossOsArchive: true

View File

@@ -1,6 +1,13 @@
name: Magisk Build
on:
push:
branches: [master]
paths:
- "app/**"
- "native/**"
- "build.py"
- ".github/workflows/build.yml"
pull_request:
branches: [master]
workflow_dispatch:
@@ -29,7 +36,7 @@ jobs:
run: ./build.py -v all
- name: Stop gradle daemon
run: ./gradlew --stop
run: ./app/gradlew --stop
- name: Upload build artifact
uses: actions/upload-artifact@v4
@@ -65,21 +72,20 @@ jobs:
run: python build.py -v -c .github/ci.prop all
- name: Stop gradle daemon
run: ./gradlew --stop
run: ./app/gradlew --stop
avd-test:
name: Test API ${{ matrix.version }} (x86_64)
runs-on: ubuntu-24.04
needs: build
if: ${{ github.event_name != 'push' }}
strategy:
fail-fast: false
matrix:
version: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
version: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36.1, "CANARY"]
type: [""]
include:
- version: "Baklava"
type: "google_apis"
- version: "Baklava"
- version: "CANARY"
type: "google_apis_ps16k"
steps:
@@ -99,10 +105,10 @@ jobs:
sudo udevadm trigger --name-match=kvm
- name: Run AVD test
timeout-minutes: 10
timeout-minutes: 15
env:
AVD_TEST_LOG: 1
run: scripts/avd_test.sh ${{ matrix.version }} ${{ matrix.type }}
run: scripts/avd.sh test ${{ matrix.version }} ${{ matrix.type }}
- name: Upload logs on error
if: ${{ failure() }}
@@ -117,6 +123,7 @@ jobs:
name: Test API ${{ matrix.version }} (x86)
runs-on: ubuntu-24.04
needs: build
if: ${{ github.event_name != 'push' }}
strategy:
fail-fast: false
matrix:
@@ -139,11 +146,11 @@ jobs:
sudo udevadm trigger --name-match=kvm
- name: Run AVD test
timeout-minutes: 10
timeout-minutes: 15
env:
FORCE_32_BIT: 1
AVD_TEST_LOG: 1
run: scripts/avd_test.sh ${{ matrix.version }}
run: scripts/avd.sh test ${{ matrix.version }}
- name: Upload logs on error
if: ${{ failure() }}
@@ -158,14 +165,15 @@ jobs:
name: Test ${{ matrix.device }}
runs-on: ubuntu-24.04
needs: build
if: ${{ github.event_name != 'push' }}
env:
CF_HOME: /home/runner/aosp_cf_phone
strategy:
fail-fast: false
matrix:
include:
- branch: "aosp-main"
device: "aosp_cf_x86_64_phone"
- branch: "aosp-android-latest-release"
device: "aosp_cf_x86_64_only_phone"
steps:
- name: Check out
@@ -183,8 +191,8 @@ jobs:
scripts/cuttlefish.sh download ${{ matrix.branch }} ${{ matrix.device }}
- name: Run Cuttlefish test
timeout-minutes: 10
run: su $USER -c 'scripts/cuttlefish.sh test'
timeout-minutes: 15
run: sudo -E -u $USER scripts/cuttlefish.sh test
- name: Upload logs on error
if: ${{ failure() }}

10
.gitignore vendored
View File

@@ -2,19 +2,13 @@ out
*.zip
*.jks
*.apk
*.log
/config.prop
/notes.md
/update.sh
/app/dict.txt
# Built binaries
native/out
# Android Studio / Gradle
# Android Studio
*.iml
.gradle
.idea
.kotlin
/local.properties
/build
/captures

15
.gitmodules vendored
View File

@@ -4,21 +4,9 @@
[submodule "lz4"]
path = native/src/external/lz4
url = https://github.com/lz4/lz4.git
[submodule "bzip2"]
path = native/src/external/bzip2
url = https://github.com/nemequ/bzip2.git
[submodule "xz"]
path = native/src/external/xz
url = https://github.com/xz-mirror/xz.git
[submodule "libcxx"]
path = native/src/external/libcxx
url = https://github.com/topjohnwu/libcxx.git
[submodule "zlib"]
path = native/src/external/zlib
url = https://android.googlesource.com/platform/external/zlib
[submodule "zopfli"]
path = native/src/external/zopfli
url = https://github.com/google/zopfli.git
[submodule "cxx-rs"]
path = native/src/external/cxx-rs
url = https://github.com/topjohnwu/cxx.git
@@ -31,6 +19,3 @@
[submodule "crt0"]
path = native/src/external/crt0
url = https://github.com/topjohnwu/crt0.git
[submodule "termux-elf-cleaner"]
path = tools/termux-elf-cleaner
url = https://github.com/termux/termux-elf-cleaner.git

View File

@@ -16,13 +16,7 @@ Some highlight features:
## Downloads
[Github](https://github.com/topjohnwu/Magisk/) is the only source where you can get official Magisk information and downloads.
Click the icon below to download Magisk apk.
[![](https://img.shields.io/badge/Magisk-v28.1-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v28.1)
[![](https://img.shields.io/badge/Magisk%20Beta-v28.1-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v28.1)
[![](https://img.shields.io/badge/Magisk-Canary-red)](https://github.com/topjohnwu/Magisk/releases/tag/canary-28102)
[Github](https://github.com/topjohnwu/Magisk/releases) is the only source where you can get official Magisk information and downloads.
## Useful Links

7
app/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
/dict.txt
# Gradle
.gradle
.kotlin
/local.properties
/build

View File

@@ -35,7 +35,7 @@ android {
}
dependencies {
implementation(project(":app:core"))
implementation(project(":core"))
coreLibraryDesugaring(libs.jdk.libs)
implementation(libs.indeterminate.checkbox)

View File

@@ -1,10 +1,13 @@
package com.topjohnwu.magisk.arch
import android.content.ContentResolver
import android.view.KeyEvent
import androidx.databinding.ViewDataBinding
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.navOptions
import com.topjohnwu.magisk.utils.AccessibilityUtils
abstract class NavigationActivity<Binding : ViewDataBinding> : UIActivity<Binding>() {
@@ -31,7 +34,17 @@ abstract class NavigationActivity<Binding : ViewDataBinding> : UIActivity<Bindin
}
}
companion object {
fun navigate(directions: NavDirections, navigation: NavController, cr: ContentResolver) {
if (AccessibilityUtils.isAnimationEnabled(cr)) {
navigation.navigate(directions)
} else {
navigation.navigate(directions, navOptions {})
}
}
}
fun NavDirections.navigate() {
navigation.navigate(this)
navigate(this, navigation, contentResolver)
}
}

View File

@@ -24,6 +24,7 @@ import androidx.core.widget.ImageViewCompat
import androidx.databinding.BindingAdapter
import androidx.databinding.InverseBindingAdapter
import androidx.databinding.InverseBindingListener
import androidx.databinding.InverseMethod
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.GridLayoutManager
@@ -33,9 +34,11 @@ import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView
import com.google.android.material.chip.Chip
import com.google.android.material.slider.Slider
import com.google.android.material.textfield.TextInputLayout
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.superuser.internal.UiThreadHandler
import com.topjohnwu.widget.IndeterminateCheckBox
@@ -306,3 +309,38 @@ fun TextView.setText(text: TextHolder) {
fun Spinner.setAdapter(items: Array<Any>, layoutRes: Int) {
adapter = ArrayAdapter(context, layoutRes, items)
}
@BindingAdapter("labelFormatter")
fun Slider.setLabelFormatter(formatter: (Float) -> Int) {
setLabelFormatter { value -> resources.getString(formatter(value)) }
}
@InverseBindingAdapter(attribute = "android:value")
fun Slider.getValueBinding() = value
@BindingAdapter("android:valueAttrChanged")
fun Slider.setListener(attrChange: InverseBindingListener) {
addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
override fun onStartTrackingTouch(slider: Slider) = Unit
override fun onStopTrackingTouch(slider: Slider) = attrChange.onChange()
})
}
@InverseMethod("sliderValueToPolicy")
fun policyToSliderValue(policy: Int): Float {
return when (policy) {
SuPolicy.DENY -> 1f
SuPolicy.RESTRICT -> 2f
SuPolicy.ALLOW -> 3f
else -> 1f
}
}
fun sliderValueToPolicy(value: Float): Int {
return when (value) {
1f -> SuPolicy.DENY
2f -> SuPolicy.RESTRICT
3f -> SuPolicy.ALLOW
else -> SuPolicy.DENY
}
}

View File

@@ -3,7 +3,6 @@ package com.topjohnwu.magisk.dialog
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.download.DownloadEngine
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.view.MagiskDialog
@@ -11,15 +10,10 @@ import java.io.File
class ManagerInstallDialog : MarkDownDialog() {
private val svc get() = ServiceLocator.networkService
override suspend fun getMarkdownText(): String {
val text = svc.fetchString(Info.remote.magisk.note)
val text = Info.update.note
// Cache the changelog
AppContext.cacheDir.listFiles { _, name -> name.endsWith(".md") }.orEmpty().forEach {
it.delete()
}
File(AppContext.cacheDir, "${Info.remote.magisk.versionCode}.md").writeText(text)
File(AppContext.cacheDir, "${Info.update.versionCode}.md").writeText(text)
return text
}

View File

@@ -17,6 +17,8 @@ import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.DownloadEngine
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
import com.topjohnwu.magisk.core.R as CoreR
import androidx.navigation.findNavController
import com.topjohnwu.magisk.arch.NavigationActivity
class HomeFragment : BaseFragment<FragmentHomeMd2Binding>(), MenuProvider {
@@ -68,7 +70,13 @@ class HomeFragment : BaseFragment<FragmentHomeMd2Binding>(), MenuProvider {
override fun onMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_settings ->
HomeFragmentDirections.actionHomeFragmentToSettingsFragment().navigate()
activity?.let {
NavigationActivity.navigate(
HomeFragmentDirections.actionHomeFragmentToSettingsFragment(),
it.findNavController(R.id.main_nav_host),
it.contentResolver,
)
}
R.id.action_reboot -> activity?.let { RebootMenu.inflate(it).show() }
else -> return super.onOptionsItemSelected(item)
}

View File

@@ -91,16 +91,15 @@ class HomeViewModel(
override suspend fun doLoadWork() {
appState = State.LOADING
Info.getRemote(svc)?.apply {
Info.fetchUpdate(svc)?.apply {
appState = when {
BuildConfig.APP_VERSION_CODE < magisk.versionCode -> State.OUTDATED
BuildConfig.APP_VERSION_CODE < versionCode -> State.OUTDATED
else -> State.UP_TO_DATE
}
val isDebug = Config.updateChannel == Config.Value.DEBUG_CHANNEL
managerRemoteVersion =
("${magisk.version} (${magisk.versionCode})" +
if (isDebug) " (D)" else "").asText()
("$version (${versionCode})" + if (isDebug) " (D)" else "").asText()
} ?: run {
appState = State.INVALID
managerRemoteVersion = CoreR.string.not_available.asText()

View File

@@ -41,7 +41,7 @@ object RebootMenu {
activity.getSystemService<PowerManager>()?.isRebootingUserspaceSupported == true) {
menu.menu.findItem(R.id.action_reboot_userspace).isVisible = true
}
if (Const.Version.isCanary()) {
if (Const.Version.atLeast_28_0()) {
menu.menu.findItem(R.id.action_reboot_safe_mode).isChecked = Config.bootloop >= 2
} else {
menu.menu.findItem(R.id.action_reboot_safe_mode).isVisible = false

View File

@@ -14,9 +14,8 @@ import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.BuildConfig.APP_VERSION_CODE
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.ContentResultCallback
import com.topjohnwu.magisk.core.ktx.toast
@@ -70,17 +69,17 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
init {
viewModelScope.launch(Dispatchers.IO) {
try {
val file = File(AppContext.cacheDir, "${BuildConfig.APP_VERSION_CODE}.md")
val text = when {
file.exists() -> file.readText()
Const.Url.CHANGELOG_URL.isEmpty() -> ""
val noteFile = File(AppContext.cacheDir, "${APP_VERSION_CODE}.md")
val noteText = when {
noteFile.exists() -> noteFile.readText()
else -> {
val str = svc.fetchString(Const.Url.CHANGELOG_URL)
file.writeText(str)
str
val note = svc.fetchUpdate(APP_VERSION_CODE)?.note.orEmpty()
if (note.isEmpty()) return@launch
noteFile.writeText(note)
note
}
}
val spanned = markwon.toMarkdown(text)
val spanned = markwon.toMarkdown(noteText)
withContext(Dispatchers.Main) {
notes = spanned
}
@@ -100,13 +99,15 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
}
override fun onSaveState(state: Bundle) {
state.putParcelable(INSTALL_STATE_KEY, InstallState(
methodId,
step,
Config.keepVerity,
Config.keepEnc,
Config.recovery
))
state.putParcelable(
INSTALL_STATE_KEY, InstallState(
methodId,
step,
Config.keepVerity,
Config.keepEnc,
Config.recovery
)
)
}
override fun onRestoreState(state: Bundle) {
@@ -124,6 +125,7 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
override fun onActivityLaunch() {
AppContext.toast(CoreR.string.patch_file_msg, Toast.LENGTH_LONG)
}
override fun onActivityResult(result: Uri) {
uri.value = result
}

View File

@@ -5,6 +5,7 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.HorizontalScrollView
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import com.topjohnwu.magisk.R
@@ -12,6 +13,7 @@ import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.utils.AccessibilityUtils
import com.topjohnwu.magisk.utils.MotionRevealHelper
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
@@ -56,6 +58,11 @@ class LogFragment : BaseFragment<FragmentLogMd2Binding>(), MenuProvider {
addItemSpacing(R.dimen.l1, R.dimen.l_50, R.dimen.l1)
fixEdgeEffect()
}
if (!AccessibilityUtils.isAnimationEnabled(requireContext().contentResolver)) {
val scrollView = view.findViewById<HorizontalScrollView>(R.id.log_scroll_magisk)
scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER)
}
}

View File

@@ -147,19 +147,11 @@ object UpdateChannel : BaseSettingsItem.Selector() {
get() = Config.updateChannel
set(value) {
Config.updateChannel = value
Info.remote = Info.EMPTY_REMOTE
Info.resetUpdate()
}
override val title = CoreR.string.settings_update_channel_title.asText()
override val entryRes = CoreR.array.update_channel
override fun entries(res: Resources): Array<String> {
return super.entries(res).let {
if (!Const.APP_IS_CANARY && !BuildConfig.DEBUG)
it.copyOfRange(0, Config.Value.CANARY_CHANNEL)
else it
}
}
}
object UpdateChannelUrl : BaseSettingsItem.Input() {
@@ -169,7 +161,7 @@ object UpdateChannelUrl : BaseSettingsItem.Input() {
get() = Config.customChannelUrl
set(value) {
Config.customChannelUrl = value
Info.remote = Info.EMPTY_REMOTE
Info.resetUpdate()
notifyPropertyChanged(BR.description)
}
@@ -330,6 +322,12 @@ object Reauthenticate : BaseSettingsItem.Toggle() {
override var value by Config::suReAuth
override fun refresh() {
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Info.showSuperUser
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O
}
}
object Restrict : BaseSettingsItem.Toggle() {
override val title = CoreR.string.settings_su_restrict_title.asText()
override val description = CoreR.string.settings_su_restrict_summary.asText()
override var value by Config::suRestrict
}

View File

@@ -22,11 +22,11 @@ import com.topjohnwu.magisk.core.ktx.activity
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.tasks.AppMigration
import com.topjohnwu.magisk.core.utils.LocaleSetting
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.AuthEvent
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
@@ -83,6 +83,9 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
// Can hide overlay windows on 12.0+
list.remove(Tapjack)
}
if (Const.Version.atLeast_30_1()) {
list.add(Restrict)
}
}
return list
@@ -127,7 +130,8 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
}
private fun createHosts() {
Shell.cmd("add_hosts_module").submit {
viewModelScope.launch {
RootUtils.addSystemlessHosts()
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
}
}

View File

@@ -4,11 +4,13 @@ import android.graphics.drawable.Drawable
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.databinding.DiffItem
import com.topjohnwu.magisk.databinding.ItemWrapper
import com.topjohnwu.magisk.databinding.ObservableRvItem
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.core.R as CoreR
class PolicyRvItem(
private val viewModel: SuperuserViewModel,
@@ -33,14 +35,34 @@ class PolicyRvItem(
var isExpanded = false
set(value) = set(value, field, { field = it }, BR.expanded)
val showSlider = Config.suRestrict || item.policy == SuPolicy.RESTRICT
@get:Bindable
var isEnabled
get() = item.policy == SuPolicy.ALLOW
get() = item.policy >= SuPolicy.ALLOW
set(value) = setImpl(value, isEnabled) {
notifyPropertyChanged(BR.enabled)
viewModel.togglePolicy(this, value)
viewModel.updatePolicy(this, if (it) SuPolicy.ALLOW else SuPolicy.DENY)
}
@get:Bindable
var sliderValue
get() = item.policy
set(value) = setImpl(value, sliderValue) {
notifyPropertyChanged(BR.sliderValue)
notifyPropertyChanged(BR.enabled)
viewModel.updatePolicy(this, it)
}
val sliderValueToPolicyString: (Float) -> Int = { value ->
when (value.toInt()) {
1 -> CoreR.string.deny
2 -> CoreR.string.restrict
3 -> CoreR.string.grant
else -> CoreR.string.deny
}
}
@get:Bindable
var shouldNotify
get() = item.notification

View File

@@ -156,15 +156,16 @@ class SuperuserViewModel(
}
}
fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
fun updatePolicy(item: PolicyRvItem, policy: Int) {
val items = itemsPolicies.filter { it.item.uid == item.item.uid }
fun updateState() {
viewModelScope.launch {
val res = if (enable) R.string.su_snack_grant else R.string.su_snack_deny
item.item.policy = if (enable) SuPolicy.ALLOW else SuPolicy.DENY
val res = if (policy >= SuPolicy.ALLOW) R.string.su_snack_grant else R.string.su_snack_deny
item.item.policy = policy
db.update(item.item)
items.forEach {
it.notifyPropertyChanged(BR.enabled)
it.notifyPropertyChanged(BR.sliderValue)
}
SnackbarEvent(res.asText(item.appName)).publish()
}

View File

@@ -43,10 +43,6 @@ enum class Theme(
val isSelected get() = Config.themeOrdinal == ordinal
fun select() {
Config.themeOrdinal = ordinal
}
companion object {
val selected get() = values().getOrNull(Config.themeOrdinal) ?: Piplup
}

View File

@@ -0,0 +1,14 @@
package com.topjohnwu.magisk.utils
import android.content.ContentResolver
import android.provider.Settings
class AccessibilityUtils {
companion object {
fun isAnimationEnabled(cr: ContentResolver): Boolean {
return !(Settings.Global.getFloat(cr, Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f) == 0.0f
&& Settings.Global.getFloat(cr, Settings.Global.TRANSITION_ANIMATION_SCALE, 1.0f) == 0.0f
&& Settings.Global.getFloat(cr, Settings.Global.WINDOW_ANIMATION_SCALE, 1.0f) == 0.0f)
}
}
}

View File

@@ -16,6 +16,7 @@
android:layout_height="match_parent">
<HorizontalScrollView
android:id="@+id/log_scroll_magisk"
gone="@{viewModel.loading}"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@@ -25,7 +25,7 @@
<include
android:id="@+id/log_track_container"
bullet="@{item.log.action == 2 ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
bullet="@{item.log.action >= 2 ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
isBottom="@{item.isBottom}"
isSelected="@{item.log.action != 2}"
isTop="@{item.isTop}"

View File

@@ -27,10 +27,8 @@
isEnabled="@{!item.removed &amp;&amp; item.enabled &amp;&amp; !item.showNotice}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="@{!item.removed &amp;&amp; item.enabled &amp;&amp; !item.showNotice}"
android:focusable="@{!item.removed &amp;&amp; item.enabled &amp;&amp; !item.showNotice}"
android:nextFocusRight="@id/module_indicator"
android:onClick="@{() -> item.setEnabled(!item.enabled)}"
app:cardBackgroundColor="@color/color_card_background_color_selector"
tools:isEnabled="false"
tools:layout_gravity="center"

View File

@@ -5,6 +5,8 @@
<data>
<import type="com.topjohnwu.magisk.databinding.DataBindingAdaptersKt" />
<variable
name="item"
type="com.topjohnwu.magisk.ui.superuser.PolicyRvItem" />
@@ -85,16 +87,32 @@
app:layout_constraintVertical_bias="0"
tools:text="com.topjohnwu.magisk" />
<com.google.android.material.switchmaterial.SwitchMaterial
<FrameLayout
android:id="@+id/policy_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/l1"
android:checked="@={item.enabled}"
android:nextFocusLeft="@id/policy"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.switchmaterial.SwitchMaterial
gone="@{item.showSlider}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={item.enabled}" />
<com.google.android.material.slider.Slider
goneUnless="@{item.showSlider}"
labelFormatter="@{item.sliderValueToPolicyString}"
android:layout_width="96dp"
android:layout_height="wrap_content"
android:stepSize="1"
android:value="@={DataBindingAdaptersKt.policyToSliderValue(item.sliderValue)}"
android:valueFrom="1"
android:valueTo="3" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,5 +1,11 @@
tasks.register("clean") {
plugins {
id("MagiskPlugin")
}
tasks.register("clean", Delete::class) {
delete(rootProject.layout.buildDirectory)
subprojects.forEach {
dependsOn(":app:${it.name}:clean")
dependsOn(":${it.name}:clean")
}
}

View File

@@ -18,17 +18,12 @@ gradlePlugin {
}
}
kotlin {
compilerOptions {
languageVersion = KotlinVersion.KOTLIN_2_0
}
}
dependencies {
implementation(kotlin("gradle-plugin", libs.versions.kotlin.get()))
implementation(libs.android.gradle.plugin)
implementation(libs.ksp.plugin)
implementation(libs.navigation.safe.args.plugin)
implementation(libs.lsparanoid.plugin)
implementation(libs.moshi.plugin)
implementation(libs.jgit)
}

View File

@@ -0,0 +1,77 @@
import com.android.build.api.artifact.ArtifactTransformationRequest
import com.android.build.api.dsl.ApkSigningConfig
import com.android.builder.internal.packaging.IncrementalPackager
import com.android.tools.build.apkzlib.sign.SigningExtension
import com.android.tools.build.apkzlib.sign.SigningOptions
import com.android.tools.build.apkzlib.zfile.ZFiles
import com.android.tools.build.apkzlib.zip.ZFileOptions
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import java.io.File
import java.security.KeyStore
import java.security.cert.X509Certificate
import java.util.jar.JarFile
abstract class AddCommentTask: DefaultTask() {
@get:Input
abstract val comment: Property<String>
@get:Input
abstract val signingConfig: Property<ApkSigningConfig>
@get:InputFiles
abstract val apkFolder: DirectoryProperty
@get:OutputDirectory
abstract val outFolder: DirectoryProperty
@get:Internal
abstract val transformationRequest: Property<ArtifactTransformationRequest<AddCommentTask>>
@TaskAction
fun taskAction() = transformationRequest.get().submit(this) { artifact ->
val inFile = File(artifact.outputFile)
val outFile = outFolder.file(inFile.name).get().asFile
val privateKey = signingConfig.get().getPrivateKey()
val signingOptions = SigningOptions.builder()
.setMinSdkVersion(0)
.setV1SigningEnabled(true)
.setV2SigningEnabled(true)
.setKey(privateKey.privateKey)
.setCertificates(privateKey.certificate as X509Certificate)
.setValidation(SigningOptions.Validation.ASSUME_INVALID)
.build()
val options = ZFileOptions().apply {
noTimestamps = true
autoSortFiles = true
}
outFile.parentFile?.mkdirs()
inFile.copyTo(outFile, overwrite = true)
ZFiles.apk(outFile, options).use {
SigningExtension(signingOptions).register(it)
it.eocdComment = comment.get().toByteArray()
it.get(IncrementalPackager.APP_METADATA_ENTRY_PATH)?.delete()
it.get(IncrementalPackager.VERSION_CONTROL_INFO_ENTRY_PATH)?.delete()
it.get(JarFile.MANIFEST_NAME)?.delete()
}
outFile
}
private fun ApkSigningConfig.getPrivateKey(): KeyStore.PrivateKeyEntry {
val keyStore = KeyStore.getInstance(storeType ?: KeyStore.getDefaultType())
storeFile!!.inputStream().use {
keyStore.load(it, storePassword!!.toCharArray())
}
val keyPwdArray = keyPassword!!.toCharArray()
val entry = keyStore.getEntry(keyAlias!!, KeyStore.PasswordProtection(keyPwdArray))
return entry as KeyStore.PrivateKeyEntry
}
}

View File

@@ -5,6 +5,12 @@ import org.gradle.api.Project
import org.gradle.kotlin.dsl.provideDelegate
import java.io.File
import java.util.Properties
import java.util.Random
// Set non-zero value here to fix the random seed for reproducible builds
// CI builds are always reproducible
val RAND_SEED = if (System.getenv("CI") != null) 42 else 0
lateinit var RANDOM: Random
private val props = Properties()
private var commitHash = ""
@@ -14,7 +20,7 @@ private val defaultAbis = setOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64")
object Config {
operator fun get(key: String): String? {
val v = props[key] as? String ?: return null
return if (v.isBlank()) null else v
return v.ifBlank { null }
}
fun contains(key: String) = get(key) != null
@@ -28,19 +34,25 @@ object Config {
}
}
fun Project.rootFile(path: String): File {
val file = File(path)
return if (file.isAbsolute) file
else File(rootProject.file(".."), path)
}
class MagiskPlugin : Plugin<Project> {
override fun apply(project: Project) = project.applyPlugin()
private fun Project.applyPlugin() {
initRandom(rootProject.file("app/dict.txt"))
initRandom(rootProject.file("dict.txt"))
props.clear()
rootProject.file("gradle.properties").inputStream().use { props.load(it) }
val configPath: String? by this
val config = configPath?.let { File(it) } ?: rootProject.file("config.prop")
val config = rootFile(configPath ?: "config.prop")
if (config.exists())
config.inputStream().use { props.load(it) }
val repo = FileRepository(rootProject.file(".git"))
val repo = FileRepository(rootFile(".git"))
val refId = repo.refDatabase.exactRef("HEAD").objectId
commitHash = repo.newObjectReader().abbreviate(refId, 8).name()
}

View File

@@ -0,0 +1,330 @@
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.instrumentation.FramesComputationMode.COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS
import com.android.build.api.instrumentation.InstrumentationScope
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import org.apache.tools.ant.filters.FixCrLfFilter
import org.gradle.api.Action
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.StopExecutionException
import org.gradle.api.tasks.Sync
import org.gradle.kotlin.dsl.assign
import org.gradle.kotlin.dsl.exclude
import org.gradle.kotlin.dsl.filter
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.ByteArrayOutputStream
import java.io.File
import java.net.URI
import java.security.MessageDigest
import java.util.HexFormat
import java.util.zip.Deflater
import java.util.zip.DeflaterOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
private fun Project.androidBase(configure: Action<BaseExtension>) =
extensions.configure("android", configure)
private fun Project.android(configure: Action<BaseAppModuleExtension>) =
extensions.configure("android", configure)
internal val Project.androidApp: BaseAppModuleExtension
get() = extensions["android"] as BaseAppModuleExtension
private val Project.androidLib: LibraryExtension
get() = extensions["android"] as LibraryExtension
internal val Project.androidComponents
get() = extensions.getByType(ApplicationAndroidComponentsExtension::class.java)
fun Project.setupCommon() {
androidBase {
compileSdkVersion(36)
buildToolsVersion = "36.0.0"
ndkPath = "$sdkDirectory/ndk/magisk"
ndkVersion = "29.0.14206865"
defaultConfig {
minSdk = 23
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
packagingOptions {
resources {
excludes += arrayOf(
"/META-INF/*",
"/META-INF/androidx/**",
"/META-INF/versions/**",
"/org/bouncycastle/**",
"/org/apache/commons/**",
"/kotlin/**",
"/kotlinx/**",
"/okhttp3/**",
"/*.txt",
"/*.bin",
"/*.json",
)
}
}
}
configurations.all {
exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk7")
exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk8")
}
tasks.withType<KotlinCompile> {
compilerOptions {
jvmTarget = JvmTarget.JVM_21
}
}
}
private fun Project.downloadFile(url: String, checksum: String): File {
val file = layout.buildDirectory.file(checksum).get().asFile
if (file.exists()) {
val md = MessageDigest.getInstance("SHA-256")
file.inputStream().use { md.update(it.readAllBytes()) }
val hash = HexFormat.of().formatHex(md.digest())
if (hash != checksum) {
file.delete()
}
}
if (!file.exists()) {
file.parentFile.mkdirs()
URI(url).toURL().openStream().use { dl ->
file.outputStream().use {
dl.copyTo(it)
}
}
}
return file
}
const val BUSYBOX_DOWNLOAD_URL =
"https://github.com/topjohnwu/magisk-files/releases/download/files/busybox-1.36.1.1.zip"
const val BUSYBOX_ZIP_CHECKSUM =
"b4d0551feabaf314e53c79316c980e8f66432e9fb91a69dbbf10a93564b40951"
fun Project.setupCoreLib() {
setupCommon()
androidLib.libraryVariants.all {
val variant = name
val variantCapped = name.replaceFirstChar { it.uppercase() }
val abiList = Config.abiList
val syncLibs = tasks.register("sync${variantCapped}JniLibs", Sync::class) {
into("src/$variant/jniLibs")
for (abi in abiList) {
into(abi) {
from(rootFile("native/out/$abi")) {
include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so")
rename { if (it.endsWith(".so")) it else "lib$it.so" }
}
}
}
from(zipTree(downloadFile(BUSYBOX_DOWNLOAD_URL, BUSYBOX_ZIP_CHECKSUM)))
include(abiList.map { "$it/libbusybox.so" })
onlyIf {
if (inputs.sourceFiles.files.size != abiList.size * 6)
throw StopExecutionException("Please build binaries first! (./build.py binary)")
true
}
}
tasks.getByPath("merge${variantCapped}JniLibFolders").dependsOn(syncLibs)
val syncResources = tasks.register("sync${variantCapped}Resources", Sync::class) {
into("src/$variant/resources/META-INF/com/google/android")
from(rootFile("scripts/update_binary.sh")) {
rename { "update-binary" }
}
from(rootFile("scripts/flash_script.sh")) {
rename { "updater-script" }
}
}
processJavaResourcesProvider.configure { dependsOn(syncResources) }
val stubTask = tasks.getByPath(":stub:comment$variantCapped")
val stubApk = stubTask.outputs.files.asFileTree.filter {
it.name.endsWith(".apk")
}
val syncAssets = tasks.register("sync${variantCapped}Assets", Sync::class) {
dependsOn(stubTask)
inputs.property("version", Config.version)
inputs.property("versionCode", Config.versionCode)
into("src/$variant/assets")
from(rootFile("scripts")) {
include("util_functions.sh", "boot_patch.sh", "addon.d.sh",
"app_functions.sh", "uninstaller.sh", "module_installer.sh")
}
from(rootFile("tools/bootctl"))
into("chromeos") {
from(rootFile("tools/futility"))
from(rootFile("tools/keys")) {
include("kernel_data_key.vbprivk", "kernel.keyblock")
}
}
from(stubApk) {
rename { "stub.apk" }
}
filesMatching("**/util_functions.sh") {
filter {
it.replace(
"#MAGISK_VERSION_STUB",
"MAGISK_VER='${Config.version}'\nMAGISK_VER_CODE=${Config.versionCode}"
)
}
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
}
}
mergeAssetsProvider.configure { dependsOn(syncAssets) }
}
tasks.named<Delete>("clean") {
delete.addAll(listOf("src/main/jniLibs", "src/main/resources", "src/debug", "src/release"))
}
}
fun Project.setupAppCommon() {
setupCommon()
android {
signingConfigs {
Config["keyStore"]?.also {
create("config") {
storeFile = rootFile(it)
storePassword = Config["keyStorePass"]
keyAlias = Config["keyAlias"]
keyPassword = Config["keyPass"]
}
}
}
defaultConfig {
targetSdk = 36
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt")
)
}
buildTypes {
val config = signingConfigs.findByName("config") ?: signingConfigs["debug"]
debug {
signingConfig = config
}
release {
signingConfig = config
}
}
lint {
disable += "MissingTranslation"
checkReleaseBuilds = false
}
dependenciesInfo {
includeInApk = false
}
packaging {
jniLibs {
useLegacyPackaging = true
}
}
}
androidComponents.onVariants { variant ->
val commentTask = tasks.register(
"comment${variant.name.replaceFirstChar { it.uppercase() }}",
AddCommentTask::class.java
)
val transformationRequest = variant.artifacts.use(commentTask)
.wiredWithDirectories(AddCommentTask::apkFolder, AddCommentTask::outFolder)
.toTransformMany(SingleArtifact.APK)
val signingConfig = androidApp.buildTypes.getByName(variant.buildType!!).signingConfig
commentTask.configure {
this.transformationRequest = transformationRequest
this.signingConfig = signingConfig
this.comment = "version=${Config.version}\n" +
"versionCode=${Config.versionCode}\n" +
"stubVersion=${Config.stubVersion}\n"
this.outFolder.set(layout.buildDirectory.dir("outputs/apk/${variant.name}"))
}
}
}
fun Project.setupMainApk() {
setupAppCommon()
android {
namespace = "com.topjohnwu.magisk"
defaultConfig {
applicationId = "com.topjohnwu.magisk"
vectorDrawables.useSupportLibrary = true
versionName = Config.version
versionCode = Config.versionCode
ndk {
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64", "riscv64")
debugSymbolLevel = "FULL"
}
}
androidComponents.onVariants { variant ->
variant.instrumentation.apply {
setAsmFramesComputationMode(COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS)
transformClassesWith(
DesugarClassVisitorFactory::class.java, InstrumentationScope.ALL) {}
}
}
}
}
const val LSPOSED_DOWNLOAD_URL =
"https://github.com/LSPosed/LSPosed/releases/download/v1.9.2/LSPosed-v1.9.2-7024-zygisk-release.zip"
const val LSPOSED_CHECKSUM =
"0ebc6bcb465d1c4b44b7220ab5f0252e6b4eb7fe43da74650476d2798bb29622"
const val SHAMIKO_DOWNLOAD_URL =
"https://github.com/LSPosed/LSPosed.github.io/releases/download/shamiko-383/Shamiko-v1.2.1-383-release.zip"
const val SHAMIKO_CHECKSUM =
"93754a038c2d8f0e985bad45c7303b96f70a93d8335060e50146f028d3a9b13f"
fun Project.setupTestApk() {
setupAppCommon()
androidApp.applicationVariants.all {
val variantCapped = name.replaceFirstChar { it.uppercase() }
val dlTask by tasks.register("download${variantCapped}Lsposed", Sync::class) {
from(downloadFile(LSPOSED_DOWNLOAD_URL, LSPOSED_CHECKSUM)) {
rename { "lsposed.zip" }
}
from(downloadFile(SHAMIKO_DOWNLOAD_URL, SHAMIKO_CHECKSUM)) {
rename { "shamiko.zip" }
}
into("src/${this@all.name}/assets")
}
mergeAssetsProvider.configure { dependsOn(dlTask) }
}
}

View File

@@ -1,8 +1,11 @@
import com.android.build.api.artifact.SingleArtifact
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
@@ -10,22 +13,25 @@ import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.assign
import org.gradle.kotlin.dsl.named
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.security.SecureRandom
import java.util.Random
import java.util.zip.Deflater
import java.util.zip.DeflaterOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
import javax.crypto.Cipher
import javax.crypto.CipherOutputStream
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import kotlin.random.asKotlinRandom
// Set non-zero value here to fix the random seed for reproducible builds
// CI builds are always reproducible
val RAND_SEED = if (System.getenv("CI") != null) 42 else 0
private lateinit var RANDOM: Random
private val kRANDOM get() = RANDOM.asKotlinRandom()
private val c1 = mutableListOf<String>()
@@ -72,7 +78,7 @@ private fun PrintStream.byteField(name: String, bytes: ByteArray) {
}
@CacheableTask
abstract class ManifestUpdater: DefaultTask() {
private abstract class ManifestUpdater: DefaultTask() {
@get:Input
abstract val applicationId: Property<String>
@@ -182,9 +188,7 @@ abstract class ManifestUpdater: DefaultTask() {
}
fun genStubClasses(factoryOutDir: File, appOutDir: File) {
fun String.ind(level: Int) = replaceIndentByMargin(" ".repeat(level))
private fun genStubClasses(factoryOutDir: File, appOutDir: File) {
val classNameGenerator = sequence {
fun notJavaKeyword(name: String) = when (name) {
"do", "if", "for", "int", "new", "try" -> false
@@ -228,7 +232,7 @@ fun genStubClasses(factoryOutDir: File, appOutDir: File) {
genClass("StubApplication", appOutDir)
}
fun genEncryptedResources(res: ByteArray, outDir: File) {
private fun genEncryptedResources(res: ByteArray, outDir: File) {
val mainPkgDir = File(outDir, "com/topjohnwu/magisk")
mainPkgDir.mkdirs()
@@ -259,3 +263,86 @@ fun genEncryptedResources(res: ByteArray, outDir: File) {
it.println("}")
}
}
fun Project.setupStubApk() {
setupAppCommon()
androidComponents.onVariants { variant ->
val variantName = variant.name
val variantCapped = variantName.replaceFirstChar { it.uppercase() }
val manifestUpdater =
project.tasks.register("${variantName}ManifestProducer", ManifestUpdater::class.java) {
dependsOn("generate${variantCapped}ObfuscatedClass")
applicationId = variant.applicationId
appClassDir.set(layout.buildDirectory.dir("generated/source/app/$variantName"))
factoryClassDir.set(layout.buildDirectory.dir("generated/source/factory/$variantName"))
}
variant.artifacts.use(manifestUpdater)
.wiredWithFiles(
ManifestUpdater::mergedManifest,
ManifestUpdater::outputManifest)
.toTransform(SingleArtifact.MERGED_MANIFEST)
}
androidApp.applicationVariants.all {
val variantCapped = name.replaceFirstChar { it.uppercase() }
val variantLowered = name.lowercase()
val outFactoryClassDir = layout.buildDirectory.file("generated/source/factory/${variantLowered}").get().asFile
val outAppClassDir = layout.buildDirectory.file("generated/source/app/${variantLowered}").get().asFile
val outResDir = layout.buildDirectory.dir("generated/source/res/${variantLowered}").get().asFile
val aapt = File(androidApp.sdkDirectory, "build-tools/${androidApp.buildToolsVersion}/aapt2")
val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" +
"${variantLowered}/process${variantCapped}Resources/linked-resources-binary-format-${variantLowered}.ap_").get().asFile
val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedClass") {
inputs.property("seed", RAND_SEED)
outputs.dirs(outFactoryClassDir, outAppClassDir)
doLast {
outFactoryClassDir.mkdirs()
outAppClassDir.mkdirs()
genStubClasses(outFactoryClassDir, outAppClassDir)
}
}
registerJavaGeneratingTask(genManifestTask, outFactoryClassDir, outAppClassDir)
val processResourcesTask = tasks.named("process${variantCapped}Resources") {
outputs.dir(outResDir)
doLast {
val apkTmp = File("${apk}.tmp")
providers.exec {
commandLine(aapt, "optimize", "-o", apkTmp, "--collapse-resource-names", apk)
}.result.get()
val bos = ByteArrayOutputStream()
ZipFile(apkTmp).use { src ->
ZipOutputStream(apk.outputStream()).use {
it.setLevel(Deflater.BEST_COMPRESSION)
it.putNextEntry(ZipEntry("AndroidManifest.xml"))
src.getInputStream(src.getEntry("AndroidManifest.xml")).transferTo(it)
it.closeEntry()
}
DeflaterOutputStream(bos, Deflater(Deflater.BEST_COMPRESSION)).use {
src.getInputStream(src.getEntry("resources.arsc")).transferTo(it)
}
}
apkTmp.delete()
genEncryptedResources(bos.toByteArray(), outResDir)
}
}
registerJavaGeneratingTask(processResourcesTask, outResDir)
}
// Override optimizeReleaseResources task
val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" +
"release/processReleaseResources/linked-resources-binary-format-release.ap_").get().asFile
val optRes = layout.buildDirectory.file("intermediates/optimized_processed_res/" +
"release/optimizeReleaseResources/resources-release-optimize.ap_").get().asFile
afterEvaluate {
tasks.named("optimizeReleaseResources") {
doLast { apk.copyTo(optRes, true) }
}
}
tasks.named<Delete>("clean") {
delete.addAll(listOf("src/debug/AndroidManifest.xml", "src/release/AndroidManifest.xml"))
}
}

5
app/core/.gitignore vendored
View File

@@ -1,4 +1,3 @@
/build
src/*/assets
src/*/jniLibs
src/*/resources
src/debug
src/release

View File

@@ -2,6 +2,7 @@ plugins {
id("com.android.library")
kotlin("android")
kotlin("plugin.parcelize")
id("dev.zacsweers.moshix")
id("com.google.devtools.ksp")
}
@@ -26,10 +27,15 @@ android {
aidl = true
buildConfig = true
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
api(project(":app:shared"))
api(project(":shared"))
coreLibraryDesugaring(libs.jdk.libs)
api(libs.timber)
api(libs.markwon.core)
@@ -48,9 +54,6 @@ dependencies {
implementation(libs.okhttp.logging)
implementation(libs.okhttp.dnsoverhttps)
implementation(libs.moshi)
ksp(libs.moshi.codegen)
implementation(libs.room.runtime)
implementation(libs.room.ktx)
ksp(libs.room.compiler)

View File

@@ -38,3 +38,4 @@
-allowaccessmodification
-dontwarn org.junit.**
-dontwarn org.apache.**

View File

@@ -14,7 +14,6 @@
<application
android:name=".App"
android:icon="@drawable/ic_launcher"
android:multiArch="true"
tools:ignore="UnusedAttribute,GoogleAppIndexingWarning"
tools:remove="android:appComponentFactory">

View File

@@ -6,4 +6,5 @@ package com.topjohnwu.magisk.core.utils;
interface IRootUtils {
android.app.ActivityManager.RunningAppProcessInfo getAppProcess(int pid);
IBinder getFileSystem();
boolean addSystemlessHosts();
}

View File

@@ -32,8 +32,9 @@ object Config : PreferenceConfig, DBConfig {
const val SU_NOTIFICATION = "su_notification"
const val SU_REAUTH = "su_reauth"
const val SU_TAPJACK = "su_tapjack"
const val SU_RESTRICT = "su_restrict"
const val CHECK_UPDATES = "check_update"
const val UPDATE_CHANNEL = "update_channel"
const val RELEASE_CHANNEL = "release_channel"
const val CUSTOM_CHANNEL = "custom_channel"
const val LOCALE = "locale"
const val DARK_THEME = "dark_theme_extended"
@@ -48,7 +49,7 @@ object Config : PreferenceConfig, DBConfig {
SU_AUTO_RESPONSE, SU_REAUTH, SU_TAPJACK)
}
object Value {
object OldValue {
// Update channels
const val DEFAULT_CHANNEL = -1
const val STABLE_CHANNEL = 0
@@ -56,6 +57,15 @@ object Config : PreferenceConfig, DBConfig {
const val CUSTOM_CHANNEL = 2
const val CANARY_CHANNEL = 3
const val DEBUG_CHANNEL = 4
}
object Value {
// Update channels
const val DEFAULT_CHANNEL = -1
const val STABLE_CHANNEL = 0
const val BETA_CHANNEL = 1
const val DEBUG_CHANNEL = 2
const val CUSTOM_CHANNEL = 3
// root access mode
const val ROOT_ACCESS_DISABLED = 0
@@ -86,14 +96,6 @@ object Config : PreferenceConfig, DBConfig {
val TIMEOUT_LIST = longArrayOf(0, -1, 10, 20, 30, 60)
}
private val defaultChannel =
if (BuildConfig.DEBUG)
Value.DEBUG_CHANNEL
else if (Const.APP_IS_CANARY)
Value.CANARY_CHANNEL
else
Value.DEFAULT_CHANNEL
@JvmField var keepVerity = false
@JvmField var keepEnc = false
@JvmField var recovery = false
@@ -109,7 +111,7 @@ object Config : PreferenceConfig, DBConfig {
private var checkUpdatePrefs by preference(Key.CHECK_UPDATES, true)
private var localePrefs by preference(Key.LOCALE, "")
var doh by preference(Key.DOH, false)
var updateChannel by preferenceStrInt(Key.UPDATE_CHANNEL, defaultChannel)
var updateChannel by preference(Key.RELEASE_CHANNEL, Value.DEFAULT_CHANNEL)
var customChannelUrl by preference(Key.CUSTOM_CHANNEL, "")
var downloadDir by preference(Key.DOWNLOAD_DIR, "")
var randName by preference(Key.RAND_NAME, true)
@@ -146,8 +148,10 @@ object Config : PreferenceConfig, DBConfig {
}
var suReAuth by preference(Key.SU_REAUTH, false)
var suTapjack by preference(Key.SU_TAPJACK, true)
var suRestrict by preference(Key.SU_RESTRICT, false)
private const val SU_FINGERPRINT = "su_fingerprint"
private const val UPDATE_CHANNEL = "update_channel"
fun toBundle(): Bundle {
val map = prefs.all - Key.NO_MIGRATION
@@ -183,17 +187,23 @@ object Config : PreferenceConfig, DBConfig {
}
prefs.edit {
// Settings migration
// Migrate su_fingerprint
if (prefs.getBoolean(SU_FINGERPRINT, false))
suBiometric = true
remove(SU_FINGERPRINT)
prefs.getString(Key.UPDATE_CHANNEL, null).also {
if (it == null ||
it.toInt() > Value.DEBUG_CHANNEL ||
it.toInt() < Value.DEFAULT_CHANNEL) {
putString(Key.UPDATE_CHANNEL, defaultChannel.toString())
// Migrate update_channel
prefs.getString(UPDATE_CHANNEL, null)?.let {
val channel = when (it.toInt()) {
OldValue.STABLE_CHANNEL -> Value.STABLE_CHANNEL
OldValue.CANARY_CHANNEL, OldValue.BETA_CHANNEL -> Value.BETA_CHANNEL
OldValue.DEBUG_CHANNEL -> Value.DEBUG_CHANNEL
OldValue.CUSTOM_CHANNEL -> Value.CUSTOM_CHANNEL
else -> Value.DEFAULT_CHANNEL
}
putInt(Key.RELEASE_CHANNEL, channel)
}
remove(UPDATE_CHANNEL)
}
}
}

View File

@@ -2,6 +2,7 @@ package com.topjohnwu.magisk.core
import android.os.Build
import android.os.Process
import com.topjohnwu.magisk.core.BuildConfig.APP_VERSION_CODE
@Suppress("DEPRECATION")
object Const {
@@ -14,23 +15,22 @@ object Const {
else Build.SUPPORTED_32_BIT_ABIS.firstOrNull()
// Paths
const val MAGISK_PATH = "/data/adb/modules"
const val MODULE_PATH = "/data/adb/modules"
const val TMPDIR = "/dev/tmp"
const val MAGISK_LOG = "/cache/magisk.log"
// Misc
val USER_ID = Process.myUid() / 100000
val APP_IS_CANARY get() = Version.isCanary(BuildConfig.APP_VERSION_CODE)
object Version {
const val MIN_VERSION = "v22.0"
const val MIN_VERCODE = 22000
private fun isCanary() = (Info.env.versionCode % 100) != 0
fun atLeast_24_0() = Info.env.versionCode >= 24000 || isCanary()
fun atLeast_25_0() = Info.env.versionCode >= 25000 || isCanary()
fun isCanary() = isCanary(Info.env.versionCode)
fun isCanary(ver: Int) = ver > 0 && ver % 100 != 0
fun atLeast_28_0() = Info.env.versionCode >= 28000 || isCanary()
fun atLeast_30_1() = Info.env.versionCode >= 30100 || isCanary()
}
object ID {
@@ -42,13 +42,9 @@ object Const {
const val PATREON_URL = "https://www.patreon.com/topjohnwu"
const val SOURCE_CODE_URL = "https://github.com/topjohnwu/Magisk"
val CHANGELOG_URL = if (APP_IS_CANARY) Info.remote.magisk.note
else "https://topjohnwu.github.io/Magisk/releases/${BuildConfig.APP_VERSION_CODE}.md"
const val GITHUB_RAW_URL = "https://raw.githubusercontent.com/"
const val GITHUB_API_URL = "https://api.github.com/"
const val GITHUB_PAGE_URL = "https://topjohnwu.github.io/magisk-files/"
const val JS_DELIVR_URL = "https://cdn.jsdelivr.net/gh/"
const val INVALID_URL = "https://example.com/"
}
object Key {

View File

@@ -19,12 +19,18 @@ object Info {
var stub: StubApk.Data? = null
val EMPTY_REMOTE = UpdateInfo()
var remote = EMPTY_REMOTE
suspend fun getRemote(svc: NetworkService): UpdateInfo? {
return if (remote === EMPTY_REMOTE) {
svc.fetchUpdate()?.apply { remote = this }
} else remote
private val EMPTY_UPDATE = UpdateInfo()
var update = EMPTY_UPDATE
private set
suspend fun fetchUpdate(svc: NetworkService): UpdateInfo? {
return if (update === EMPTY_UPDATE) {
svc.fetchUpdate()?.apply { update = this }
} else update
}
fun resetUpdate() {
update = EMPTY_UPDATE
}
var isRooted = false
@@ -41,13 +47,14 @@ object Info {
private set
var slot = ""
private set
var isVendorBoot = false
private set
@JvmField val isZygiskEnabled = System.getenv("ZYGISK_ENABLED") == "1"
@JvmStatic val isFDE get() = crypto == "block"
@JvmStatic var ramdisk = false
private set
private var crypto = ""
var hasGMS = true
val isEmulator =
Build.DEVICE.contains("vsoc")
|| getProperty("ro.kernel.qemu", "0") == "1"
@@ -108,6 +115,7 @@ object Info {
crypto = getVar("CRYPTOTYPE")
slot = getVar("SLOT")
legacySAR = getBool("LEGACYSAR")
isVendorBoot = getBool("VENDORBOOT")
// Default presets
Config.recovery = getBool("RECOVERYMODE")

View File

@@ -75,9 +75,8 @@ class JobService : BaseJobService() {
private fun checkUpdate(params: JobParameters): Boolean {
GlobalScope.launch(Dispatchers.IO) {
ServiceLocator.networkService.fetchUpdate()?.let {
Info.remote = it
if (Info.env.isActive && BuildConfig.APP_VERSION_CODE < it.magisk.versionCode)
Info.fetchUpdate(ServiceLocator.networkService)?.let {
if (Info.env.isActive && BuildConfig.APP_VERSION_CODE < it.versionCode)
Notifications.updateAvailable()
jobFinished(params, false)
}

View File

@@ -1,45 +0,0 @@
package com.topjohnwu.magisk.core.data
import com.topjohnwu.magisk.core.model.BranchInfo
import com.topjohnwu.magisk.core.model.ModuleJson
import com.topjohnwu.magisk.core.model.UpdateInfo
import okhttp3.ResponseBody
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Path
import retrofit2.http.Streaming
import retrofit2.http.Url
private const val BRANCH = "branch"
private const val REPO = "repo"
private const val FILE = "file"
interface GithubPageServices {
@GET
suspend fun fetchUpdateJSON(@Url file: String): UpdateInfo
}
interface RawServices {
@GET
@Streaming
suspend fun fetchFile(@Url url: String): ResponseBody
@GET
suspend fun fetchString(@Url url: String): String
@GET
suspend fun fetchModuleJson(@Url url: String): ModuleJson
}
interface GithubApiServices {
@GET("repos/{$REPO}/branches/{$BRANCH}")
@Headers("Accept: application/vnd.github.v3+json")
suspend fun fetchBranch(
@Path(REPO, encoded = true) repo: String,
@Path(BRANCH) branch: String
): BranchInfo
}

View File

@@ -0,0 +1,48 @@
package com.topjohnwu.magisk.core.data
import com.topjohnwu.magisk.core.model.ModuleJson
import com.topjohnwu.magisk.core.model.Release
import com.topjohnwu.magisk.core.model.UpdateJson
import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Path
import retrofit2.http.Query
import retrofit2.http.Streaming
import retrofit2.http.Url
interface RawUrl {
@GET
@Streaming
suspend fun fetchFile(@Url url: String): ResponseBody
@GET
suspend fun fetchString(@Url url: String): String
@GET
suspend fun fetchModuleJson(@Url url: String): ModuleJson
@GET
suspend fun fetchUpdateJson(@Url url: String): UpdateJson
}
interface GithubApiServices {
@GET("/repos/{owner}/{repo}/releases")
@Headers("Accept: application/vnd.github+json")
suspend fun fetchReleases(
@Path("owner") owner: String = "topjohnwu",
@Path("repo") repo: String = "Magisk",
@Query("per_page") per: Int = 10,
@Query("page") page: Int = 1,
): Response<MutableList<Release>>
@GET("/repos/{owner}/{repo}/releases/latest")
@Headers("Accept: application/vnd.github+json")
suspend fun fetchLatestRelease(
@Path("owner") owner: String = "topjohnwu",
@Path("repo") repo: String = "Magisk",
): Release
}

View File

@@ -19,7 +19,7 @@ abstract class SuLogDatabase : RoomDatabase() {
companion object {
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) = with(database) {
override fun migrate(db: SupportSQLiteDatabase) = with(db) {
execSQL("ALTER TABLE logs ADD COLUMN target INTEGER NOT NULL DEFAULT -1")
execSQL("ALTER TABLE logs ADD COLUMN context TEXT NOT NULL DEFAULT ''")
execSQL("ALTER TABLE logs ADD COLUMN gids TEXT NOT NULL DEFAULT ''")

View File

@@ -5,7 +5,7 @@ import com.squareup.moshi.Moshi
import com.topjohnwu.magisk.ProviderInstaller
import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.model.DateTimeAdapter
import com.topjohnwu.magisk.core.utils.LocaleSetting
import okhttp3.Cache
import okhttp3.ConnectionSpec
@@ -72,15 +72,13 @@ fun createOkHttpClient(context: Context): OkHttpClient {
chain.proceed(request.build())
}
if (!ProviderInstaller.install(context)) {
Info.hasGMS = false
}
ProviderInstaller.install(context)
return builder.build()
}
fun createMoshiConverterFactory(): MoshiConverterFactory {
val moshi = Moshi.Builder().build()
val moshi = Moshi.Builder().add(DateTimeAdapter()).build()
return MoshiConverterFactory.create(moshi)
}

View File

@@ -35,8 +35,8 @@ object ServiceLocator {
val markwon by lazy { createMarkwon(AppContext) }
val networkService by lazy {
NetworkService(
createApiService(retrofit, Const.Url.GITHUB_PAGE_URL),
createApiService(retrofit, Const.Url.GITHUB_RAW_URL),
createApiService(retrofit, Const.Url.INVALID_URL),
createApiService(retrofit, Const.Url.GITHUB_API_URL),
)
}
}
@@ -44,7 +44,7 @@ object ServiceLocator {
private fun createSuLogDatabase(context: Context) =
Room.databaseBuilder(context, SuLogDatabase::class.java, "sulogs.db")
.addMigrations(SuLogDatabase.MIGRATION_1_2)
.fallbackToDestructiveMigration()
.fallbackToDestructiveMigration(true)
.build()
private fun createMarkwon(context: Context) =

View File

@@ -8,7 +8,7 @@ import android.net.Uri
import android.os.Parcelable
import androidx.core.net.toUri
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.model.MagiskJson
import com.topjohnwu.magisk.core.model.UpdateInfo
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.view.Notifications
@@ -38,7 +38,7 @@ abstract class Subject : Parcelable {
@Parcelize
class App(
private val json: MagiskJson = Info.remote.magisk,
private val json: UpdateInfo = Info.update,
override val notifyId: Int = Notifications.nextId()
) : Subject() {
override val title: String get() = "Magisk-${json.version}(${json.versionCode})"

View File

@@ -109,7 +109,7 @@ fun PackageManager.getPackageInfo(uid: Int, pid: Int): PackageInfo? {
return null
}
// Try to find package name from PID
val proc = RootUtils.obj?.getAppProcess(pid)
val proc = RootUtils.getAppProcess(pid)
if (proc == null) {
if (uid == Process.SHELL_UID) {
// It is possible that some apps installed are sharing UID with shell.

View File

@@ -14,10 +14,11 @@ import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.lang.reflect.Field
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.Collections
import java.util.Locale
inline fun <In : Closeable, Out : Closeable> withInOut(
input: In,
@@ -83,19 +84,15 @@ inline fun <T, R> Flow<T>.concurrentMap(crossinline transform: suspend (T) -> R)
}
}
fun Long.toTime(format: DateFormat) = format.format(this).orEmpty()
fun Long.toTime(format: DateTimeFormatter): String = format.format(Instant.ofEpochMilli(this))
// Some devices don't allow filenames containing ":"
val timeFormatStandard by lazy {
SimpleDateFormat(
"yyyy-MM-dd'T'HH.mm.ss",
Locale.ROOT
)
val timeFormatStandard: DateTimeFormatter by lazy {
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH.mm.ss").withZone(ZoneId.systemDefault())
}
val timeDateFormat: DateFormat by lazy {
DateFormat.getDateTimeInstance(
DateFormat.DEFAULT,
DateFormat.DEFAULT,
Locale.ROOT
)
val timeDateFormat: DateTimeFormatter by lazy {
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withZone(ZoneId.systemDefault())
}
val dateFormat: DateTimeFormatter by lazy {
DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withZone(ZoneId.systemDefault())
}

View File

@@ -1,17 +1,22 @@
package com.topjohnwu.magisk.core.model
import android.os.Parcelable
import com.squareup.moshi.FromJson
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonQualifier
import com.squareup.moshi.ToJson
import kotlinx.parcelize.Parcelize
import java.time.Instant
@JsonClass(generateAdapter = true)
data class UpdateInfo(
val magisk: MagiskJson = MagiskJson(),
class UpdateJson(
val magisk: UpdateInfo = UpdateInfo(),
)
@Parcelize
@JsonClass(generateAdapter = true)
data class MagiskJson(
data class UpdateInfo(
val version: String = "",
val versionCode: Int = -1,
val link: String = "",
@@ -27,11 +32,37 @@ data class ModuleJson(
)
@JsonClass(generateAdapter = true)
data class CommitInfo(
val sha: String
data class ReleaseAssets(
val name: String,
@param:Json(name = "browser_download_url") val url: String,
)
class DateTimeAdapter {
@ToJson
fun toJson(date: Instant): String {
return date.toString()
}
@FromJson
fun fromJson(date: String): Instant {
return Instant.parse(date)
}
}
@JsonClass(generateAdapter = true)
data class BranchInfo(
val commit: CommitInfo
)
data class Release(
@param:Json(name = "tag_name") val tag: String,
val name: String,
val prerelease: Boolean,
val assets: List<ReleaseAssets>,
val body: String,
@param:Json(name = "created_at") val createdTime: Instant,
) {
val versionCode: Int get() {
return if (tag[0] == 'v') {
(tag.drop(1).toFloat() * 1000).toInt()
} else {
tag.drop(7).toInt()
}
}
}

View File

@@ -5,6 +5,7 @@ import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.nio.ExtendedFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
@@ -12,7 +13,7 @@ import java.io.IOException
import java.util.Locale
data class LocalModule(
private val path: String,
val base: ExtendedFile,
) : Module() {
private val svc get() = ServiceLocator.networkService
@@ -24,20 +25,18 @@ data class LocalModule(
var description: String = ""
var updateInfo: OnlineModule? = null
var outdated = false
private var updateUrl: String = ""
private val removeFile = RootUtils.fs.getFile(path, "remove")
private val disableFile = RootUtils.fs.getFile(path, "disable")
private val updateFile = RootUtils.fs.getFile(path, "update")
private val riruFolder = RootUtils.fs.getFile(path, "riru")
private val zygiskFolder = RootUtils.fs.getFile(path, "zygisk")
private val unloaded = RootUtils.fs.getFile(zygiskFolder, "unloaded")
val updated: Boolean get() = updateFile.exists()
val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists()
val isZygisk: Boolean get() = zygiskFolder.exists()
val zygiskUnloaded: Boolean get() = unloaded.exists()
val hasAction: Boolean;
private val removeFile = base.getChildFile("remove")
private val disableFile = base.getChildFile("disable")
private val updateFile = base.getChildFile("update")
val zygiskFolder = base.getChildFile("zygisk")
val updated get() = updateFile.exists()
val isRiru = (id == "riru-core") || base.getChildFile("riru").exists()
val isZygisk = zygiskFolder.exists()
val zygiskUnloaded = zygiskFolder.getChildFile("unloaded").exists()
val hasAction = base.getChildFile("action.sh").exists()
var enable: Boolean
get() = !disableFile.exists()
@@ -90,19 +89,16 @@ data class LocalModule(
init {
runCatching {
parseProps(Shell.cmd("dos2unix < $path/module.prop").exec().out)
parseProps(Shell.cmd("dos2unix < $base/module.prop").exec().out)
}
if (id.isEmpty()) {
val sep = path.lastIndexOf('/')
id = path.substring(sep + 1)
id = base.name
}
if (name.isEmpty()) {
name = id
}
hasAction = RootUtils.fs.getFile(path, "action.sh").exists()
}
suspend fun fetch(): Boolean {
@@ -125,14 +121,14 @@ data class LocalModule(
companion object {
fun loaded() = RootUtils.fs.getFile(Const.MAGISK_PATH).exists()
fun loaded() = RootUtils.fs.getFile(Const.MODULE_PATH).exists()
suspend fun installed() = withContext(Dispatchers.IO) {
RootUtils.fs.getFile(Const.MAGISK_PATH)
RootUtils.fs.getFile(Const.MODULE_PATH)
.listFiles()
.orEmpty()
.filter { !it.isFile && !it.isHidden }
.map { LocalModule("${Const.MAGISK_PATH}/${it.name}") }
.map { LocalModule(it) }
.sortedBy { it.name.lowercase(Locale.ROOT) }
}
}

View File

@@ -4,15 +4,16 @@ import com.topjohnwu.magisk.core.data.magiskdb.MagiskDB
class SuPolicy(
val uid: Int,
var policy: Int = INTERACTIVE,
var policy: Int = QUERY,
var remain: Long = -1L,
var logging: Boolean = true,
var notification: Boolean = true,
) {
companion object {
const val INTERACTIVE = 0
const val QUERY = 0
const val DENY = 1
const val ALLOW = 2
const val RESTRICT = 3
}
fun toMap(): MutableMap<String, Any> {

View File

@@ -1,46 +1,114 @@
package com.topjohnwu.magisk.core.repository
import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Config.Value.BETA_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.CANARY_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.CUSTOM_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.DEBUG_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.DEFAULT_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.STABLE_CHANNEL
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.data.GithubPageServices
import com.topjohnwu.magisk.core.data.RawServices
import com.topjohnwu.magisk.core.data.GithubApiServices
import com.topjohnwu.magisk.core.data.RawUrl
import com.topjohnwu.magisk.core.ktx.dateFormat
import com.topjohnwu.magisk.core.model.Release
import com.topjohnwu.magisk.core.model.ReleaseAssets
import com.topjohnwu.magisk.core.model.UpdateInfo
import retrofit2.HttpException
import timber.log.Timber
import java.io.IOException
class NetworkService(
private val pages: GithubPageServices,
private val raw: RawServices
private val raw: RawUrl,
private val api: GithubApiServices,
) {
suspend fun fetchUpdate() = safe {
var info = when (Config.updateChannel) {
DEFAULT_CHANNEL, STABLE_CHANNEL -> fetchStableUpdate()
DEFAULT_CHANNEL -> if (BuildConfig.DEBUG) fetchDebugUpdate() else fetchStableUpdate()
STABLE_CHANNEL -> fetchStableUpdate()
BETA_CHANNEL -> fetchBetaUpdate()
CANARY_CHANNEL -> fetchCanaryUpdate()
DEBUG_CHANNEL -> fetchDebugUpdate()
CUSTOM_CHANNEL -> fetchCustomUpdate(Config.customChannelUrl)
else -> throw IllegalArgumentException()
}
if (info.magisk.versionCode < Info.env.versionCode &&
Config.updateChannel == DEFAULT_CHANNEL) {
if (info.versionCode < Info.env.versionCode &&
Config.updateChannel == DEFAULT_CHANNEL &&
!BuildConfig.DEBUG
) {
Config.updateChannel = BETA_CHANNEL
info = fetchBetaUpdate()
}
info
}
// UpdateInfo
private suspend fun fetchStableUpdate() = pages.fetchUpdateJSON("stable.json")
private suspend fun fetchBetaUpdate() = pages.fetchUpdateJSON("beta.json")
private suspend fun fetchCanaryUpdate() = pages.fetchUpdateJSON("canary.json")
private suspend fun fetchDebugUpdate() = pages.fetchUpdateJSON("debug.json")
private suspend fun fetchCustomUpdate(url: String) = pages.fetchUpdateJSON(url)
suspend fun fetchUpdate(version: Int) = safe {
findRelease { it.versionCode == version }.asInfo()
}
// Keep going through all release pages until we find a match
private suspend inline fun findRelease(predicate: (Release) -> Boolean): Release? {
var page = 1
while (true) {
val response = api.fetchReleases(page = page)
val releases = response.body() ?: throw HttpException(response)
// Remove all non Magisk releases
releases.removeAll { it.tag[0] != 'v' && !it.tag.startsWith("canary") }
// Make sure it's sorted correctly
releases.sortByDescending { it.createdTime }
releases.find(predicate)?.let { return it }
if (response.headers()["link"]?.contains("rel=\"next\"", ignoreCase = true) == true) {
page += 1
} else {
return null
}
}
}
private inline fun Release?.asInfo(
selector: (ReleaseAssets) -> Boolean = {
// Default selector picks the non-debug APK
it.name.run { endsWith(".apk") && !contains("debug") }
}): UpdateInfo {
return if (this == null) UpdateInfo()
else if (tag[0] == 'v') asPublicInfo(selector)
else asCanaryInfo(selector)
}
private inline fun Release.asPublicInfo(selector: (ReleaseAssets) -> Boolean): UpdateInfo {
val version = tag.drop(1)
val date = dateFormat.format(createdTime)
return UpdateInfo(
version = version,
versionCode = versionCode,
link = assets.find(selector)!!.url,
note = "## $date $name\n\n$body"
)
}
private inline fun Release.asCanaryInfo(selector: (ReleaseAssets) -> Boolean): UpdateInfo {
return UpdateInfo(
version = name.substring(8, 16),
versionCode = versionCode,
link = assets.find(selector)!!.url,
note = "## $name\n\n$body"
)
}
// Version number: debug == beta >= stable
// Find the latest non-prerelease
private suspend fun fetchStableUpdate() = api.fetchLatestRelease().asInfo()
// Find the latest release, regardless whether it's prerelease
private suspend fun fetchBetaUpdate() = findRelease { true }.asInfo()
private suspend fun fetchDebugUpdate() =
findRelease { true }.asInfo { it.name == "app-debug.apk" }
private suspend fun fetchCustomUpdate(url: String): UpdateInfo {
val info = raw.fetchUpdateJson(url).magisk
return info.let { it.copy(note = raw.fetchString(it.note)) }
}
private inline fun <T> safe(factory: () -> T): T? {
return try {

View File

@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
public class ByteArrayStream extends ByteArrayOutputStream {
@@ -27,4 +28,8 @@ public class ByteArrayStream extends ByteArrayOutputStream {
public ByteArrayInputStream getInputStream() {
return new ByteArrayInputStream(buf, 0, count);
}
public ByteBuffer toByteBuffer() {
return ByteBuffer.wrap(buf, 0, count);
}
}

View File

@@ -510,7 +510,7 @@ public class SignApk {
privateKey[0] = key;
// Generate, in memory, an APK signed using standard JAR Signature Scheme.
ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
ByteArrayStream v1SignedApkBuf = new ByteArrayStream();
JarOutputStream outputJar = new JarOutputStream(v1SignedApkBuf);
// Use maximum compression for compressed entries because the APK lives forever on
// the system partition.
@@ -519,8 +519,7 @@ public class SignApk {
copyFiles(manifest, inputJar, outputJar, timestamp, alignment);
signFile(manifest, publicKey, privateKey, timestamp, outputJar);
outputJar.close();
ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray());
v1SignedApkBuf.reset();
ByteBuffer v1SignedApk = v1SignedApkBuf.toByteBuffer();
ByteBuffer[] outputChunks;
List<ApkSignerV2.SignerConfig> signerConfigs = createV2SignerConfigs(privateKey, publicKey,

View File

@@ -70,7 +70,7 @@ object SuCallbackHandler {
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids)
if (notify)
notify(context, log.action == SuPolicy.ALLOW, log.appName)
notify(context, log.action >= SuPolicy.ALLOW, log.appName)
runBlocking { ServiceLocator.logRepo.insert(log) }
}
@@ -86,7 +86,7 @@ object SuCallbackHandler {
pm.getPackageInfo(uid, pid)?.applicationInfo?.getLabel(pm)
}.getOrNull() ?: "[UID] $uid"
notify(context, policy == SuPolicy.ALLOW, appName)
notify(context, policy >= SuPolicy.ALLOW, appName)
}
private fun notify(context: Context, granted: Boolean, appName: String) {

View File

@@ -82,7 +82,11 @@ class SuRequestHandler(
}
suspend fun respond(action: Int, time: Long) {
policy.policy = action
if (action == SuPolicy.ALLOW && Config.suRestrict) {
policy.policy = SuPolicy.RESTRICT
} else {
policy.policy = action
}
if (time >= 0) {
policy.remain = TimeUnit.MINUTES.toSeconds(time)
} else {

View File

@@ -17,7 +17,6 @@ import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.copyAll
import com.topjohnwu.magisk.core.ktx.copyAndClose
import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.utils.DummyList
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
@@ -47,7 +46,6 @@ import java.io.OutputStream
import java.io.PushbackInputStream
import java.nio.ByteBuffer
import java.security.SecureRandom
import java.util.Arrays
import java.util.Locale
import java.util.concurrent.atomic.AtomicBoolean
@@ -83,10 +81,12 @@ abstract class MagiskInstallImpl protected constructor(
}
private fun findImage(slot: String): Boolean {
val bootPath = (
"(RECOVERYMODE=${Config.recovery} " +
"SLOT=$slot find_boot_image; " +
"echo \$BOOTIMAGE)").fsh()
val cmd =
"RECOVERYMODE=${Config.recovery} " +
"VENDORBOOT=${Info.isVendorBoot} " +
"SLOT=$slot " +
"find_boot_image; echo \$BOOTIMAGE"
val bootPath = ("($cmd)").fsh()
if (bootPath.isEmpty()) {
console.add("! Unable to detect target image")
return false
@@ -134,7 +134,6 @@ abstract class MagiskInstallImpl protected constructor(
if (entry != null) {
val magisk32 = File(installDir, "magisk32")
zf.getInputStream(entry).writeTo(magisk32)
magisk32.setExecutable(true)
}
}
}
@@ -149,11 +148,15 @@ abstract class MagiskInstallImpl protected constructor(
Os.symlink(lib.path, "$installDir/$name")
}
// Also symlink magisk32 on 64-bit devices that supports 32-bit
val lib32 = info.javaClass.getDeclaredField("secondaryNativeLibraryDir")
.get(info) as String?
if (lib32 != null) {
Os.symlink("$lib32/libmagisk.so", "$installDir/magisk32");
// Also extract magisk32 on 64-bit devices that supports 32-bit
val abi32 = Const.CPU_ABI_32
if (Process.is64Bit() && abi32 != null) {
val name = "lib/$abi32/libmagisk.so"
val entry = javaClass.classLoader!!.getResourceAsStream(name)
if (entry != null) {
val magisk32 = File(installDir, "magisk32")
entry.writeTo(magisk32)
}
}
}
@@ -191,7 +194,8 @@ abstract class MagiskInstallImpl protected constructor(
return true
}
private suspend fun InputStream.copyAndCloseOut(out: OutputStream) = out.use { copyAll(it) }
private suspend fun InputStream.copyAndCloseOut(out: OutputStream) =
out.use { copyAll(it, 1024 * 1024) }
private class NoAvailableStream(s: InputStream) : FilterInputStream(s) {
// Make sure available is never called on the actual stream and always return 0
@@ -225,8 +229,8 @@ abstract class MagiskInstallImpl protected constructor(
console.add("- Processing tar file")
var entry: TarArchiveEntry? = tarIn.nextEntry
fun TarArchiveEntry.decompressedStream(): InputStream {
val stream = if (name.endsWith(".lz4"))
fun decompressedStream(): InputStream {
val stream = if (tarIn.currentEntry.name.endsWith(".lz4"))
FramedLZ4CompressorInputStream(tarIn, true) else tarIn
return NoAvailableStream(stream)
}
@@ -252,9 +256,9 @@ abstract class MagiskInstallImpl protected constructor(
if (bootItem != null) {
console.add("-- Extracting: ${bootItem.name}")
entry.decompressedStream().copyAndCloseOut(bootItem.file.newOutputStream())
decompressedStream().copyAndCloseOut(bootItem.file.newOutputStream())
} else if (entry.name.contains("vbmeta.img")) {
val rawData = entry.decompressedStream().readBytes()
val rawData = decompressedStream().readBytes()
// Valid vbmeta.img should be at least 256 bytes
if (rawData.size < 256)
continue
@@ -287,7 +291,7 @@ abstract class MagiskInstallImpl protected constructor(
} else {
console.add("-- Copying : ${entry.name}")
tarOut.putArchiveEntry(entry)
tarIn.copyAll(tarOut, bufferSize = 1024 * 1024)
tarIn.copyAll(tarOut)
tarOut.closeArchiveEntry()
}
entry = tarIn.nextEntry ?: break
@@ -429,7 +433,7 @@ abstract class MagiskInstallImpl protected constructor(
// Process input file
try {
PushbackInputStream(uri.inputStream(), 512).use { src ->
PushbackInputStream(uri.inputStream().buffered(1024 * 1024), 512).use { src ->
val head = ByteArray(512)
if (src.read(head) != head.size) {
console.add("! Invalid input file")
@@ -438,12 +442,13 @@ abstract class MagiskInstallImpl protected constructor(
src.unread(head)
val magic = head.copyOf(4)
val tarMagic = Arrays.copyOfRange(head, 257, 262)
val tarMagic = head.copyOfRange(257, 262)
srcBoot = if (tarMagic.contentEquals("ustar".toByteArray())) {
// tar file
outFile = MediaStoreUtils.getFile("$destName.tar")
outStream = TarArchiveOutputStream(outFile.uri.outputStream()).also {
val os = outFile.uri.outputStream().buffered(1024 * 1024)
outStream = TarArchiveOutputStream(os).also {
it.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR)
it.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU)
}
@@ -500,7 +505,7 @@ abstract class MagiskInstallImpl protected constructor(
bootItem.file = newBoot
bootItem.copyTo(outStream as TarArchiveOutputStream)
} else {
newBoot.newInputStream().copyAndClose(outStream)
newBoot.newInputStream().use { it.copyAll(outStream, 1024 * 1024) }
}
newBoot.delete()
@@ -514,6 +519,8 @@ abstract class MagiskInstallImpl protected constructor(
outFile.delete()
Timber.e(e)
return false
} finally {
outStream.close()
}
// Fix up binaries

View File

@@ -62,7 +62,7 @@ class NetworkObserver(context: Context) {
}
private fun postValue(b: Boolean) {
Info.remote = Info.EMPTY_REMOTE
Info.resetUpdate()
Info.isConnected.postValue(b)
}

View File

@@ -7,11 +7,14 @@ import android.content.ServiceConnection
import android.os.IBinder
import android.system.Os
import androidx.core.content.getSystemService
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import com.topjohnwu.superuser.ipc.RootService
import com.topjohnwu.superuser.nio.FileSystemManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.File
import java.util.concurrent.locks.AbstractQueuedSynchronizer
@@ -43,16 +46,7 @@ class RootUtils(stub: Any?) : RootService() {
return object : IRootUtils.Stub() {
override fun getAppProcess(pid: Int) = safe(null) { getAppProcessImpl(pid) }
override fun getFileSystem(): IBinder = FileSystemManager.getService()
}
}
private inline fun <T> safe(default: T, block: () -> T): T {
return try {
block()
} catch (e: Throwable) {
// The process died unexpectedly
Timber.e(e)
default
override fun addSystemlessHosts() = safe(false) { addSystemlessHostsImpl() }
}
}
@@ -78,6 +72,26 @@ class RootUtils(stub: Any?) : RootService() {
return null
}
private fun addSystemlessHostsImpl(): Boolean {
val module = File(Const.MODULE_PATH, "hosts")
if (module.exists()) return true
val hosts = File(module, "system/etc/hosts")
if (!hosts.parentFile.mkdirs()) return false
File(module, "module.prop").outputStream().writer().use {
it.write("""
id=hosts
name=Systemless Hosts
version=1.0
versionCode=1
author=Magisk
description=Magisk app built-in systemless hosts module
""".trimIndent())
}
File("/system/etc/hosts").copyTo(hosts)
File(module, "update").createNewFile()
return true
}
object Connection : AbstractQueuedSynchronizer(), ServiceConnection {
init {
state = 1
@@ -131,11 +145,25 @@ class RootUtils(stub: Any?) : RootService() {
return field
}
private set
var obj: IRootUtils? = null
private var obj: IRootUtils? = null
get() {
Connection.await()
return field
}
private set
fun getAppProcess(pid: Int) = safe(null) { obj?.getAppProcess(pid) }
suspend fun addSystemlessHosts() =
withContext(Dispatchers.IO) { safe(false) { obj?.addSystemlessHosts() ?: false } }
private inline fun <T> safe(default: T, block: () -> T): T {
return try {
block()
} catch (e: Throwable) {
// The process died unexpectedly
Timber.e(e)
default
}
}
}
}

View File

@@ -1,50 +0,0 @@
package com.topjohnwu.magisk.core.utils
import com.topjohnwu.magisk.core.ktx.copyAll
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream
import org.apache.commons.compress.archivers.zip.ZipFile
import java.io.File
import java.io.IOException
import java.io.InputStream
@Throws(IOException::class)
suspend fun File.unzip(folder: File, path: String = "", junkPath: Boolean = false) {
ZipFile.Builder().setFile(this).get().use { zip ->
for (entry in zip.entries) {
if (!entry.name.startsWith(path) || entry.isDirectory) {
// Ignore directories, only create files
continue
}
val name = if (junkPath)
entry.name.substring(entry.name.lastIndexOf('/') + 1)
else
entry.name
val dest = File(folder, name)
dest.parentFile?.mkdirs()
dest.outputStream().use { out -> zip.getInputStream(entry).copyAll(out) }
}
}
}
@Throws(IOException::class)
suspend fun InputStream.unzip(folder: File, path: String = "", junkPath: Boolean = false) {
ZipArchiveInputStream(this).use { zin ->
var entry: ZipArchiveEntry
while (true) {
entry = zin.nextEntry ?: break
if (!entry.name.startsWith(path) || entry.isDirectory) {
// Ignore directories, only create files
continue
}
val name = if (junkPath)
entry.name.substring(entry.name.lastIndexOf('/') + 1)
else
entry.name
val dest = File(folder, name)
dest.parentFile?.mkdirs()
dest.outputStream().use { out -> zin.copyAll(out) }
}
}
}

View File

@@ -5,9 +5,25 @@ import androidx.annotation.Keep
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.test.Environment.Companion.EMPTY_ZYGISK
import com.topjohnwu.magisk.test.Environment.Companion.INVALID_ZYGISK
import com.topjohnwu.magisk.test.Environment.Companion.MOUNT_TEST
import com.topjohnwu.magisk.test.Environment.Companion.REMOVE_TEST
import com.topjohnwu.magisk.test.Environment.Companion.SEPOLICY_RULE
import com.topjohnwu.magisk.test.Environment.Companion.UPGRADE_TEST
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Assume.assumeTrue
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import java.util.concurrent.TimeUnit
@@ -21,6 +37,17 @@ class AdditionalTest : BaseTest {
private const val SHELL_PKG = "com.android.shell"
private const val LSPOSED_CATEGORY = "org.lsposed.manager.LAUNCH_MANAGER"
private const val LSPOSED_PKG = "org.lsposed.manager"
private lateinit var modules: List<LocalModule>
@BeforeClass
@JvmStatic
fun before() {
BaseTest.prerequisite()
runBlocking {
modules = LocalModule.installed()
}
}
}
@After
@@ -29,9 +56,25 @@ class AdditionalTest : BaseTest {
}
@Test
fun testLaunchLsposedManager() {
fun testModuleCount() {
var expected = 4
if (Environment.mount()) expected++
if (Environment.preinit()) expected++
if (Environment.lsposed()) expected++
if (Environment.shamiko()) expected++
assertEquals("Module count incorrect", expected, modules.size)
}
@Test
fun testLsposed() {
assumeTrue(Environment.lsposed())
val module = modules.find { it.id == "zygisk_lsposed" }
assertNotNull("zygisk_lsposed is not installed", module)
module!!
assertFalse("zygisk_lsposed is not enabled", module.zygiskUnloaded)
// Launch lsposed manager to ensure the module is active
uiAutomation.executeShellCommand(
"am start -c $LSPOSED_CATEGORY $SHELL_PKG/.BugreportWarningActivity"
).let { pfd -> AutoCloseInputStream(pfd).use { it.readBytes() } }
@@ -42,4 +85,77 @@ class AdditionalTest : BaseTest {
device.wait(Until.hasObject(By.res(pattern)), TimeUnit.SECONDS.toMillis(10))
)
}
@Test
fun testModuleMount() {
assumeTrue(Environment.mount())
assertNotNull("$MOUNT_TEST is not installed", modules.find { it.id == MOUNT_TEST })
assertTrue(
"/system/fonts/newfile should exist",
RootUtils.fs.getFile("/system/fonts/newfile").exists()
)
assertFalse(
"/system/bin/screenrecord should not exist",
RootUtils.fs.getFile("/system/bin/screenrecord").exists()
)
val egg = RootUtils.fs.getFile("/system/app/EasterEgg").list() ?: arrayOf()
assertArrayEquals(
"/system/app/EasterEgg should be replaced",
egg,
arrayOf("newfile")
)
}
@Test
fun testSepolicyRule() {
assumeTrue(Environment.preinit())
assertNotNull("$SEPOLICY_RULE is not installed", modules.find { it.id == SEPOLICY_RULE })
assertTrue(
"Module sepolicy.rule is not applied",
Shell.cmd("magiskpolicy --print-rules | grep -q magisk_test").exec().isSuccess
)
}
@Test
fun testEmptyZygiskModule() {
val module = modules.find { it.id == EMPTY_ZYGISK }
assertNotNull("$EMPTY_ZYGISK is not installed", module)
module!!
assertTrue("$EMPTY_ZYGISK should be zygisk unloaded", module.zygiskUnloaded)
}
@Test
fun testInvalidZygiskModule() {
val module = modules.find { it.id == INVALID_ZYGISK }
assertNotNull("$INVALID_ZYGISK is not installed", module)
module!!
assertTrue("$INVALID_ZYGISK should be zygisk unloaded", module.zygiskUnloaded)
}
@Test
fun testRemoveModule() {
assertNull("$REMOVE_TEST should be removed", modules.find { it.id == REMOVE_TEST })
assertTrue(
"Uninstaller of $REMOVE_TEST should be run",
RootUtils.fs.getFile(Environment.REMOVE_TEST_MARKER).exists()
)
}
@Test
fun testModuleUpgrade() {
val module = modules.find { it.id == UPGRADE_TEST }
assertNotNull("$UPGRADE_TEST is not installed", module)
module!!
assertFalse("$UPGRADE_TEST should be disabled", module.enable)
assertTrue(
"$UPGRADE_TEST should be updated",
module.base.getChildFile("post-fs-data.sh").exists()
)
assertFalse(
"$UPGRADE_TEST should be updated",
module.base.getChildFile("service.sh").exists()
)
}
}

View File

@@ -12,7 +12,8 @@ import org.junit.Assert.assertTrue
interface BaseTest {
val instrumentation: Instrumentation
get() = InstrumentationRegistry.getInstrumentation()
val context: Context get() = instrumentation.targetContext
val appContext: Context get() = instrumentation.targetContext
val testContext: Context get() = instrumentation.context
val uiAutomation: UiAutomation get() = instrumentation.uiAutomation
val device: UiDevice get() = UiDevice.getInstance(instrumentation)

View File

@@ -6,21 +6,29 @@ import androidx.annotation.Keep
import androidx.core.net.toUri
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.topjohnwu.magisk.core.BuildConfig.APP_PACKAGE_NAME
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.download.DownloadNotifier
import com.topjohnwu.magisk.core.download.DownloadProcessor
import com.topjohnwu.magisk.core.ktx.cachedFile
import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.tasks.AppMigration
import com.topjohnwu.magisk.core.tasks.FlashZip
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.nio.ExtendedFile
import kotlinx.coroutines.runBlocking
import org.apache.commons.compress.archivers.zip.ZipFile
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Assume.assumeTrue
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import timber.log.Timber
import java.io.File
import java.io.PrintStream
@Keep
@RunWith(AndroidJUnit4::class)
@@ -31,12 +39,34 @@ class Environment : BaseTest {
@JvmStatic
fun before() = BaseTest.prerequisite()
fun lsposed(): Boolean {
return Build.VERSION.SDK_INT >= 27 && Build.VERSION.SDK_INT <= 34
// The kernel running on emulators < API 26 does not play well with
// magic mount. Skip mount_test on those legacy platforms.
fun mount(): Boolean {
return Build.VERSION.SDK_INT >= 26
}
private const val LSPOSED_URL =
"https://github.com/LSPosed/LSPosed/releases/download/v1.9.2/LSPosed-v1.9.2-7024-zygisk-release.zip"
// It is possible that there are no suitable preinit partition to use
fun preinit(): Boolean {
return Shell.cmd("magisk --preinit-device").exec().isSuccess
}
fun lsposed(): Boolean {
return Build.VERSION.SDK_INT in 27..34
}
fun shamiko(): Boolean {
return Build.VERSION.SDK_INT >= 27
}
private const val MODULE_UPDATE_PATH = "/data/adb/modules_update"
private const val MODULE_ERROR = "Module zip processing incorrect"
const val MOUNT_TEST = "mount_test"
const val SEPOLICY_RULE = "sepolicy_rule"
const val INVALID_ZYGISK = "invalid_zygisk"
const val REMOVE_TEST = "remove_test"
const val REMOVE_TEST_MARKER = "/dev/.remove_test_removed"
const val EMPTY_ZYGISK = "empty_zygisk"
const val UPGRADE_TEST = "upgrade_test"
}
object TimberLog : CallbackList<String>(Runnable::run) {
@@ -45,35 +75,191 @@ class Environment : BaseTest {
}
}
private fun checkModuleZip(file: File) {
// Make sure module processing is correct
ZipFile.Builder().setFile(file).get().use { zip ->
val meta = zip.entries
.asSequence()
.filter { it.name.startsWith("META-INF") }
.toMutableList()
assertEquals(MODULE_ERROR, 6, meta.size)
val binary = zip.getInputStream(
zip.getEntry("META-INF/com/google/android/update-binary")
).use { it.readBytes() }
val ref = appContext.assets.open("module_installer.sh").use { it.readBytes() }
assertArrayEquals(MODULE_ERROR, ref, binary)
val script = zip.getInputStream(
zip.getEntry("META-INF/com/google/android/updater-script")
).use { it.readBytes() }
assertArrayEquals(MODULE_ERROR, "#MAGISK\n".toByteArray(), script)
}
}
private fun setupMountTest(root: ExtendedFile) {
val error = "$MOUNT_TEST setup failed"
val path = root.getChildFile(MOUNT_TEST)
// Create /system/fonts/newfile
val etc = path.getChildFile("system").getChildFile("fonts")
assertTrue(error, etc.mkdirs())
assertTrue(error, etc.getChildFile("newfile").createNewFile())
// Create /system/app/EasterEgg/.replace
val egg = path.getChildFile("system").getChildFile("app").getChildFile("EasterEgg")
assertTrue(error, egg.mkdirs())
assertTrue(error, egg.getChildFile(".replace").createNewFile())
// Create /system/app/EasterEgg/newfile
assertTrue(error, egg.getChildFile("newfile").createNewFile())
// Delete /system/bin/screenrecord
val bin = path.getChildFile("system").getChildFile("bin")
assertTrue(error, bin.mkdirs())
assertTrue(error, Shell.cmd("mknod $bin/screenrecord c 0 0").exec().isSuccess)
assertTrue(error, Shell.cmd("set_default_perm $path").exec().isSuccess)
}
private fun setupSystemlessHost() {
val error = "hosts setup failed"
assertTrue(error, runBlocking { RootUtils.addSystemlessHosts() })
assertTrue(error, RootUtils.fs.getFile(Const.MODULE_PATH).getChildFile("hosts").exists())
}
private fun setupSepolicyRuleModule(root: ExtendedFile) {
val error = "$SEPOLICY_RULE setup failed"
val path = root.getChildFile(SEPOLICY_RULE)
assertTrue(error, path.mkdirs())
// Add sepolicy patch
PrintStream(path.getChildFile("sepolicy.rule").newOutputStream()).use {
it.println("type magisk_test domain")
}
assertTrue(error, Shell.cmd(
"set_default_perm $path",
"copy_preinit_files"
).exec().isSuccess)
}
private fun setupEmptyZygiskModule(root: ExtendedFile) {
val error = "$EMPTY_ZYGISK setup failed"
val path = root.getChildFile(EMPTY_ZYGISK)
// Create an empty zygisk folder
val module = LocalModule(path)
assertTrue(error, module.zygiskFolder.mkdirs())
}
private fun setupInvalidZygiskModule(root: ExtendedFile) {
val error = "$INVALID_ZYGISK setup failed"
val path = root.getChildFile(INVALID_ZYGISK)
// Create invalid zygisk libraries
val module = LocalModule(path)
assertTrue(error, module.zygiskFolder.mkdirs())
assertTrue(error, module.zygiskFolder.getChildFile("armeabi-v7a.so").createNewFile())
assertTrue(error, module.zygiskFolder.getChildFile("arm64-v8a.so").createNewFile())
assertTrue(error, module.zygiskFolder.getChildFile("x86.so").createNewFile())
assertTrue(error, module.zygiskFolder.getChildFile("x86_64.so").createNewFile())
assertTrue(error, Shell.cmd("set_default_perm $path").exec().isSuccess)
}
private fun setupRemoveModule(root: ExtendedFile) {
val error = "$REMOVE_TEST setup failed"
val path = root.getChildFile(REMOVE_TEST)
// Create a new module but mark is as "remove"
val module = LocalModule(path)
assertTrue(error, path.mkdirs())
// Create uninstaller script
path.getChildFile("uninstall.sh").newOutputStream().writer().use {
it.write("touch $REMOVE_TEST_MARKER")
}
assertTrue(error, path.getChildFile("service.sh").createNewFile())
module.remove = true
assertTrue(error, Shell.cmd("set_default_perm $path").exec().isSuccess)
}
private fun setupUpgradeModule(root: ExtendedFile, update: ExtendedFile) {
val error = "$UPGRADE_TEST setup failed"
val oldPath = root.getChildFile(UPGRADE_TEST)
val newPath = update.getChildFile(UPGRADE_TEST)
// Create an existing module but mark as "disable
val module = LocalModule(oldPath)
assertTrue(error, oldPath.mkdirs())
module.enable = false
// Install service.sh into the old module
assertTrue(error, oldPath.getChildFile("service.sh").createNewFile())
// Create an upgrade module
assertTrue(error, newPath.mkdirs())
// Install post-fs-data.sh into the new module
assertTrue(error, newPath.getChildFile("post-fs-data.sh").createNewFile())
assertTrue(error, Shell.cmd(
"set_default_perm $oldPath",
"set_default_perm $newPath",
).exec().isSuccess)
}
@Test
fun setupMagisk() {
fun setupEnvironment() {
runBlocking {
assertTrue(
"Magisk setup failed",
MagiskInstaller.Emulator(TimberLog, TimberLog).exec()
)
}
}
@Test
fun setupLsposed() {
assumeTrue(lsposed())
val notify = object : DownloadNotifier {
override val context = this@Environment.context
override val context = appContext
override fun notifyUpdate(id: Int, editor: (Notification.Builder) -> Unit) {}
}
val processor = DownloadProcessor(notify)
val zip = context.cachedFile("lsposed.zip")
val shamiko = appContext.cachedFile("shamiko.zip")
runBlocking {
ServiceLocator.networkService.fetchFile(LSPOSED_URL).byteStream().use {
processor.handleModule(it, zip.toUri())
testContext.assets.open("shamiko.zip").use {
processor.handleModule(it, shamiko.toUri())
}
checkModuleZip(shamiko)
if (shamiko()) {
assertTrue(
"Shamiko installation failed",
FlashZip(shamiko.toUri(), TimberLog, TimberLog).exec()
)
}
assertTrue(
"LSPosed installation failed",
FlashZip(zip.toUri(), TimberLog, TimberLog).exec()
)
}
val lsp = appContext.cachedFile("lsposed.zip")
runBlocking {
testContext.assets.open("lsposed.zip").use {
processor.handleModule(it, lsp.toUri())
}
checkModuleZip(lsp)
if (lsposed()) {
assertTrue(
"LSPosed installation failed",
FlashZip(lsp.toUri(), TimberLog, TimberLog).exec()
)
}
}
val root = RootUtils.fs.getFile(Const.MODULE_PATH)
val update = RootUtils.fs.getFile(MODULE_UPDATE_PATH)
if (mount()) { setupMountTest(update) }
if (preinit()) { setupSepolicyRuleModule(update) }
setupSystemlessHost()
setupEmptyZygiskModule(update)
setupInvalidZygiskModule(update)
setupRemoveModule(root)
setupUpgradeModule(root, update)
}
@Test
@@ -82,7 +268,7 @@ class Environment : BaseTest {
assertTrue(
"App hiding failed",
AppMigration.patchAndHide(
context = context,
context = appContext,
label = "Settings",
pkg = "repackaged.$APP_PACKAGE_NAME"
)
@@ -95,7 +281,7 @@ class Environment : BaseTest {
runBlocking {
assertTrue(
"App restoration failed",
AppMigration.restoreApp(context)
AppMigration.restoreApp(appContext)
)
}
}

View File

@@ -6,25 +6,25 @@
<string name="logs">السجلات</string>
<string name="settings">الإعدادات</string>
<string name="install">تثبيت</string>
<string name="section_home">الأساسي</string>
<string name="section_theme">السِمات</string>
<string name="section_home">الصفحة الرئيسية</string>
<string name="section_theme">المظهر</string>
<!--Home-->
<string name="no_connection">لا يوجد إتصال</string>
<string name="app_changelog">تفاصيل التحديث</string>
<string name="loading">جارٍ التحميل...</string>
<string name="update">تحديث</string>
<string name="not_available">غير/متوفر</string>
<string name="not_available">غير متوفر</string>
<string name="hide">إخفاء</string>
<string name="home_package">الحزمة</string>
<string name="home_support_title">تبرع لنا</string>
<string name="home_item_source">الكود المصدري للتطبيق</string>
<string name="home_support_content">مـاجـيسك هي، وستظل دوماً، مجانيةً و مفتوحة المصدر، اظهر اهتمامك لنا لكي نبقيها هكذا بدعم مالي صغير</string>
<string name="home_support_content">ماجيسك هو، وسيظل دوماً، مجانياّ و مفتوح المصدر، اظهر اهتمامك لنا لكي نبقيه هكذا بدعم مالي صغير</string>
<string name="home_installed_version">تم التثبيت</string>
<string name="home_latest_version">آخر إصدار</string>
<string name="invalid_update_channel">مصدر التحديث غير صالح</string>
<string name="uninstall_magisk_title">إلغاء تثبيت Magisk</string>
<string name="uninstall_magisk_title">إلغاء تثبيت ماجيسك</string>
<string name="uninstall_magisk_msg">ستُعطل/ستُحذف جميع الإضافات. سيُحذف الروت، وربما ستشفر بياناتك إذا لم تكن غير مشفرة حالياً.</string>
<!--Install-->
@@ -34,7 +34,7 @@
<string name="install_options_title">الخيارات</string>
<string name="install_method_title">الطريقة</string>
<string name="install_next">التالي</string>
<string name="install_start">هيا، بنا</string>
<string name="install_start">هيا بنا</string>
<string name="manager_download_install">اضغط للتنزيل و التثبيت</string>
<string name="direct_install">تثبيت مباشر (موصى بها)</string>
<string name="install_inactive_slot">التثبيت على المنطقة الغير نشطة (بعد OTA)</string>
@@ -87,15 +87,15 @@
<!-- MagiskHide -->
<string name="show_system_app">إظهار برامج النظام</string>
<string name="hide_filter_hint">البحث بالإسم</string>
<string name="hide_filter_hint">البحث بالاسم</string>
<string name="hide_search">ابحث</string>
<!--Module Fragment-->
<string name="no_info_provided">م توفر معلومات)</string>
<string name="no_info_provided">ا تتوفر معلومات)</string>
<string name="reboot_recovery">إعادة التشغيل إلى Recovery</string>
<string name="reboot_bootloader">إعادة التشغيل إلى Bootloader</string>
<string name="reboot_download">إعادة التشغيل إلى وضـع Odin</string>
<string name="reboot_edl">إعادة التشغيل إلى وضـعية EDL</string>
<string name="reboot_edl">إعادة التشغيل إلى EDL</string>
<string name="module_version_author">%1$sبواسطة%2$s</string>
<string name="module_state_remove">إزالة </string>
<string name="module_state_restore">إسترجاع</string>
@@ -104,15 +104,15 @@
<string name="external_rw_permission_denied">امنحني إذن الولوج للذاكرة الداخلية</string>
<!--Settings -->
<string name="settings_dark_mode_title">وضـعية الِسمات</string>
<string name="settings_dark_mode_message">حدد الوضـع الذي يناسب ذوقك</string>
<string name="settings_dark_mode_title">المظهر</string>
<string name="settings_dark_mode_message">حدد المظهر الذي يناسب ذوقك</string>
<string name="settings_dark_mode_light">الوضـع المضيء</string>
<string name="settings_dark_mode_system">اتبّع النظام</string>
<string name="settings_dark_mode_dark">وضـع الظلام</string>
<string name="settings_dark_mode_dark">الوضع المظلم</string>
<string name="settings_download_path_title">مسار التحميل</string>
<string name="settings_download_path_message">ستحمل الملفات إلى %1$s</string>
<string name="language">اللغة</string>
<string name="system_default">(الأفتراضي)</string>
<string name="system_default">(الإفتراضي)</string>
<string name="settings_check_update_title">تحقق من التحديثات</string>
<string name="settings_check_update_summary">التحقق من التحديثات في الخلفية بشكل دوري</string>
<string name="settings_update_channel_title">مصدر التحديثات</string>
@@ -123,8 +123,8 @@
<string name="settings_hosts_title">موانع الاعلانات</string>
<string name="settings_hosts_summary">حجب الاعلانات دون تعديل النظام</string>
<string name="settings_hosts_toast">تم تمكين خاصية حجب الاعلانات</string>
<string name="settings_app_name_hint">الإسم الجديد</string>
<string name="settings_app_name_helper">التطبيق الجديد سوف يملك هذا الإسم</string>
<string name="settings_app_name_hint">الاسم الجديد</string>
<string name="settings_app_name_helper">التطبيق الجديد سوف يملك هذا الاسم</string>
<string name="settings_app_name_error">الصيغة غير مقبولة</string>
<string name="settings_su_app_adb">التطبيقات و ADB</string>
<string name="settings_su_app">التطبيقات فقط</string>
@@ -140,51 +140,51 @@
<string name="auto_response">الفعل التلقائي</string>
<string name="request_timeout">المهلة قبل الفعل التلقائي</string>
<string name="superuser_notification">إشعارات طلبات الروت</string>
<string name="settings_su_reauth_title">إعادة المصادقة بعد الترقية</string>
<string name="settings_su_reauth_summary">أعد مصادقة صلاحيات الروت بعد إجراء ترقيات للتطبيق</string>
<string name="settings_su_reauth_title">إعادة المصادقة بعد التحديث</string>
<string name="settings_su_reauth_summary">أعد مصادقة صلاحيات الروت بعد تحديث التطبيق</string>
<string name="settings_customization">تخصيص</string>
<string name="multiuser_mode">نمط مستخدمين متعددين</string>
<string name="multiuser_mode">نمط المستخدم المزدوج</string>
<string name="settings_owner_only">مالك الجهاز فقط</string>
<string name="settings_owner_manage">المالك هو من يحدد</string>
<string name="settings_user_independent">مستقل </string>
<string name="settings_user_independent">مستقل</string>
<string name="owner_only_summary">للمالك فقط له صلاحيات الروت</string>
<string name="owner_manage_summary">فقط المالك من يرفض و يمنح صلاحيات الروت</string>
<string name="user_independent_summary">كل مستخدم له قواعد روت خاصة به</string>
<string name="mount_namespace_mode">نمط Mount Namespace</string>
<string name="settings_ns_global">نمط Namespace العام</string>
<string name="settings_ns_requester">نمط NameSpace المتوارث</string>
<string name="settings_ns_isolate">نمط NameSpace المعزول</string>
<string name="settings_ns_global">نمط Namespace عام</string>
<string name="settings_ns_requester">نمط NameSpace متوارث</string>
<string name="settings_ns_isolate">نمط NameSpace معزول</string>
<string name="global_summary">جميع الجلسات الروت تستخدم NameSpace العام</string>
<string name="requester_summary">جميع الجلسات الروت تستخدم NameSpace المتوارث</string>
<string name="isolate_summary">جميع الجلسات الروت تستخدم NameSpace المعزول</string>
<!--Notifications-->
<string name="update_channel">تحديثات Magisk</string>
<string name="update_channel">تحديثات ماجيسك</string>
<string name="progress_channel">إشعارات التقدم</string>
<string name="download_complete">اكتمل التنزيل</string>
<string name="download_file_error">فشل تنزيل الملف</string>
<string name="magisk_update_title">تحديث مـاجـيسك متوفر!</string>
<string name="magisk_update_title">تحديث ماجيسك متوفر!</string>
<!--Toasts, Dialogs-->
<string name="yes">نعم</string>
<string name="no">لا</string>
<string name="download">تنزيل</string>
<string name="reboot">إعادة التشغيل</string>
<string name="release_notes">معلومات الأصدار الجديد</string>
<string name="flashing">يتم الحرق...</string>
<string name="release_notes">معلومات الإصدار الجديد</string>
<string name="flashing">يتم التثبيت...</string>
<string name="done">تم!</string>
<string name="failure">فشل!</string>
<string name="open_link_failed_toast">لم يُعثر على تطبيق لفتح الرابط …</string>
<string name="complete_uninstall">إلغاء التثبيت بالكامل</string>
<string name="restore_img">استعادة الصور</string>
<string name="restore_img_msg">جار الأستعادة…</string>
<string name="restore_done">تم الأستعادة</string>
<string name="restore_fail">النسخة الاحتياطية الأصلية غير موجودة!</string>
<string name="setup_fail">فشل التضبيط</string>
<string name="env_fix_title"> الإعداد الأضافي مطلوب</string>
<string name="setup_msg">جار تضبيت البيئة</string>
<string name="unsupport_magisk_title">إصدار مـاجـيسك غير مدعوم</string>
<string name="restore_img_msg">جار الإستعادة…</string>
<string name="restore_done">تم الإستعادة</string>
<string name="restore_fail">النسخة الإحتياطية الأصلية غير موجودة!</string>
<string name="setup_fail">فشل الإعداد</string>
<string name="env_fix_title">الإعداد الإضافي مطلوب</string>
<string name="setup_msg">جار إعداد البيئة</string>
<string name="unsupport_magisk_title">إصدار ماجيسك غير مدعوم</string>
</resources>

View File

@@ -0,0 +1,250 @@
<resources>
<!--Author: Radoš Milićev (https://github.com/rammba)-->
<!--Sections-->
<string name="modules">Moduli</string>
<string name="superuser">Super-korisnik</string>
<string name="logs">Logovi</string>
<string name="settings">Podešavanja</string>
<string name="install">Instalacija</string>
<string name="section_home">Početno</string>
<string name="section_theme">Teme</string>
<string name="denylist">Lista zabrana</string>
<!--Home-->
<string name="no_connection">Nedostupna konekcija</string>
<string name="app_changelog">Promene u aplikaciji</string>
<string name="loading">Učitavanje…</string>
<string name="update">Ažuriranje</string>
<string name="not_available">N/A</string>
<string name="hide">Sakrij</string>
<string name="home_package">Paket</string>
<string name="home_app_title">Apl.</string>
<string name="home_notice_content">Preuzmite Magisk SAMO sa zvanične GitHub stranice. Fajlovi iz nepoznatih izvora mogu biti maliciozni!</string>
<string name="home_support_title">Podržite nas</string>
<string name="home_follow_title">Zapratite nas</string>
<string name="home_item_source">Izvor</string>
<string name="home_support_content">Magisk jeste i uvek će biti besplatan i open source. Međutim, možete pokazati da vam je stalo svojom donacijom.</string>
<string name="home_installed_version">Instalirano</string>
<string name="home_latest_version">Najnovije</string>
<string name="invalid_update_channel">Nevalidan kanal ažuriranja</string>
<string name="uninstall_magisk_title">Deinstaliraj Magisk</string>
<string name="uninstall_magisk_msg">Svi moduli će biti onemogućeni/uklonjeni!\nKoren će biti uklonjen!\nSvako neenkriptovano interno skladište će upotrebom Magisk-a biti ponovo enkriptovano!</string>
<!--Install-->
<string name="keep_force_encryption">Zadrži forsiranu enkripciju</string>
<string name="keep_dm_verity">Zadrži AVB 2.0/dm-verity</string>
<string name="recovery_mode">Režim oporavka</string>
<string name="install_options_title">Opcije</string>
<string name="install_method_title">Metod</string>
<string name="install_next">Naredno</string>
<string name="install_start">Počnimo</string>
<string name="manager_download_install">Pritisni da preuzmeš i instaliraš</string>
<string name="direct_install">Direktna instalacija (Preporučeno)</string>
<string name="install_inactive_slot">Instalacija na neaktivan slot (Nakon OTA)</string>
<string name="install_inactive_slot_msg">Vaš uređaj će biti FORSIRAN da se pokrene na trenutno neaktivnom slotu nakon ponovnog pokretanja!\nKoristite opciju samo kad se OTA završi.\nNastavi?</string>
<string name="setup_title">Dodatne postavke</string>
<string name="select_patch_file">Izaberite fajl</string>
<string name="patch_file_msg">Izaberite sliku (*.img) ili ODIN tarfile (*.tar) ili payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Ponovo pokretanje za 5 sekundi…</string>
<string name="flash_screen_title">Instalacija</string>
<!--Superuser-->
<string name="su_request_title">Super-korisnički zahtev</string>
<string name="touch_filtered_warning">Magisk ne može da verifikuje vaš odgovor, jer aplikacija prikriva super-korisnički zahtev.</string>
<string name="deny">Zabrani</string>
<string name="prompt">Zahtev</string>
<string name="restrict">Ograniči</string>
<string name="grant">Dozvoli</string>
<string name="su_warning">Pruža potpun pristup vašem uređaju.\nZabranite ako niste sigurni!</string>
<string name="forever">Zauvek</string>
<string name="once">Jednom</string>
<string name="tenmin">10 min</string>
<string name="twentymin">20 min</string>
<string name="thirtymin">30 min</string>
<string name="sixtymin">60 min</string>
<string name="su_allow_toast">%1$s je dobio prava na super-korisnika</string>
<string name="su_deny_toast">%1$s nije dobio prava na super-korisnika</string>
<string name="su_snack_grant">Super-korisnička prava od %1$s su pružena</string>
<string name="su_snack_deny">Super-korisnička prava od %1$s su odbijena</string>
<string name="su_snack_notif_on">Notifikacije od %1$s su omogućene</string>
<string name="su_snack_notif_off">Notifikacije od %1$s su onemogućene</string>
<string name="su_snack_log_on">Logovanje za %1$s je omogućeno</string>
<string name="su_snack_log_off">Logovanje za %1$s je onemogućeno</string>
<string name="su_revoke_title">Opozovi?</string>
<string name="su_revoke_msg">Potvrdi da opozoveš prava na super-korisnika od %1$s?</string>
<string name="toast">Toast</string>
<string name="none">Ništa</string>
<string name="superuser_toggle_notification">Notifikacije</string>
<string name="superuser_toggle_revoke">Opozovi</string>
<string name="superuser_policy_none">Nijedna aplikacija nije tražila permisije za super-korisnika još uvek.</string>
<!--Logs-->
<string name="log_data_none">Nemate logova. Pokušajte koristiti korenske aplikacije više.</string>
<string name="log_data_magisk_none">Magisk logovi su prazni, to je čudno.</string>
<string name="menuSaveLog">Sačuvaj log</string>
<string name="menuClearLog">Ukloni log</string>
<string name="logs_cleared">Log uspešno uklonjen</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Ciljani UID: %1$d</string>
<string name="target_pid">Ciljani PID: %s</string>
<string name="selinux_context">SELinux kontekst: %s</string>
<string name="supp_group">Dopunska grupa: %s</string>
<!--MagiskHide-->
<string name="show_system_app">Prikaži sistemske apl.</string>
<string name="show_os_app">Prikaži apl. OS-a</string>
<string name="hide_filter_hint">Filtriraj po imenu</string>
<string name="hide_search">Pretraga</string>
<!--Module-->
<string name="no_info_provided">(Bez informacija)</string>
<string name="reboot_userspace">Lako ponovo pokretanje</string>
<string name="reboot_recovery">Ponovo pokreni za oporavak</string>
<string name="reboot_bootloader">Ponovo pokreni za bootloader</string>
<string name="reboot_download">Ponovo pokreni za preuzimanje</string>
<string name="reboot_edl">Ponovo pokreni za EDL</string>
<string name="reboot_safe_mode">Siguran mod</string>
<string name="module_version_author">%1$s od %2$s</string>
<string name="module_state_remove">Ukloni</string>
<string name="module_action">Akcija</string>
<string name="module_state_restore">Povrati</string>
<string name="module_action_install_external">Instaliraj iz skladišta</string>
<string name="update_available">Ažuriranje dostupno</string>
<string name="suspend_text_riru">Modul je suspendovan jer je %1$s omogućeno</string>
<string name="suspend_text_zygisk">Modul je suspendovan jer %1$s nije omogućeno</string>
<string name="zygisk_module_unloaded">Zygisk modul nije učitan zbog nekompatibilnosti</string>
<string name="module_empty">Nijedan modul nije instaliran</string>
<string name="confirm_install">Instaliraj modul %1$s?</string>
<string name="confirm_install_title">Potvrda instalacije</string>
<!--Settings-->
<string name="settings_dark_mode_title">Tema</string>
<string name="settings_dark_mode_message">Izaberite temu koja vam najviše odgovara!</string>
<string name="settings_dark_mode_light">Uvek svetlo</string>
<string name="settings_dark_mode_system">Prati sistem</string>
<string name="settings_dark_mode_dark">Uvek tamno</string>
<string name="settings_download_path_title">Putanja za preuzimanje</string>
<string name="settings_download_path_message">Fajlovi će biti sačuvani na %1$s</string>
<string name="settings_hide_app_title">Sakrij Magisk apl.</string>
<string name="settings_hide_app_summary">Instaliraj proxy aplikaciju sa nasumičnim ID-jem paketa i prilagođenom labelom</string>
<string name="settings_restore_app_title">Povrati Magisk apl.</string>
<string name="settings_restore_app_summary">Otkrij apl. i povrati originalni APK</string>
<string name="language">Jezik</string>
<string name="system_default">(Podrazumevano sistemski)</string>
<string name="settings_check_update_title">Proveri ažuriranja</string>
<string name="settings_check_update_summary">Periodično proveri ažuriranja u pozadini</string>
<string name="settings_update_channel_title">Kanal ažuriranja</string>
<string name="settings_update_stable">Stabilno</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_debug">Debug</string>
<string name="settings_update_custom">Prilagođeno</string>
<string name="settings_update_custom_msg">Unesi prilagođeni URL kanala</string>
<string name="settings_zygisk_summary">Pokreni delove Magisk-a u Zygote daemon-u</string>
<string name="settings_denylist_title">Sprovedi listu zabrana</string>
<string name="settings_denylist_summary">Procesi na listi zabrana će povratiti sve Magisk izmene</string>
<string name="settings_denylist_config_title">Konfiguriši listu zabrana</string>
<string name="settings_denylist_config_summary">Izaberi procese koji će biti na listi zabrana</string>
<string name="settings_hosts_title">Bezsistemski domaćini (hosts)</string>
<string name="settings_hosts_summary">Podrška bezsistemskih domaćina za aplikacije blokiranja reklama</string>
<string name="settings_hosts_toast">Modul bezsistemskih domaćina dodat</string>
<string name="settings_app_name_hint">Novo ime</string>
<string name="settings_app_name_helper">Apl. će biti spakovana pod ovim imenom</string>
<string name="settings_app_name_error">Nevalidan format</string>
<string name="settings_su_app_adb">Aplikacije i ADB</string>
<string name="settings_su_app">Samo aplikacije</string>
<string name="settings_su_adb">Samo ADB</string>
<string name="settings_su_disable">Onemogućeno</string>
<string name="settings_su_request_10">10 sekundi</string>
<string name="settings_su_request_15">15 sekundi</string>
<string name="settings_su_request_20">20 sekundi</string>
<string name="settings_su_request_30">30 sekundi</string>
<string name="settings_su_request_45">45 sekundi</string>
<string name="settings_su_request_60">60 sekundi</string>
<string name="superuser_access">Pristup super-korisnika</string>
<string name="auto_response">Automatski odgovor</string>
<string name="request_timeout">Istek zahteva</string>
<string name="superuser_notification">Notifikacije super-korisnika</string>
<string name="settings_su_reauth_title">Ponovo odobri nakon ažuriranja</string>
<string name="settings_su_reauth_summary">Ponovo traži permisije super-korisnika nakon ažuriranja aplikacija</string>
<string name="settings_su_tapjack_title">Zaštita od tapjacking-a</string>
<string name="settings_su_tapjack_summary">Prompt dijalog super-korisnika neće reagovati dok je prikriven drugim prozorom ili overlay-em</string>
<string name="settings_su_auth_title">Autentifikacija korisnika</string>
<string name="settings_su_auth_summary">Traži autentifikaciju korisnika tokom zahteva super-korisnika</string>
<string name="settings_su_auth_insecure">Nijedan metod autentifikacije nije podešen na uređaju</string>
<string name="settings_su_restrict_title">Ograniči korenske sposobnosti</string>
<string name="settings_su_restrict_summary">Podrazumevano ograničava apl. super-korisnika. Upozorenje: ovo će većinu aplikacija skršiti. Ne omogućavaj, osim ako znaš šta radiš.</string>
<string name="settings_customization">Prilagođavanje</string>
<string name="setting_add_shortcut_summary">Dodaj lepu prečicu na početni ekran u slučaju da se ime i ikonica ne prepoznaju lako nakon skrivanja aplikacije</string>
<string name="settings_doh_title">DNS preko HTTPS-a</string>
<string name="settings_doh_description">Zaobilazno rešenje DNS trovanja u nekim nacijama</string>
<string name="settings_random_name_title">Nasumično ime na izlazu</string>
<string name="settings_random_name_description">Nasumično ime izlaznog fajla slika i tar fajlova radi sprečavanja detekcije</string>
<string name="multiuser_mode">Višekorisnički režim</string>
<string name="settings_owner_only">Samo vlasnik uređaja</string>
<string name="settings_owner_manage">Određeno od strane vlasnika</string>
<string name="settings_user_independent">Nezavisno od korisnika</string>
<string name="owner_only_summary">Samo vlasnik ima pristup korenu</string>
<string name="owner_manage_summary">Samo vlasnik može da pristupa korenu i da prima zahteve za njega</string>
<string name="user_independent_summary">Svaki korisnik ima svoja pravila korena</string>
<string name="mount_namespace_mode">Mount režim namespace-a</string>
<string name="settings_ns_global">Globalni namespace</string>
<string name="settings_ns_requester">Nasleđeni namespace</string>
<string name="settings_ns_isolate">Izolovani namespace</string>
<string name="global_summary">Sve korenske sesije koriste globalni mount namespace</string>
<string name="requester_summary">Korenske sesije će naslediti namespace od podnosioca zahteva</string>
<string name="isolate_summary">Svaka korenska sesija će imati svoj izolovani namespace</string>
<!--Notifications-->
<string name="update_channel">Ažuriranja Magisk-a</string>
<string name="progress_channel">Notifikacije o progresu</string>
<string name="updated_channel">Ažuriranje završeno</string>
<string name="download_complete">Preuzimanje završeno</string>
<string name="download_file_error">Greška pri preuzimanju fajla</string>
<string name="magisk_update_title">Ažuriranje Magisk-a dostupno!</string>
<string name="updated_title">Magisk je ažuriran</string>
<string name="updated_text">Klikni da otvoriš aplikaciju</string>
<!--Toasts, Dialogs-->
<string name="yes">Da</string>
<string name="no">Ne</string>
<string name="repo_install_title">Instaliraj %1$s %2$s(%3$d)</string>
<string name="download">Preuzmi</string>
<string name="reboot">Ponovo pokreni</string>
<string name="close">Zatvori</string>
<string name="release_notes">Release notes</string>
<string name="flashing">Flešovanje…</string>
<string name="running">Pokretanje…</string>
<string name="done">Završeno!</string>
<string name="done_action">Pokretanje akcije %1$s završeno</string>
<string name="failure">Neuspešno!</string>
<string name="hide_app_title">Skrivanje Magisk aplikacije…</string>
<string name="open_link_failed_toast">Nije pronađena aplikacija za otvaranje linka</string>
<string name="complete_uninstall">Kompletna deinstalacija</string>
<string name="restore_img">Povrati slike</string>
<string name="restore_img_msg">Povratak…</string>
<string name="restore_done">Povratak uspešan!</string>
<string name="restore_fail">Fabrički bekap ne postoji!</string>
<string name="setup_fail">Neuspešna postavka</string>
<string name="env_fix_title">Potrebno dodatno podešavanje</string>
<string name="env_fix_msg">Vaš uređaj zahteva dodatno podešavanje da bi Magisk radio kako treba. Da li želite nastaviti i pokrenuti ponovo?</string>
<string name="env_full_fix_msg">Vaš uređaj zahteva ponovno flešovanje da bi Magisk radio kako treba. Reinstalirajte Magisk kroz aplikaciju, režim oporavka ne može dobiti tačne informacije o uređaju.</string>
<string name="setup_msg">Pokretanje podešavanja okruženja…</string>
<string name="unsupport_magisk_title">Nepodržana verzija Magisk-a</string>
<string name="unsupport_magisk_msg">Ova verzija aplikacije ne podržava Magisk verzije manje od %1$s.\n\nAplikacija će se ponašati kao da Magisk nije instaliran. Molimo ažurirajte Magisk što pre.</string>
<string name="unsupport_general_title">Nenormalno stanje</string>
<string name="unsupport_system_app_msg">Pokretanje aplikacije kao sistemske nije podržano. Molimo postavite aplikaciju da bude korisnička.</string>
<string name="unsupport_other_su_msg">Detektovan \"su\" binary koji nije Magisk-ov. Molimo uklonite konkurentno korensko rešenje i/ili reinstalirajte Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk je instaliran na eksterno skladište. Molimo pomerite apl. u interno skladište.</string>
<string name="unsupport_nonroot_stub_msg">Skrivena Magisk aplikacija ne može nastaviti sa radom jer je koren izgubljen. Molimo povratite originalni APK.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Dozvolite permisiju za skladište da biste omogućili ovu funkcionalnost</string>
<string name="post_notifications_denied">Dozvolite permisiju za notifikacije da biste omogućili ovu funkcionalnost</string>
<string name="install_unknown_denied">Dozvolite \"instaliranje nepoznatih aplikacija\" da biste omogućili ovu funkcionalnost</string>
<string name="add_shortcut_title">Dodaj prečicu na početni ekran</string>
<string name="add_shortcut_msg">Nakon skrivanja aplikacije, njeno ime i ikonicu ćete teško prepoznati. Želite li dodati lepu prečicu na početni ekran?</string>
<string name="app_not_found">Nije pronađena aplikacija za ovu akciju</string>
<string name="reboot_apply_change">Ponovo pokreni da primeniš izmene</string>
<string name="restore_app_confirmation">Ovo će vratiti skrivenu aplikaciju na originalnu. Da li stvarno to želite?</string>
</resources>

View File

@@ -8,6 +8,7 @@
<string name="install">نصب</string>
<string name="section_home">خانه</string>
<string name="section_theme">تم ها</string>
<string name="denylist">لیست منع</string>
<!--Home-->
<string name="no_connection">هیچ اتصالی وجود ندارد</string>
@@ -17,7 +18,9 @@
<string name="not_available">غیر/قابل دسترسی</string>
<string name="hide">پنهان کردن</string>
<string name="home_package">پکیج</string>
<string name="home_app_title">برنامه</string>
<string name="home_notice_content">Magisk را فقط از صفحه رسمی GitHub دانلود کنید. فایل‌ها از منابع ناشناس می‌توانند مخرب باشند!</string>
<string name="home_follow_title">ما را دنبال کنید</string>
<string name="home_support_title">حمایت ما</string>
<string name="home_item_source">منبع</string>
<string name="home_support_content">این برنامه (Magisk) رایگان و متن باز است و همیشه خواهد ماند. اگرچه شما میتواند با دونیت خود نشان دهد که به ما اهمیت می دهید.</string>
@@ -47,8 +50,10 @@
<!--Superuser-->
<string name="su_request_title">درخواست کاربر روت</string>
<string name="touch_filtered_warning">به دلیل اینکه یک برنامه در حال پوشاندن درخواست Superuser است، Magisk نمی‌تواند پاسخ شما را تأیید کند.</string>
<string name="deny">رد کردن</string>
<string name="prompt">درخواست کردن</string>
<string name="restrict">محدود کردن</string>
<string name="grant">اجازه دادن</string>
<string name="su_warning">دسترسی کامل به دستگاه شما را اعطا می کند. \nاگر مطمئن نیستید رد کنید!</string>
<string name="forever">همیشه</string>
@@ -67,37 +72,50 @@
<string name="su_snack_log_off">ورود به سیستم از %1$s غییر فعال است</string>
<string name="su_revoke_title">باطل بشه؟</string>
<string name="su_revoke_msg">تایید کنید که %1$s باطل بشه؟</string>
<string name="toast">پیام کوتاه</string>
<string name="none">هیچ کدام</string>
<string name="superuser_toggle_notification">اعلان ها</string>
<string name="superuser_toggle_revoke">ابطال</string>
<string name="superuser_policy_none">هنوز هیچ برنامه ای مجوز روت درخواست نکرده است.</string>
<!--Logs-->
<string name="log_data_none">شما هیچ لاگی ندارید, سعی کنید برنامه های که به روت دسترسی میگیرند را استفاده کنید.</string>
<string name="log_data_magisk_none">لاگ های مربوط به Magisk خالی است. پنا بر خدا.</string>
<string name="log_data_magisk_none">لاگ های مربوط به Magisk خالی است.</string>
<string name="menuSaveLog">ذخیره کردن لاگ</string>
<string name="menuClearLog">پاک کردن لاگ</string>
<string name="logs_cleared">لاگ با موفقیت پاک شد.</string>
<!--SafetyNet-->
<string name="pid">شناسه پردازش: %1$d</string>
<string name="target_uid">شناسه کاربر هدف: %1$d</string>
<string name="target_pid">شناسه پردازش هدف: %s</string>
<string name="selinux_context">متن SELinux: %s</string>
<string name="supp_group">گروه تکمیلی: %s</string>
<!-- MagiskHide -->
<string name="show_system_app">نشان دادن برنامه های سیستمی</string>
<string name="show_os_app">نمایش برنامه‌های سیستم عامل</string>
<string name="hide_filter_hint">فیلتر کردن با نام</string>
<string name="hide_search">سرچ کردن</string>
<!--Module -->
<string name="no_info_provided">(هیچ اطلاعاتی ارائه نشده است)</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="reboot_safe_mode">راه اندازی مججد برای رفتن به حالت امن</string>
<string name="module_version_author">%1$s با %2$s</string>
<string name="module_state_remove">حذف کردن</string>
<string name="module_state_restore">بازگرداندن</string>
<string name="module_action_install_external">نصب از حافظه</string>
<string name="update_available">بروزرسانی در دسترس است</string>
<string name="suspend_text_riru">ماژول به دلیل فعال بودن %1$s متوقف شد</string>
<string name="suspend_text_zygisk">ماژول به دلیل غیرفعال بودن %1$s متوقف شد</string>
<string name="zygisk_module_unloaded">ماژول Zygisk به دلیل ناسازگاری بارگذاری نشد</string>
<string name="module_empty">هیچ ماژولی نصب نشده است</string>
<string name="confirm_install">نصب ماژول %1$s؟</string>
<string name="confirm_install_title">تأیید نصب</string>
<!--Settings -->
<string name="settings_dark_mode_title">حالت تم</string>
@@ -107,6 +125,10 @@
<string name="settings_dark_mode_dark">همیشه تاریک</string>
<string name="settings_download_path_title">مسیر دانلود</string>
<string name="settings_download_path_message">فایل ها در %1$s ذخیره خواهند شد.</string>
<string name="settings_hide_app_title">مخفی کردن برنامه Magisk</string>
<string name="settings_hide_app_summary">نصب یک برنامه پروکسی با شناسه بسته تصادفی و برچسب سفارشی</string>
<string name="settings_restore_app_title">بازگردانی برنامه Magisk</string>
<string name="settings_restore_app_summary">آشکار کردن برنامه و بازگرداندن APK اصلی</string>
<string name="language">زبان</string>
<string name="system_default">(پیش فرض سیستم)</string>
<string name="settings_check_update_title">چک کردن بروز رسانی ها</string>
@@ -114,8 +136,14 @@
<string name="settings_update_channel_title">کانال بروزرسانی</string>
<string name="settings_update_stable">پایدار</string>
<string name="settings_update_beta">آزمایشی</string>
<string name="settings_update_debug">اشکال‌زدایی</string>
<string name="settings_update_custom">شخصی سازی شده</string>
<string name="settings_update_custom_msg">اضافه کردن یک URL سفارشی</string>
<string name="settings_zygisk_summary">اجرای بخش‌هایی از Magisk در سرویس Zygote</string>
<string name="settings_denylist_title">اعمال لیست منع</string>
<string name="settings_denylist_summary">فرآیندهای موجود در لیست منع تمام تغییرات Magisk را از دست خواهند داد</string>
<string name="settings_denylist_config_title">پیکربندی لیست منع</string>
<string name="settings_denylist_config_summary">انتخاب فرآیندهایی که باید در لیست منع قرار گیرند</string>
<string name="settings_hosts_title">نصب بدون حذف یا تغییر در فایل ها</string>
<string name="settings_hosts_summary">نصب بدون حذف یا تغییر در فایل ها رای ساپورت از برنامه های Adblock</string>
<string name="settings_hosts_toast">ماژول نصب بدون حذف یا تغییر در فایل ها اضافه شد</string>
@@ -138,9 +166,19 @@
<string name="superuser_notification">اعلان روت</string>
<string name="settings_su_reauth_title">احراز هویت دوباره پس از بروز رسانی</string>
<string name="settings_su_reauth_summary">تأیید کردندوباره مجوزهای روت پس از ارتقاء برنامه</string>
<string name="settings_su_tapjack_title">محافظت در برابر Tapjacking</string>
<string name="settings_su_tapjack_summary">پنجره درخواست Superuser زمانی که توسط پنجره یا لایه دیگری پوشانده شود، به ورودی پاسخ نخواهد داد</string>
<string name="settings_su_auth_title">احراز هویت کاربر</string>
<string name="settings_su_auth_summary">درخواست احراز هویت کاربر هنگام درخواست Superuser</string>
<string name="settings_su_auth_insecure">هیچ روش احراز هویتی روی دستگاه پیکربندی نشده است</string>
<string name="settings_su_restrict_title">محدود کردن دسترسی روت</string>
<string name="settings_su_restrict_summary">به طور پیش‌فرض برنامه‌های Superuser جدید را محدود می‌کند. هشدار: این کار بیشتر برنامه‌ها را از کار می‌اندازد. فقط اگر دقیقاً می‌دانید چه می‌کنید آن را فعال کنید.</string>
<string name="settings_customization">سفارشی سازی</string>
<string name="setting_add_shortcut_summary">اضافه کردن یک میانبر زیبا را در صفحه اصلی در صورت شناسایی نام و نماد پس از پنهان کردن برنامه</string>
<string name="settings_doh_title">DNS روی HTTPS</string>
<string name="settings_doh_description">دور زدن مسمومیت DNS در برخی کشورها</string>
<string name="settings_random_name_title">تغییر تصادفی نام خروجی</string>
<string name="settings_random_name_description">تغییر تصادفی نام فایل خروجی تصاویر و فایل‌های tar پچ‌شده برای جلوگیری از شناسایی</string>
<string name="multiuser_mode">حالت چند کاربره</string>
<string name="settings_owner_only">فقط صاحب دستگاه</string>
<string name="settings_owner_manage">صاحب دستگاه مدیریت شود</string>
@@ -148,7 +186,6 @@
<string name="owner_only_summary">فقط مالک دسترسی روت دارد</string>
<string name="owner_manage_summary">فقط مالک می تواند دسترسی روت را مدیریت کرده و درخواست های پرامپت را دریافت کند</string>
<string name="user_independent_summary">هر کاربر قوانین روت جداگانه خود را دارد</string>
<string name="mount_namespace_mode">نصب کردن Namespace Mode</string>
<string name="settings_ns_global">سراسری Namespace</string>
<string name="settings_ns_requester">وراثتی Namespace</string>
@@ -160,19 +197,27 @@
<!--Notifications-->
<string name="update_channel">Magisk بروزرسانی های</string>
<string name="progress_channel">اعلان پیشرفت</string>
<string name="updated_channel">به‌روزرسانی کامل شد</string>
<string name="download_complete">دانلود کامل شد</string>
<string name="download_file_error">خطا در دانلود فایل</string>
<string name="magisk_update_title">بروزرسانی Magisk در دسترس است!</string>
<string name="updated_title">Magisk به‌روزرسانی شد</string>
<string name="updated_text">برای باز کردن برنامه لمس کنید</string>
<!--Toasts, Dialogs-->
<string name="yes">بله</string>
<string name="no">نه</string>
<string name="download">انلود کردن</string>
<string name="repo_install_title">نصب %1$s %2$s(%3$d)</string>
<string name="download">دانلود کردن</string>
<string name="reboot">راه اندازی مجدد</string>
<string name="close">بستن</string>
<string name="release_notes">نکته های نسخه</string>
<string name="flashing">ر حال فلش کردن…</string>
<string name="running">در حال اجرا…</string>
<string name="done">تمام!</string>
<string name="done_action">انجام عملیات %1$s به پایان رسید</string>
<string name="failure">ناموفق</string>
<string name="hide_app_title">در حال مخفی کردن برنامه Magisk…</string>
<string name="open_link_failed_toast">هیچ برنامه ای برای باز کردن لینک یافت نشد</string>
<string name="complete_uninstall">کامل کردن حذف</string>
<string name="restore_img">بازیابی تصاویر</string>
@@ -181,9 +226,24 @@
<string name="restore_fail">نسخه پشتیبان استک موجود نیست!</string>
<string name="setup_fail">نصب انجام نشد</string>
<string name="env_fix_title">به تنظیمات اضافی نیاز دارد</string>
<string name="env_fix_msg">دستگاه شما به پیکربندی اضافی نیاز دارد تا Magisk به درستی کار کند. آیا می‌خواهید ادامه دهید و راه‌اندازی مجدد انجام شود؟</string>
<string name="env_full_fix_msg">دستگاه شما نیاز به نصب دوباره Magisk دارد تا به درستی کار کند. لطفاً Magisk را از داخل برنامه دوباره نصب کنید، حالت Recovery نمی‌تواند اطلاعات دستگاه را به درستی بگیرد.</string>
<string name="setup_msg">راه اندازی محیط نصب…</string>
<string name="unsupport_magisk_title">نسخه پشتیبانی نشده Magisk</string>
<string name="unsupport_magisk_msg">این نسخه از برنامه از نسخه‌های Magisk پایین‌تر از %1$s پشتیبانی نمی‌کند.\n\nبرنامه طوری رفتار می‌کند که انگار Magisk نصب نشده است. لطفاً هرچه سریع‌تر Magisk را به‌روزرسانی کنید.</string>
<string name="unsupport_general_title">وضعیت غیرعادی</string>
<string name="unsupport_system_app_msg">اجرای این برنامه به عنوان برنامه سیستمی پشتیبانی نمی‌شود. لطفاً آن را به برنامه کاربری بازگردانید.</string>
<string name="unsupport_other_su_msg">یک باینری "su" غیر از Magisk شناسایی شد. لطفاً هر راهکار روت دیگری را حذف کنید و/یا Magisk را دوباره نصب کنید.</string>
<string name="unsupport_external_storage_msg">Magisk روی حافظه خارجی نصب شده است. لطفاً برنامه را به حافظه داخلی منتقل کنید.</string>
<string name="unsupport_nonroot_stub_msg">برنامه مخفی Magisk نمی‌تواند ادامه دهد زیرا دسترسی روت از بین رفته است. لطفاً APK اصلی را بازگردانید.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">برای فعال کردن این قابلیت ، اجازه دسترسی به حافظه بدهید</string>
<string name="post_notifications_denied">برای فعال‌سازی این قابلیت، مجوز اعلان‌ها را بدهید</string>
<string name="install_unknown_denied">برای فعال‌سازی این قابلیت، «نصب برنامه‌های ناشناخته» را مجاز کنید</string>
<string name="add_shortcut_title">اضافه کردن میانبر را به صفحه</string>
<string name="add_shortcut_msg">بعد از مخفی کردن این برنامه، ممکن است نام و آیکون آن سخت قابل شناسایی شود. آیا می‌خواهید یک میانبر زیبا به صفحه اصلی اضافه کنید؟</string>
<string name="app_not_found">هیچ برنامه‌ای برای انجام این عملیات یافت نشد</string>
<string name="reboot_apply_change">برای اعمال تغییرات، دستگاه را دوباره راه‌اندازی کنید</string>
<string name="restore_app_confirmation">این کار برنامه مخفی شده را به نسخه اصلی بازمی‌گرداند. آیا واقعاً می‌خواهید این کار را انجام دهید؟</string>
</resources>

View File

@@ -0,0 +1,249 @@
<resources>
<!--Sections-->
<string name="modules">Modules</string>
<string name="superuser">Superuser</string>
<string name="logs">Logs</string>
<string name="settings">Settings</string>
<string name="install">Install</string>
<string name="section_home">Home</string>
<string name="section_theme">Themes</string>
<string name="denylist">DenyList</string>
<!--Home-->
<string name="no_connection">Net nahi chal rha hai</string>
<string name="app_changelog">Kya naga hai</string>
<string name="loading">Loading ho rha hai…</string>
<string name="update">Update</string>
<string name="not_available">Available nahi hai</string>
<string name="hide">Chhupao</string>
<string name="home_package">Package</string>
<string name="home_app_title">App</string>
<string name="home_notice_content">Hamesha Magisk ko uske official github release source se download karein. Unofficial source ki file khatarnak ho sakti hai.</string>
<string name="home_support_title">Humein Support karo</string>
<string name="home_follow_title">Humein Karo</string>
<string name="home_item_source">Source</string>
<string name="home_support_content">Magisk hamesha free aur open source rahega. Agar aap support karna chahte ho, toh donation de sakte ho.</string>
<string name="home_installed_version">Jo version install hai</string>
<string name="home_latest_version">Latest</string>
<string name="invalid_update_channel">Galat update channel</string>
<string name="uninstall_magisk_title">Magisk uninstall karo</string>
<string name="uninstall_magisk_msg">Saare modules disable ya remove ho jayenge!\nRoot khatam ho jayega!\nAgar Magisk ne storage ko decrypt kiya tha toh wo phir se encrypt ho jayega!</string>
<!--Install-->
<string name="keep_force_encryption">Force encryption ko preserve karo</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity ko preserve karo</string>
<string name="recovery_mode">Recovery mode</string>
<string name="install_options_title">Options</string>
<string name="install_method_title">Method</string>
<string name="install_next">Aage badho</string>
<string name="install_start">Chalo shuru karein</string>
<string name="manager_download_install">Download aur install karne ke liye dabao</string>
<string name="direct_install">Direct install (Recommended)</string>
<string name="install_inactive_slot">Inactive slot par install karo (OTA ke baad)</string>
<string name="install_inactive_slot_msg">Reboot ke baad device ko inactive slot se boot karna padega!\nSirf tab use karo jab OTA complete ho chuka ho.\nAage badhna hai?</string>
<string name="setup_title">Extra setup</string>
<string name="select_patch_file">File select karke patch karo</string>
<string name="patch_file_msg">Raw image (*.img), ODIN tar file (*.tar), ya payload.bin (*.bin) select karo</string>
<string name="reboot_delay_toast">Phone 5 second mein reboot hoga…</string>
<string name="flash_screen_title">Installation ho rahi hai</string>
<!--Superuser-->
<string name="su_request_title">ROOT access maang rha hai</string>
<string name="touch_filtered_warning">Ek app Superuser request ko cover kar raha hai, isliye Magisk aapka response verify nahi kar sakta.</string>
<string name="deny">Nahi</string>
<string name="prompt">Poocho</string>
<string name="restrict">Restrict</string>
<string name="grant">Haan Theek hai</string>
<string name="su_warning">Yeh full access dega device ko.\nAgar sure nahi ho toh deny kar do!</string>
<string name="forever">Hamesha ke liye</string>
<string name="once">Ek baar ke liye</string>
<string name="tenmin">10 mins</string>
<string name="twentymin">20 mins</string>
<string name="thirtymin">30 mins</string>
<string name="sixtymin">60 mins</string>
<string name="su_allow_toast">%1$s ko ROOT access de diya gaya</string>
<string name="su_deny_toast">%1$s ko ROOT access nahi diya gaya</string>
<string name="su_snack_grant">%1$s ko ROOT access mila</string>
<string name="su_snack_deny">%1$s ka ROOT access deny hua</string>
<string name="su_snack_notif_on">%1$s ke notifications ON hain</string>
<string name="su_snack_notif_off">%1$s ke notifications OFF hain</string>
<string name="su_snack_log_on">%1$s ka logging ON hai</string>
<string name="su_snack_log_off">%1$s ka logging OFF hai</string>
<string name="su_revoke_title">Access wapas lena hai?</string>
<string name="su_revoke_msg">Kya aap confirm karte ho ki %1$s ka ROOT access hata diya jaye?</string>
<string name="toast">Toast</string>
<string name="none">Kuch nahi</string>
<string name="superuser_toggle_notification">Notifications</string>
<string name="superuser_toggle_revoke">Wapas lelo</string>
<string name="superuser_policy_none">Ab tak kisi bhi app ne ROOT access nahi manga hai</string>
<!--Logs-->
<string name="log_data_none">Koi logs nahi mile. Shayad tumhe root apps ka zyada use krna chahiye.</string>
<string name="log_data_magisk_none">Ajeeb baat hai, Yaha toh logs hain hi nahi.</string>
<string name="menuSaveLog">Log save karo</string>
<string name="menuClearLog">Log clear karo</string>
<string name="logs_cleared">Logs clear ho gaye</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Target UID: %1$d</string>
<string name="target_pid">Target PID: %s</string>
<string name="selinux_context">SELinux context: %s</string>
<string name="supp_group">Supplementary group: %s</string>
<!--MagiskHide-->
<string name="show_system_app">System apps dikhao</string>
<string name="show_os_app">OS apps dikhao</string>
<string name="hide_filter_hint">Naam ke hisaab se filter karo</string>
<string name="hide_search">Search karo</string>
<!--Module-->
<string name="no_info_provided">(Koi info nahi di gayi)</string>
<string name="reboot_userspace">Soft reboot</string>
<string name="reboot_recovery">Recovery mode mein reboot karo</string>
<string name="reboot_bootloader">Bootloader mode mein reboot karo</string>
<string name="reboot_download">Download mode mein reboot karo</string>
<string name="reboot_edl">EDL mode mein reboot karo</string>
<string name="reboot_safe_mode">Safe mode</string>
<string name="module_version_author">%1$s ko %2$s ne banaya hai</string>
<string name="module_state_remove">Delete karo</string>
<string name="module_action">Action</string>
<string name="module_state_restore">Wapas laao</string>
<string name="module_action_install_external">Storage se install karo</string>
<string name="update_available">Naya update available hai</string>
<string name="suspend_text_riru">Module suspend kiya gaya kyunki %1$s enabled hai</string>
<string name="suspend_text_zygisk">Bhai %1$s ON kr tabb ye module chalega</string>
<string name="zygisk_module_unloaded">Zygisk module compatible nahi tha, isliye load nahi hua</string>
<string name="module_empty">Koi module install nahi hai</string>
<string name="confirm_install">>%1$s module install karna hai?</string>
<string name="confirm_install_title">Ek baar firse soch lo</string>
<!--Settings-->
<string name="settings_dark_mode_title">Theme mode</string>
<string name="settings_dark_mode_message">Apni hisaab se mode choose karo!</string>
<string name="settings_dark_mode_light">Hamesha light theme</string>
<string name="settings_dark_mode_system">System ke saath follow karo</string>
<string name="settings_dark_mode_dark">Hamesha dark theme</string>
<string name="settings_download_path_title">Download path</string>
<string name="settings_download_path_message">Files yahan save hongi: %1$s</string>
<string name="settings_hide_app_title">Magisk app ko hide karo</string>
<string name="settings_hide_app_summary">Magisk app ka name aur package ID change kro</string>
<string name="settings_restore_app_title">Magisk app ko unhide karo</string>
<string name="settings_restore_app_summary">App ko unhide karo aur original APK wapas lao</string>
<string name="language">Language</string>
<string name="system_default">(System ki default)</string>
<string name="settings_check_update_title">Updates check karo</string>
<string name="settings_check_update_summary">Background mein updates auto check honge</string>
<string name="settings_update_channel_title">Update channel</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_debug">Debug</string>
<string name="settings_update_custom">Custom</string>
<string name="settings_update_custom_msg">Apna custom channel URL daaloL</string>
<string name="settings_zygisk_summary">Magisk ke kuch parts ko Zygote daemon mein run karo</string>
<string name="settings_denylist_title">DenyList enforce karo</string>
<string name="settings_denylist_summary">DenyList mein jo processes hain, unpe Magisk ka effect hata diya jayega</string>
<string name="settings_denylist_config_title">DenyList set karo</string>
<string name="settings_denylist_config_summary">Kaunse process DenyList mein daalne hain, select karo</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Ad-blocking apps ke liye systemless hosts support</string>
<string name="settings_hosts_toast">Systemless hosts module add kar diya gaya</string>
<string name="settings_app_name_hint">Naya naam</string>
<string name="settings_app_name_helper">App is naam ke saath repack hoga</string>
<string name="settings_app_name_error">Naam ka format galat hai</string>
<string name="settings_su_app_adb">Apps aur ADB</string>
<string name="settings_su_app">Sirf apps</string>
<string name="settings_su_adb">Sirf ADB</string>
<string name="settings_su_disable">Disable kiya gaya</string>
<string name="settings_su_request_10">10 seconds</string>
<string name="settings_su_request_15">15 seconds</string>
<string name="settings_su_request_20">20 seconds</string>
<string name="settings_su_request_30">30 seconds</string>
<string name="settings_su_request_45">45 seconds</string>
<string name="settings_su_request_60">60 seconds</string>
<string name="superuser_access">ROOT access</string>
<string name="auto_response">Automatic response</string>
<string name="request_timeout">Request timeout</string>
<string name="superuser_notification">ROOT notification</string>
<string name="settings_su_reauth_title">Upgrade ke baad dobara permission puchho</string>
<string name="settings_su_reauth_summary">App upgrade hone ke baad Superuser permission firse maangna</string>
<string name="settings_su_tapjack_title">Tapjacking se protection</string>
<string name="settings_su_tapjack_summary">Agar Superuser prompt kisi aur window ya overlay ke neeche chhup gaya ho, toh uspar tap kaam nahi karega</string>
<string name="settings_su_auth_title">User authentication</string>
<string name="settings_su_auth_summary">Superuser request ke time user se authentication maango</string>
<string name="settings_su_auth_insecure">Device mein koi bhi authentication method set nahi hai</string>
<string name="settings_su_restrict_title">Root access ko limit karo</string>
<string name="settings_su_restrict_summary">Nayeapps ko ROOT access maangne se block karega. Warning: Isse zyada tarr apps kaam karna band kar denge. Sirf tab enable karo jab aapko pata ho aap kya kar rahe ho.</string>
<string name="settings_customization">Customization</string>
<string name="setting_add_shortcut_summary">Agar app hide karne ke baad uska naam ya icon samajhne mein dikkat ho rahi ho, toh home screen pe ek shortcut add kar lo</string>
<string name="settings_doh_title">DNS over HTTPS</string>
<string name="settings_doh_description">DNS poisoning se bachne ke liye (kuch countries mein zaroori padti hai)</string>
<string name="settings_random_name_title">Output file ka naam random karo</string>
<string name="settings_random_name_description">Patched images aur tar files ka naam random bana ke detection se bachao</string>
<string name="multiuser_mode">Multiuser mode</string>
<string name="settings_owner_only">Sirf device owner</string>
<string name="settings_owner_manage">Device owner manage karega</string>
<string name="settings_user_independent">Har user ke liye alag</string>
<string name="owner_only_summary">Sirf device owner ko root access milega</string>
<string name="owner_manage_summary">Sirf owner root access manage kar sakta hai aur requests receive karega</string>
<string name="user_independent_summary">Har user ke liye alag root rules honge</string>
<string name="mount_namespace_mode">Mount namespace mode</string>
<string name="settings_ns_global">Global namespace</string>
<string name="settings_ns_requester">Inherit namespace</string>
<string name="settings_ns_isolate">Isolated namespace</string>
<string name="global_summary">Sabhi root sessions ek hi global mount namespace use karenge</string>
<string name="requester_summary">Root session apne requester ka namespace inherit karega</string>
<string name="isolate_summary">Har root session ka apna alag isolated namespace hoga</string>
<!--Notifications-->
<string name="update_channel">Magisk updates</string>
<string name="progress_channel">Progress notifications</string>
<string name="updated_channel">Update ho gaya</string>
<string name="download_complete">Download ho gaya</string>
<string name="download_file_error">File download karne mein error aaya</string>
<string name="magisk_update_title">Magisk ka naya update available hai!</string>
<string name="updated_title">Magisk update ho gaya</string>
<string name="updated_text">App open karne ke liye tap karo</string>
<!--Toasts, Dialogs-->
<string name="yes">Haan</string>
<string name="no">Nahi</string>
<string name="repo_install_title">%1$s %2$s(%3$d) Install karo</string>
<string name="download">Download karo</string>
<string name="reboot">Reboot karo</string>
<string name="close">Close karo</string>
<string name="release_notes">Release notes</string>
<string name="flashing">Flash ho raha hai…</string>
<string name="running">Chal raha hai…</string>
<string name="done">Ho gaya!</string>
<string name="done_action">%1$s ka action complete ho gaya</string>
<string name="failure">Fail ho gaya!</string>
<string name="hide_app_title">Magisk app ko chhupa rahe hain…</string>
<string name="open_link_failed_toast">Link kholne ke liye koi app nahi mila</string>
<string name="complete_uninstall">Sab kuch uninstall karo</string>
<string name="restore_img">Images restore karo</string>
<string name="restore_img_msg">Restore kiya ja raha hai…</string>
<string name="restore_done">Restore complete ho gaya!</string>
<string name="restore_fail">Stock backup available nahi hai!</string>
<string name="setup_fail">Setup fail ho gaya</string>
<string name="env_fix_title">Iske liye thoda extra setup chahiye</string>
<string name="env_fix_msg">Magisk ko sahi se chalane ke liye thoda aur setup karna padega. Kya aap proceed karke device reboot karna chahte ho?</string>
<string name="env_full_fix_msg">Magisk ko properly chalane ke liye aapko usse dubara flash karna padega. App ke andar se Magisk reinstall karo, kyunki Recovery mode sahi device info nahi de pata.</string>
<string name="setup_msg">Environment setup chal raha hai…</string>
<string name="unsupport_magisk_title">Magisk version supported nahi hain</string>
<string name="unsupport_magisk_msg">Is app version ko %1$s se purani Magisk versions support nahi karti.\n\nApp aise behave karega jaise Magisk install hi nahi hai. Jaldi se Magisk ko update karo.</string>
<string name="unsupport_general_title">System thoda alag behave kar raha hai</string>
<string name="unsupport_system_app_msg">App ko system app bana ke chalana supported nahi hai. Please app ko wapas user app bana do.</string>
<string name="unsupport_other_su_msg">Pehle doosri root method hatao ya Magisk dobara install karo.</string>
<string name="unsupport_external_storage_msg">Magisk external storage pe installed hai. App ko internal storage mein move karo.</string>
<string name="unsupport_nonroot_stub_msg">Hidden Magisk app ab kaam nahi karega kyunki root chala gaya hai. Please original APK restore karo.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Iss feature ko enable karne ke liye storage permission allow karo</string>
<string name="post_notifications_denied">Is feature ke liye notifications permission allow karo</string>
<string name="install_unknown_denied">\"Install unknown apps\" ki permission allow karo taaki ye feature kaam kar sakey</string>
<string name="add_shortcut_title">Shortcut home screen pe add karo</string>
<string name="add_shortcut_msg">App ko hide karne ke baad agar uska icon ya naam pehchanna mushkil ho, toh ek shortcut home screen pe add kar lein?</string>
<string name="app_not_found">Is action ko handle karne ke liye koi app nahi mila</string>
<string name="reboot_apply_change">Changes apply karne ke liye reboot krna zaroori hai</string>
<string name="restore_app_confirmation">Ye action hidden app ko original version mein wapas laayega. Kya aap sach mein ye karna chahte ho?</string>
</resources>

View File

@@ -3,7 +3,7 @@
<!--Sections-->
<string name="modules">מודולים</string>
<string name="superuser">משתמש על</string>
<string name="logs">יומני רישום</string>
<string name="logs">Log</string>
<string name="settings">הגדרות</string>
<string name="install">התקנה</string>
<string name="section_home">בית</string>
@@ -12,10 +12,10 @@
<!--Home-->
<string name="no_connection">אין חיבור זמין</string>
<string name="app_changelog">יומן שינויים</string>
<string name="app_changelog">רשימת שינויים</string>
<string name="loading">טוען…</string>
<string name="update">עדכון</string>
<string name="not_available">ל</string>
<string name="not_available">לא זמין</string>
<string name="hide">הסתרה</string>
<string name="home_package">חבילה</string>
<string name="home_app_title">יישום</string>
@@ -23,28 +23,28 @@
<string name="home_support_title">תמיכה בנו</string>
<string name="home_follow_title">עקבו אחרינו</string>
<string name="home_item_source">מקור</string>
<string name="home_support_content">Magisk היה ותמיד יהיה בעל קוד מקור פתוח. עם זאת באפשרותך להראות לנו שאכפת לך על ידי שליחת תרומה קטנה.</string>
<string name="home_support_content">Magisk היה ותמיד יהיה בקוד פתוח. עם זאת באפשרותך להראות לנו שאכפת לך על ידי שליחת תרומה קטנה.</string>
<string name="home_installed_version">מותקנת</string>
<string name="home_latest_version">אחרונה</string>
<string name="invalid_update_channel">ערוץ עדכון לא חוקי</string>
<string name="uninstall_magisk_title">הסרת Magisk</string>
<string name="uninstall_magisk_msg">כל המודולים יושבתו/יוסרו!\nגישת שורש תושבת!\nהנתונים שלך עשויים להיות מוצפנים אם לא הוצפנו כבר!</string>
<string name="uninstall_magisk_msg">כל המודולים יושבתו/יוסרו!\nגישת Root תושבת!\nהנתונים שלך עשויים להיות מוצפנים אם לא הוצפנו כבר!</string>
<!--Install-->
<string name="keep_force_encryption">שמירה על הצפנה בכח</string>
<string name="keep_dm_verity">שמירה על AVB 2.0/dm-verity</string>
<string name="recovery_mode">מצב שחזור</string>
<string name="recovery_mode">מצב Recovery</string>
<string name="install_options_title">אפשרויות</string>
<string name="install_method_title">שיטה</string>
<string name="install_next">הבא</string>
<string name="install_start">צא לדרך</string>
<string name="manager_download_install">לחיצה להורדה והתקנה</string>
<string name="direct_install">התקנה ישירה (מומלץ)</string>
<string name="install_inactive_slot">התקנה לחריץ לא פעיל (לאחר OTA)</string>
<string name="install_inactive_slot_msg">ההתקן שלך ייאלץ אתחול לחריץ הלא פעיל הנוכחי שלך לאחר הפעלה מחדש!\nיש להשתמש באפשרות זו רק לאחר ביצוע OTA בלבד.\nלהמשיך?</string>
<string name="install_inactive_slot">התקנה לסלוט לא פעיל (לאחר OTA)</string>
<string name="install_inactive_slot_msg">ההתקן שלך ייאלץ אתחול לסלוט הלא פעיל הנוכחי שלך לאחר הפעלה מחדש!\nיש להשתמש באפשרות זו רק לאחר ביצוע OTA בלבד.\nלהמשיך?</string>
<string name="setup_title">התקנה נוספת</string>
<string name="select_patch_file">בחירה והתקנת קובץ</string>
<string name="patch_file_msg">בחירת תמונה גולמית (*.img) או ODIN tarfile (*.tar) או payload.bin (*.bin)</string>
<string name="patch_file_msg">בחירת קובץ גולמי (*.img) או ODIN tarfile (*.tar) או payload.bin (*.bin)</string>
<string name="reboot_delay_toast">מאתחל בעוד 5 שניות…</string>
<string name="flash_screen_title">התקנה</string>
@@ -67,22 +67,22 @@
<string name="su_snack_deny">הרשאות משתמש על עבור %1$s נשללו</string>
<string name="su_snack_notif_on">התראות של %1$s מופעלות</string>
<string name="su_snack_notif_off">התראות של %1$s מושבתות</string>
<string name="su_snack_log_on">יומני רישום עבור %1$s פועלות</string>
<string name="su_snack_log_off">יומני רישום עבור %1$s מושבתות</string>
<string name="su_snack_log_on">Log עבור %1$s מופעל</string>
<string name="su_snack_log_off">Log עבור %1$s מושבת</string>
<string name="su_revoke_title">להסיר?</string>
<string name="su_revoke_msg">נא לאשר שלילת הרשאות עבור %1$s?</string>
<string name="toast">הרמת כוסית</string>
<string name="toast">התראה</string>
<string name="none">ללא</string>
<string name="superuser_toggle_notification">התראות</string>
<string name="superuser_toggle_revoke">הסרה</string>
<string name="superuser_policy_none">טרם נתבקשו הרשאות משתמש על על ידי יישומים</string>
<!--Logs-->
<string name="log_data_none">הינך ללא יומן, יש לנסות להשתמש יותר ביישומי השורש שלך</string>
<string name="log_data_magisk_none">יומני רישום Magisk ריקים, זה מוזר</string>
<string name="menuSaveLog">שמירת יומן רישום</string>
<string name="menuClearLog">ניקוי יומן רישום כעת</string>
<string name="logs_cleared">יומני רישום נוקו בהצלחה</string>
<string name="log_data_none">אין Log, יש לנסות להשתמש יותר ביישומי הRoot שלך</string>
<string name="log_data_magisk_none">Log Magisk ריק, זה מוזר</string>
<string name="menuSaveLog">שמירת Log</string>
<string name="menuClearLog">ניקוי Log כעת</string>
<string name="logs_cleared">Log נוקה בהצלחה</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">יעד UID: %1$d</string>
<string name="target_pid">מציב ns יעד PID: %s</string>
@@ -100,15 +100,15 @@
<!--Module-->
<string name="no_info_provided">(לא סופק מידע)</string>
<string name="reboot_userspace">אתחול רך</string>
<string name="reboot_recovery">אתחול למצב שחזור</string>
<string name="reboot_bootloader">אתחול לטוען האתחול</string>
<string name="reboot_recovery">אתחול למצב Recovery</string>
<string name="reboot_bootloader">אתחול לBootloader</string>
<string name="reboot_download">אתחול למצב הורדה</string>
<string name="reboot_edl">אתחול למצב EDL</string>
<string name="reboot_safe_mode">מצב בטוח</string>
<string name="module_version_author">%1$s מאת %2$s</string>
<string name="module_state_remove">הסרה</string>
<string name="module_action">פעולה</string>
<string name="module_state_restore">שחזור</string>
<string name="module_state_restore">שיחזור</string>
<string name="module_action_install_external">התקנה מהאחסון</string>
<string name="update_available">עדכונים זמינים</string>
<string name="suspend_text_riru">מודול מושעה כי %1$s מופעל</string>
@@ -129,7 +129,7 @@
<string name="settings_hide_app_title">הסתרת היישום Magisk</string>
<string name="settings_hide_app_summary">התקנת יישום מתווך עם מזהה חבילה אקראי ותווית שם מותאמת אישית</string>
<string name="settings_restore_app_title">שיחזור היישום Magisk</string>
<string name="settings_restore_app_summary">ביטול הסתרת היישום ושחזור אל ה-APK המקורי</string>
<string name="settings_restore_app_summary">ביטול הסתרת היישום ושיחזור אל ה-APK המקורי</string>
<string name="language">שפה</string>
<string name="system_default">(ברירת מחדל מערכת)</string>
<string name="settings_check_update_title">בדיקת עדכונים</string>
@@ -144,9 +144,9 @@
<string name="settings_denylist_summary">כל השינויים של Magisk יוחזרו לתהליכים ברשימת הדחייה</string>
<string name="settings_denylist_config_title">הגדרת רשימת הדחייה</string>
<string name="settings_denylist_config_summary">בחירת התהליכים שייכללו ברשימת הדחייה</string>
<string name="settings_hosts_title">מארחים חסרי מערכת</string>
<string name="settings_hosts_summary">מארחים חסרי מערכת תומכים ביישומים חוסמי פרסומות</string>
<string name="settings_hosts_toast">הוספת מודול מארחים חסרי מערכת</string>
<string name="settings_hosts_title">hosts חסרי מערכת</string>
<string name="settings_hosts_summary">hosts חסרי מערכת תומכים ביישומים חוסמי פרסומות</string>
<string name="settings_hosts_toast">הוספת מודול hosts חסרי מערכת</string>
<string name="settings_app_name_hint">שם חדש</string>
<string name="settings_app_name_helper">היישום יארז מחדש בשם זה</string>
<string name="settings_app_name_error">פורמט לא חוקי</string>
@@ -181,16 +181,16 @@
<string name="settings_owner_only">בעל ההתקן בלבד</string>
<string name="settings_owner_manage">אחראי ניהול ההתקן</string>
<string name="settings_user_independent">משתמש עצמאי</string>
<string name="owner_only_summary">לבעלים בלבד ישנה גישת שורש</string>
<string name="owner_manage_summary">הבעלים בלבד יכול לנהל גישת שורש ולקבל הנחיות לבקשה</string>
<string name="user_independent_summary">לכל משתמש יש כללי שורש נפרדים משלו</string>
<string name="owner_only_summary">לבעלים בלבד ישנה גישת Root</string>
<string name="owner_manage_summary">הבעלים בלבד יכול לנהל גישת Root ולקבל הנחיות לבקשה</string>
<string name="user_independent_summary">לכל משתמש יש כללי Root נפרדים משלו</string>
<string name="mount_namespace_mode">מצב הצבת מרחב שם</string>
<string name="settings_ns_global">מרחב שם גלובלי</string>
<string name="settings_ns_requester">מרחב שם מורש</string>
<string name="settings_ns_isolate">מרחב שם מבודד</string>
<string name="global_summary">כלל חיבורי השורש משתמשים במרחב שם הגלובלי</string>
<string name="requester_summary">חיבורי השורש יירשו את מרחב השם של המבקש</string>
<string name="isolate_summary">לכל חיבור שורש יהיה מרחב שם מבודד</string>
<string name="global_summary">כלל חיבורי הRoot משתמשים במרחב שם הגלובלי</string>
<string name="requester_summary">חיבורי הRoot יירשו את מרחב השם של המבקש</string>
<string name="isolate_summary">לכל חיבור Root יהיה מרחב שם מבודד</string>
<!--Notifications-->
<string name="update_channel">עדכוני Magisk</string>
@@ -225,7 +225,7 @@
<string name="setup_fail">ההתקנה כשלה</string>
<string name="env_fix_title">דורש התקנה נוספת</string>
<string name="env_fix_msg">ההתקן שלך זקוק להתקנה נוספת כדי ש-Magisk יפעל כראוי. האם ברצונך להמשיך ולהפעיל מחדש?</string>
<string name="env_full_fix_msg">ההתקן שלך זקוק לצריבה מחדש של Magisk כדי לעבוד כראוי. נא להתקין מחדש את Magisk בתוך היישום, מצב השחזור אינו יכול לקבל מידע נכון על ההתקן.</string>
<string name="env_full_fix_msg">ההתקן שלך זקוק לצריבה מחדש של Magisk כדי לעבוד כראוי. נא להתקין מחדש את Magisk בתוך היישום, מצב הRecovery אינו יכול לקבל מידע נכון על ההתקן.</string>
<string name="setup_msg">הגדרת סביבת ריצה…</string>
<string name="unsupport_magisk_title">גרסת Magisk אינה נתמכת</string>
<string name="unsupport_magisk_msg">גרסה זו של היישום אינה תומכת ביישום Magisk הנמוך מ- %1$s.\n\nהיישום יתנהג כאילו Magisk אינו מותקן,יש לשדרג את Magisk במהירות האפשריות.</string>
@@ -233,7 +233,7 @@
<string name="unsupport_system_app_msg">הפעלת יישום זה כיישום מערכת אינה נתמך. נא להשיב את היישום כיישום משתמש.</string>
<string name="unsupport_other_su_msg">התגלתה פקודת \"su\" שאינה שייכת ליישום Magisk נא להסיר את הפקודה שאינה נתמכת.</string>
<string name="unsupport_external_storage_msg">Magisk מותקן באחסון החיצוני. נא להעביר את היישום לאחסון הפנימי.</string>
<string name="unsupport_nonroot_stub_msg">היישום אינו יכול להמשיך לעבוד במצב הנסתר מכיוון שגישת השורש אבדה. נא לשחזר אותו חזרה ל-APK המקורי.</string>
<string name="unsupport_nonroot_stub_msg">היישום אינו יכול להמשיך לעבוד במצב הנסתר מכיוון שגישת הRoot אבדה. נא לשחזר אותו חזרה ל-APK המקורי.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">הענת הרשאת אחסון להפעלת פונקציה זו</string>
<string name="post_notifications_denied">הענקת הרשאה להתראות כדי להפעיל פונקציה זו</string>

View File

@@ -15,18 +15,18 @@
<string name="app_changelog">앱 변경 사항</string>
<string name="loading">로딩중…</string>
<string name="update">업데이트</string>
<string name="not_available">N/A</string>
<string name="not_available">알 수 없음</string>
<string name="hide">숨기기</string>
<string name="home_package">패키지</string>
<string name="home_app_title"></string>
<string name="home_notice_content">공식 Github 페이지에서 Magisk를 다운로드하십시오. 알 수 없는 소스의 파일이 악의적일 수 있습니다!</string>
<string name="home_notice_content">공식 Github 페이지에서 Magisk를 다운로드하십시오. 알 수 없는 출처에서 받은 파일이 위험할 수 있습니다!</string>
<string name="home_support_title">후원하기</string>
<string name="home_item_source">소스</string>
<string name="home_support_content">Magisk는 항상 무료일 것이며, 오픈소스일 것입니다. 그러나 소액의 후원을 통해 관심을 표할 수 있습니다.</string>
<string name="home_installed_version">설치됨</string>
<string name="home_latest_version">최신</string>
<string name="invalid_update_channel">올바르지 않은 업데이트 채널</string>
<string name="invalid_update_channel">잘못된 업데이트 채널</string>
<string name="uninstall_magisk_title">Magisk 제거</string>
<string name="uninstall_magisk_msg">모든 모듈이 비활성화/제거됩니다. 루트도 제거될 것이며, 데이터도 암호화 되어있지 않으면 암호화될 수도 있습니다.</string>
@@ -51,11 +51,11 @@
<!--Superuser-->
<string name="su_request_title">슈퍼유저 요청</string>
<string name="touch_filtered_warning">앱이 슈퍼유저 요청을 가려, Magisk에서 응답을 확인할 수 없습니다.</string>
<string name="deny">일괄 거부</string>
<string name="prompt">수동 허가</string>
<string name="grant">일괄 허용</string>
<string name="su_warning">기기에 대한 전체 액세스 권한을 부여합니다.\n확실하지 않은 경우 거부하세요!</string>
<string name="forever">영구적으로</string>
<string name="deny">모두 거부</string>
<string name="prompt">물어보기</string>
<string name="grant">모두 허용</string>
<string name="su_warning">기기에 대한 슈퍼유저 권한을 부여합니다.\n확실하지 않은 경우 거부하세요!</string>
<string name="forever">영구</string>
<string name="once">한 번만</string>
<string name="tenmin">10분</string>
<string name="twentymin">20분</string>
@@ -69,20 +69,20 @@
<string name="su_snack_notif_off">%1$s의 알림이 비활성화됨</string>
<string name="su_snack_log_on">%1$s의 로깅이 활성화됨</string>
<string name="su_snack_log_off">%1$s의 로깅이 비활성화됨</string>
<string name="su_revoke_title">취소하시겠습니까?</string>
<string name="su_revoke_msg">정말 %1$s의 권한을 취소하시겠습니까?</string>
<string name="su_revoke_title">제거하시겠습니까?</string>
<string name="su_revoke_msg">정말 %1$s의 권한을 제거하시겠습니까?</string>
<string name="toast">토스트</string>
<string name="none">없음</string>
<string name="superuser_toggle_notification">알림</string>
<string name="superuser_toggle_revoke">권한삭제</string>
<string name="superuser_toggle_revoke">권한 제거</string>
<string name="superuser_policy_none">슈퍼유저 권한을 요청한 앱이 없습니다.</string>
<!--Logs-->
<string name="log_data_none">로그가 없습니다. 슈퍼유저 권한을 필요로 하는 앱을 사용하십시오.</string>
<string name="log_data_magisk_none">Magisk 로그가 없습니다.</string>
<string name="menuSaveLog">로그 저장</string>
<string name="menuClearLog">지금 로그 삭제</string>
<string name="menuClearLog">로그 삭제</string>
<string name="logs_cleared">로그 삭제 완료.</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Target UID: %1$d</string>
@@ -96,9 +96,9 @@
<string name="hide_search">검색</string>
<!--Module-->
<string name="no_info_provided">(제공된 정보 없음)</string>
<string name="no_info_provided">(정보 없음)</string>
<string name="reboot_userspace">조용히 다시 시작</string>
<string name="reboot_recovery">리커버리로 다시 시작</string>
<string name="reboot_recovery">복구 모드로 다시 시작</string>
<string name="reboot_bootloader">부트로더로 다시 시작</string>
<string name="reboot_download">다운로드 모드로 다시 시작</string>
<string name="reboot_edl">EDL로 다시 시작</string>
@@ -107,20 +107,20 @@
<string name="module_state_restore">복구</string>
<string name="module_action_install_external">저장소에서 설치</string>
<string name="update_available">업데이트 가능</string>
<string name="suspend_text_riru">%1$s 가 활성화 되어있어 모듈 로드가 일시정지 되었습니다.</string>
<string name="suspend_text_zygisk">%1$s 가 활성화 되어있어 모듈이 로드되지 않았습니다.</string>
<string name="suspend_text_riru">%1$s 가 활성화 되어있어 모듈 로드되지 않았습니다.</string>
<string name="suspend_text_zygisk">%1$s 가 활성화되어 있지 않아 모듈이 로드되지 않았습니다.</string>
<string name="zygisk_module_unloaded">호환성 문제로 인해 Zygisk 모듈이 로드되지 않았습니다.</string>
<!--Settings-->
<string name="settings_dark_mode_title">테마 선택</string>
<string name="settings_dark_mode_message">원하는 테마 모드를 선택하세요!</string>
<string name="settings_dark_mode_light">기본</string>
<string name="settings_dark_mode_system">시스템 설정값</string>
<string name="settings_dark_mode_system">자동</string>
<string name="settings_dark_mode_dark">다크 모드</string>
<string name="settings_download_path_title">다운로드 경로</string>
<string name="settings_download_path_title">다운로드 위치</string>
<string name="settings_download_path_message">파일이 %1$s에 저장됩니다</string>
<string name="settings_hide_app_title">Magisk 앱 숨기기</string>
<string name="settings_hide_app_summary">랜덤 패키지 ID와 커스텀 앱 이름으로 Magisk 프록시 앱을 설치합니다.</string>
<string name="settings_hide_app_summary">무작위 패키지명과 사용자 지정 앱 이름으로 Magisk 프록시 앱을 설치합니다.</string>
<string name="settings_restore_app_title">Magisk 앱 복원</string>
<string name="settings_restore_app_summary">앱 숨기기를 해제하고 원래 APK로 복원합니다.</string>
<string name="language">언어</string>
@@ -167,12 +167,12 @@
<string name="settings_doh_description">일부 국가에 존재하는 DNS 포이즈닝을 해결합니다.</string>
<string name="multiuser_mode">다중 사용자 모드</string>
<string name="settings_owner_only">기기 소유자만</string>
<string name="settings_owner_manage">기기 소유자에 의해 관리됨</string>
<string name="settings_user_independent">사용자별</string>
<string name="owner_only_summary">소유자만 루트 액세스를 갖습니다.</string>
<string name="owner_manage_summary">소유자만 루트 액세스를 관리하고 요청을 받을 수 있습니다.</string>
<string name="user_independent_summary">각각의 사용자가 개별적인 권한을 갖습니다.</string>
<string name="settings_owner_only">주인 사용자만</string>
<string name="settings_owner_manage">주인 사용자에 의해 관리됨</string>
<string name="settings_user_independent">사용자별 분리</string>
<string name="owner_only_summary">주인 사용자만 루트 액세스를 갖습니다.</string>
<string name="owner_manage_summary">주인 사용자가 다른 사용자들의 루트 액세스를 관리하고 요청을 받을 수 있습니다.</string>
<string name="user_independent_summary">각각의 사용자가 권한을 관리합니다.</string>
<string name="mount_namespace_mode">네임스페이스 마운트 모드</string>
<string name="settings_ns_global">전역 네임스페이스</string>
@@ -187,7 +187,7 @@
<string name="progress_channel">진행 상황</string>
<string name="updated_channel">업데이트 완료</string>
<string name="download_complete">다운로드 완료</string>
<string name="download_file_error">파일 다운로드 오류</string>
<string name="download_file_error">파일 다운로드 실패</string>
<string name="magisk_update_title">새 버전의 Magisk를 사용할 수 있습니다!</string>
<string name="updated_title">Magisk가 업데이트 되었습니다!</string>
<string name="updated_text">터치하여 앱 열기</string>
@@ -208,7 +208,7 @@
<string name="restore_img">이미지 복구</string>
<string name="restore_img_msg">복구하는 중…</string>
<string name="restore_done">복구 완료!</string>
<string name="restore_fail">백업이 존재하지 않습니다!</string>
<string name="restore_fail">백업이 존재하지 않습니다!</string>
<string name="setup_fail">설치 실패</string>
<string name="env_fix_title">추가 설정 필요</string>
<string name="env_fix_msg">Magisk가 제대로 작동하려면 추가 설정이 필요합니다. 다시 시작 하시겠습니까?</string>
@@ -219,10 +219,10 @@
<string name="unsupport_system_app_msg">해당 앱을 시스템 앱으로 실행하는 것은 지원되지 않습니다. 앱을 일반 사용자 앱으로 실행해 주세요.</string>
<string name="unsupport_other_su_msg">Magisk으로 부터 설치되지 않은 \"su\" 바이너리가 감지되었습니다. 다른 루팅 방법을 제거하거나, Magisk 를 다시 설치해주세요.</string>
<string name="unsupport_external_storage_msg">Magisk 가 외부 저장소에 설치되어 있습니다. Magisk 를 내부 저장소에 설치 해주세요.</string>
<string name="unsupport_nonroot_stub_msg">숨겨진 Magisk 앱은 루팅이 풀려 더이상 작동하지 못합니다. 래 APK 를 복원하거나 재설치 해주세요.</string>
<string name="unsupport_nonroot_stub_msg">숨겨진 Magisk 앱은 루트 권한이 손실되어 사용할 수 없습니다. 래 APK 를 복원하거나 재설치 해주세요.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">해당 기능을 사용하려면 저장소 권한을 허용해 주십시오.</string>
<string name="install_unknown_denied">이 기능을 활성화 하려면 "알 수 없는 앱 설치"를 허용해주세요.</string>
<string name="install_unknown_denied">이 기능을 활성화 하려면 "출처를 알 수 없는 앱 설치"를 허용해주세요.</string>
<string name="add_shortcut_title">홈 화면에 바로가기 추가</string>
<string name="add_shortcut_msg">앱을 숨긴 후 아이콘과 이름을 알아보기 힘들 경우를 위해 알아보기 쉬운 바로가기를 홈 화면에 추가합니다.</string>
<string name="app_not_found">해당 작업을 처리할 어플리케이션이 없습니다.</string>

View File

@@ -53,8 +53,9 @@
<string name="touch_filtered_warning">Como um app está ocultando uma solicitação de SuperUsuário, o Magisk não pode verificar sua resposta.</string>
<string name="deny">Negar</string>
<string name="prompt">Perguntar</string>
<string name="restrict">Restringir</string>
<string name="grant">Permitir</string>
<string name="su_warning">Permite acesso total ao seu aparelho.\nNão permita se você não tiver certeza do que está fazendo!</string>
<string name="su_warning">Permite acesso total ao seu dispositivo.\nNão permita se você não tiver certeza do que está fazendo!</string>
<string name="forever">Sempre</string>
<string name="once">Uma vez</string>
<string name="tenmin">10 mins</string>
@@ -63,19 +64,19 @@
<string name="sixtymin">60 mins</string>
<string name="su_allow_toast">%1$s foi permitido o acesso de SuperUsuário</string>
<string name="su_deny_toast">%1$s foi negado o acesso de SuperUsuário</string>
<string name="su_snack_grant">Os acessos de SuperUsuário de %1$s foram concedidos</string>
<string name="su_snack_grant">Os acessos de SuperUsuário de %1$s foram permitidos</string>
<string name="su_snack_deny">Os acessos de SuperUsuário de %1$s foram negados</string>
<string name="su_snack_notif_on">As notificações de %1$s foram ativadas</string>
<string name="su_snack_notif_off">As notificações de %1$s foram desativadas</string>
<string name="su_snack_log_on">Os registros de %1$s foram ativados</string>
<string name="su_snack_log_off">Os registros de %1$s foram desativados</string>
<string name="su_revoke_title">Revogar?</string>
<string name="su_revoke_msg">Confirmar a remoção do acesso de SuperUsuário de %1$s?</string>
<string name="su_revoke_msg">Confirme para revogar os acessos de SuperUsuário de %1$s</string>
<string name="toast">Notificação (Pop-up)</string>
<string name="none">Nenhum</string>
<string name="superuser_toggle_notification">Notificações</string>
<string name="superuser_toggle_revoke">Revogar</string>
<string name="superuser_policy_none">Nenhum app solicitou permissão de SuperUsuário ainda</string>
<string name="superuser_policy_none">Nenhum app solicitou permissão de SuperUsuário ainda.</string>
<!--Logs-->
<string name="log_data_none">Não há registros. Tente usar mais seus apps root.</string>
@@ -135,6 +136,7 @@
<string name="settings_update_channel_title">Canal de atualização</string>
<string name="settings_update_stable">Estável</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_debug">Debug</string>
<string name="settings_update_custom">Personalizado</string>
<string name="settings_update_custom_msg">Insira um URL de canal personalizado</string>
<string name="settings_zygisk_summary">Executa partes do Magisk no Zygote</string>
@@ -169,6 +171,8 @@
<string name="settings_su_auth_title">Autenticação de usuário</string>
<string name="settings_su_auth_summary">Solicite autenticação de usuário durante solicitações de SuperUsuário</string>
<string name="settings_su_auth_insecure">Nenhum método de autenticação está configurado no dispositivo</string>
<string name="settings_su_restrict_title">Restringir recursos root</string>
<string name="settings_su_restrict_summary">Restringirá novos apps de SuperUsuário por padrão. Aviso: isso quebrará a maioria dos apps. Não ative se você não souber o que está fazendo.</string>
<string name="settings_customization">Personalizações</string>
<string name="setting_add_shortcut_summary">Adicione um atalho na tela inicial, caso o nome e o ícone sejam difíceis de reconhecer logo após ocultar o app.</string>
<string name="settings_doh_title">DNS sobre HTTPS</string>
@@ -235,7 +239,7 @@
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Conceda permissão de armazenamento para ativar esta funcionalidade</string>
<string name="post_notifications_denied">Conceda permissão às notificações para ativar esta funcionalidade</string>
<string name="install_unknown_denied">Permita a opção "Instalar apps de fontes desconhecidas" para ativar esta funcionalidade</string>
<string name="install_unknown_denied">Permita a opção \"Instalar apps de fontes desconhecidas\" para ativar esta funcionalidade</string>
<string name="add_shortcut_title">Adicionar atalho à tela inicial</string>
<string name="add_shortcut_msg">Após ocultar o app do Magisk, seu nome e ícone ficarão difíceis de reconhecer. Deseja adicionar um atalho na tela inicial?</string>
<string name="app_not_found">Nenhum app encontrado para realizar esta ação</string>

View File

@@ -3,7 +3,7 @@
<!--Sections-->
<string name="modules">Módulos</string>
<string name="superuser">SuperUsuário</string>
<string name="logs">Registros</string>
<string name="logs">Registos</string>
<string name="settings">Configurações</string>
<string name="install">Instalar</string>
<string name="section_home">Início</string>
@@ -11,50 +11,51 @@
<string name="denylist">Lista de negação</string>
<!--Home-->
<string name="no_connection">Nenhuma conexão disponível</string>
<string name="app_changelog">Registro de alterações</string>
<string name="loading">Carregando</string>
<string name="no_connection">Nenhuma ligação disponível</string>
<string name="app_changelog">Registo de alterações</string>
<string name="loading">A carregar</string>
<string name="update">Atualizar</string>
<string name="not_available">Não disponível</string>
<string name="hide">Ocultar</string>
<string name="home_package">Pacote</string>
<string name="home_app_title">App</string>
<string name="home_notice_content">Baixe o Magisk SOMENTE pela página oficial do GitHub. Arquivos de fontes desconhecidas podem ser maliciosos!</string>
<string name="home_notice_content">Descarregue o Magisk APENAS na página oficial do GitHub. Os ficheiros de fontes desconhecidas podem ser maliciosos!</string>
<string name="home_support_title">Apoie-nos</string>
<string name="home_follow_title">Siga-nos</string>
<string name="home_item_source">Fonte</string>
<string name="home_support_content">Magisk sempre foi e sempre será, gratuito e de código aberto. No entanto, você pode nos ajudar enviando uma pequena doação.</string>
<string name="home_support_content">Magisk sempre foi e sempre será, gratuito e de código aberto. No entanto, você pode ajudar-nos enviando uma pequena doação.</string>
<string name="home_installed_version">Instalado</string>
<string name="home_latest_version">Recente</string>
<string name="invalid_update_channel">Canal de atualização inválido</string>
<string name="uninstall_magisk_title">Desinstalar Magisk</string>
<string name="uninstall_magisk_msg">Todos os módulos serão desativados/removidos!\nO root será removido!\nSeus dados não criptografados devido ao uso do Magisk, serão re-criptografados!</string>
<string name="uninstall_magisk_msg">Todos os módulos serão desativados/removidos!\nO root será removido!\nOs seus dados não encriptados devido à utilização do Magisk, serão re-encriptados!</string>
<!--Install-->
<string name="keep_force_encryption">Manter criptografia forçada</string>
<string name="keep_force_encryption">Manter encriptação forçada</string>
<string name="keep_dm_verity">Manter AVB 2.0/dm-verity</string>
<string name="recovery_mode">Modo Recovery</string>
<string name="install_options_title">Opções</string>
<string name="install_method_title">Método</string>
<string name="install_next">Próximo</string>
<string name="install_start">Vamos lá</string>
<string name="manager_download_install">Toque para baixar e instalar</string>
<string name="manager_download_install">Toque para descarregar e instalar</string>
<string name="direct_install">Instalação direta (recomendada)</string>
<string name="install_inactive_slot">Instalar no slot inativo (após o OTA)</string>
<string name="install_inactive_slot_msg">Seu dispositivo será FORÇADO a inicializar no slot inativo atual após uma reinicialização!\nSó use esta opção após a conclusão do OTA.\nDeseja continuar?</string>
<string name="install_inactive_slot_msg">O seu dispositivo será FORÇADO a inicializar no slot inativo atual após um reinício!\nSó use esta opção após a conclusão do OTA.\nDeseja continuar?</string>
<string name="setup_title">Configuração adicional</string>
<string name="select_patch_file">Selecione e corrija um arquivo</string>
<string name="patch_file_msg">Selecione um arquivo imagem (*.img) ou um arquivo tar (*.tar) ou um arquivo payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Reiniciando em 5 segundos…</string>
<string name="select_patch_file">Selecione e corrija um ficheiro</string>
<string name="patch_file_msg">Selecione um ficheiro de imagem (*.img) ou um ficheiro tar (*.tar) ou um ficheiro payload.bin (*.bin)</string>
<string name="reboot_delay_toast">A reiniciar em 5 segundos…</string>
<string name="flash_screen_title">Instalação</string>
<!--Superuser-->
<string name="su_request_title">Solicitação de SuperUsuário</string>
<string name="touch_filtered_warning">Como um app está ocultando uma solicitação de SuperUsuário, o Magisk não pode verificar sua resposta.</string>
<string name="touch_filtered_warning">Como um app está a ocultar um pedido de SuperUsuário, o Magisk não consegue verificar a sua resposta.</string>
<string name="deny">Negar</string>
<string name="prompt">Perguntar</string>
<string name="restrict">Restringir</string>
<string name="grant">Permitir</string>
<string name="su_warning">Permite acesso total ao seu aparelho.\nNão permita se você não tiver certeza do que está fazendo!</string>
<string name="su_warning">Permite o acesso total ao seu dispositivo.\nNão o permita se não tiver a certeza do que está a fazer!</string>
<string name="forever">Sempre</string>
<string name="once">Uma vez</string>
<string name="tenmin">10 mins</string>
@@ -63,26 +64,26 @@
<string name="sixtymin">60 mins</string>
<string name="su_allow_toast">%1$s foi permitido o acesso de SuperUsuário</string>
<string name="su_deny_toast">%1$s foi negado o acesso de SuperUsuário</string>
<string name="su_snack_grant">Os acessos de SuperUsuário de %1$s foram concedidos</string>
<string name="su_snack_grant">Os acessos de SuperUsuário de %1$s foram permitidos</string>
<string name="su_snack_deny">Os acessos de SuperUsuário de %1$s foram negados</string>
<string name="su_snack_notif_on">As notificações de %1$s foram ativadas</string>
<string name="su_snack_notif_off">As notificações de %1$s foram desativadas</string>
<string name="su_snack_log_on">Os registros de %1$s foram ativados</string>
<string name="su_snack_log_off">Os registros de %1$s foram desativados</string>
<string name="su_snack_log_on">Os registos de %1$s foram ativados</string>
<string name="su_snack_log_off">Os registos de %1$s foram desativados</string>
<string name="su_revoke_title">Revogar?</string>
<string name="su_revoke_msg">Confirmar a remoção do acesso de SuperUsuário de %1$s?</string>
<string name="su_revoke_msg">Confirme para revogar os acessos de SuperUsuário de %1$s</string>
<string name="toast">Notificação (Pop-up)</string>
<string name="none">Nenhum</string>
<string name="superuser_toggle_notification">Notificações</string>
<string name="superuser_toggle_revoke">Revogar</string>
<string name="superuser_policy_none">Nenhum app solicitou permissão de SuperUsuário ainda</string>
<string name="superuser_policy_none">Nenhum app solicitou permissão de SuperUsuário ainda.</string>
<!--Logs-->
<string name="log_data_none">Não há registros. Tente usar mais seus apps root.</string>
<string name="log_data_magisk_none">Os registros do Magisk estão vazios, isso é estranho.</string>
<string name="menuSaveLog">Salvar registros</string>
<string name="menuClearLog">Limpar registros agora</string>
<string name="logs_cleared">Registros limpo com sucesso</string>
<string name="log_data_none">Não há registos. Tente utilizar mais seus apps root.</string>
<string name="log_data_magisk_none">Os registos do Magisk estão vazios, isto é estranho.</string>
<string name="menuSaveLog">Salvar registos</string>
<string name="menuClearLog">Limpar registos agora</string>
<string name="logs_cleared">Registos limpo com sucesso</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Alvo UID: %1$d</string>
<string name="target_pid">Alvo PID: %s</string>
@@ -118,25 +119,26 @@
<!--Settings-->
<string name="settings_dark_mode_title">Modo do tema</string>
<string name="settings_dark_mode_message">Selecione o modo mais adequado para você!</string>
<string name="settings_dark_mode_message">Selecione o modo mais adequado para si!</string>
<string name="settings_dark_mode_light">Sempre claro</string>
<string name="settings_dark_mode_system">Seguir sistema</string>
<string name="settings_dark_mode_dark">Sempre escuro</string>
<string name="settings_download_path_title">Caminho para baixar</string>
<string name="settings_download_path_message">Os arquivos serão salvos em %1$s</string>
<string name="settings_download_path_title">Caminho para descarregar</string>
<string name="settings_download_path_message">Os ficheiros serão salvos em %1$s</string>
<string name="settings_hide_app_title">Ocultar app do Magisk</string>
<string name="settings_hide_app_summary">Instala o app oculto com ID aleatório e nome personalizado</string>
<string name="settings_restore_app_title">Restaurar app do Magisk</string>
<string name="settings_restore_app_summary">Desoculta o app do Magisk e restaura o APK original</string>
<string name="language">Idioma</string>
<string name="system_default">(Padrão do sistema)</string>
<string name="system_default">(Predefinição do sistema)</string>
<string name="settings_check_update_title">Verificar por atualizações</string>
<string name="settings_check_update_summary">Verifique automaticamente se há atualizações ao abrir o app</string>
<string name="settings_update_channel_title">Canal de atualização</string>
<string name="settings_update_stable">Estável</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_debug">Debug</string>
<string name="settings_update_custom">Personalizado</string>
<string name="settings_update_custom_msg">Insira um URL de canal personalizado</string>
<string name="settings_update_custom_msg">Introduza um URL de canal personalizado</string>
<string name="settings_zygisk_summary">Executa partes do Magisk no Zygote</string>
<string name="settings_denylist_title">Aplicar lista de negação</string>
<string name="settings_denylist_summary">Os processos na lista de negação terão todas as modificações do Magisk revertidas</string>
@@ -167,35 +169,37 @@
<string name="settings_su_tapjack_title">Proteção contra atividades sobrepostas</string>
<string name="settings_su_tapjack_summary">A caixa de diálogo do SuperUsuário não responderá à entrada enquanto estiver oculta por qualquer outra janela ou sobreposição</string>
<string name="settings_su_auth_title">Autenticação de usuário</string>
<string name="settings_su_auth_summary">Solicite autenticação de usuário durante solicitações de SuperUsuário</string>
<string name="settings_su_auth_summary">Solicite autenticação de usuário durante pedidos de SuperUsuário</string>
<string name="settings_su_auth_insecure">Nenhum método de autenticação está configurado no dispositivo</string>
<string name="settings_su_restrict_title">Restringir recursos root</string>
<string name="settings_su_restrict_summary">Restringirá novos apps de SuperUsuário por predefinição. Aviso: isto quebrará a maioria dos apps. Não ative se você não souber o que está a fazer.</string>
<string name="settings_customization">Personalizações</string>
<string name="setting_add_shortcut_summary">Adicione um atalho na tela inicial, caso o nome e o ícone sejam difíceis de reconhecer logo após ocultar o app.</string>
<string name="setting_add_shortcut_summary">Adicione um atalho no ecrã inicial, caso o nome e o ícone sejam difíceis de reconhecer logo após ocultar o app.</string>
<string name="settings_doh_title">DNS sobre HTTPS</string>
<string name="settings_doh_description">Solução alternativa para envenenamento de DNS em alguns países</string>
<string name="settings_random_name_title">Randomizar nome de saída</string>
<string name="settings_random_name_description">Randomize o nome do arquivo de saída de imagens corrigidas e arquivos tar (*.tar) para evitar a detecção</string>
<string name="settings_random_name_description">Randomize o nome do ficheiro de saída de imagens corrigidas e ficheiros tar (*.tar) para evitar a deteção</string>
<string name="multiuser_mode">Modo multiusuário</string>
<string name="settings_owner_only">Somente proprietário do dispositivo</string>
<string name="settings_owner_manage">Gerenciado pelo proprietário do dispositivo</string>
<string name="settings_owner_manage">Gerido pelo proprietário do dispositivo</string>
<string name="settings_user_independent">Independente do usuário</string>
<string name="owner_only_summary">Somente o proprietário tem acesso root</string>
<string name="owner_manage_summary">Somente o proprietário pode gerenciar o acesso root e receber pedidos de solicitação</string>
<string name="owner_manage_summary">Somente o proprietário pode gerir o acesso root e receber pedidos de solicitação</string>
<string name="user_independent_summary">Cada usuário tem suas próprias regras de root separadas</string>
<string name="mount_namespace_mode">Montar namespace</string>
<string name="settings_ns_global">Global</string>
<string name="settings_ns_requester">Herdado</string>
<string name="settings_ns_isolate">Individual</string>
<string name="global_summary">Todas as sessões root usam o namespace de montagem global</string>
<string name="requester_summary">As sessões root herdarão o namespace do solicitante</string>
<string name="isolate_summary">Cada sessão root terá seu próprio namespace individual</string>
<string name="global_summary">Todas as sessões root utilizam o namespace de montagem global</string>
<string name="requester_summary">As sessões root herdarão o namespace do requerente</string>
<string name="isolate_summary">Cada sessão root terá o seu próprio namespace individual</string>
<!--Notifications-->
<string name="update_channel">Atualizações do Magisk</string>
<string name="progress_channel">Notificações de progresso</string>
<string name="updated_channel">Atualização concluída</string>
<string name="download_complete">Download concluído</string>
<string name="download_file_error">Erro ao baixar arquivo</string>
<string name="download_file_error">Erro ao descarregar ficheiro</string>
<string name="magisk_update_title">Atualização do Magisk disponível!</string>
<string name="updated_title">Magisk atualizado</string>
<string name="updated_text">Toque para abrir o app</string>
@@ -209,37 +213,37 @@
<string name="close">Fechar</string>
<string name="release_notes">Notas da atualização</string>
<string name="flashing">Flashando…</string>
<string name="running">Executando</string>
<string name="running">A executar</string>
<string name="done">Concluído!</string>
<string name="done_action">Ação de execução de %1$s concluída</string>
<string name="failure">Falhou!</string>
<string name="hide_app_title">Ocultando o app do Magisk…</string>
<string name="hide_app_title">A ocultar o app do Magisk…</string>
<string name="open_link_failed_toast">Nenhum app encontrado para abrir o link</string>
<string name="complete_uninstall">Desinstalação completa</string>
<string name="restore_img">Restaurar imagens</string>
<string name="restore_img_msg">Restaurando</string>
<string name="restore_img_msg">A restaurar</string>
<string name="restore_done">Restauração concluída!</string>
<string name="restore_fail">O backup original não existe!</string>
<string name="setup_fail">Falha na instalação</string>
<string name="env_fix_title">Configuração adicional exigida</string>
<string name="env_fix_msg">Seu dispositivo exige uma configuração adicional para o Magisk funcionar corretamente. Deseja continuar e reiniciar?</string>
<string name="env_full_fix_msg">Seu dispositivo precisa refazer o flash do Magisk para funcionar corretamente. Por favor, reinstale o Magisk no app, o modo Recovery não pode obter as devidas informações do dispositivo.</string>
<string name="setup_msg">Executando a configuração do ambiente…</string>
<string name="env_full_fix_msg">O seu dispositivo precisa de refazer o flash do Magisk para funcionar corretamente. Por favor, reinstale o Magisk no app, o modo Recovery não consegue obter as devidas informações do dispositivo.</string>
<string name="setup_msg">A executar a configuração do ambiente…</string>
<string name="unsupport_magisk_title">Versão do Magisk não suportada</string>
<string name="unsupport_magisk_msg">Esta versão do app não suporta a versão do Magisk inferior a %1$s.\n\nO app irá se comportar como se nenhum Magisk estivesse sido instalado. Por favor, atualize o Magisk assim que possível.</string>
<string name="unsupport_magisk_msg">Esta versão do app não suporta versões do Magisk inferiores a %1$s.\n\nO app irá comportar-se como se nenhum Magisk estivesse instalado. Por favor, atualize o Magisk assim que possível.</string>
<string name="unsupport_general_title">Estado anormal</string>
<string name="unsupport_system_app_msg">Não há suporte para executar este app como um app do sistema. Por favor, reverta o app para um app de usuário.</string>
<string name="unsupport_other_su_msg">Não foi possível detectar o binário \"su\" do Magisk. Por favor, remova qualquer outro root concorrente e/ou reinstale o Magisk.</string>
<string name="unsupport_external_storage_msg">O app do Magisk está instalado no armazenamento externo. Por favor, mova o app para o armazenamento interno.</string>
<string name="unsupport_nonroot_stub_msg">O app oculto do Magisk não pode continuar funcionando porque o root foi perdido. Por favor, restaure o APK original.</string>
<string name="unsupport_nonroot_stub_msg">O app oculto do Magisk não pode continuar a funcionar porque o root foi perdido. Por favor, restaure o APK original.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Conceda permissão de armazenamento para ativar esta funcionalidade</string>
<string name="post_notifications_denied">Conceda permissão às notificações para ativar esta funcionalidade</string>
<string name="install_unknown_denied">Permita a opção "Instalar apps de fontes desconhecidas" para ativar esta funcionalidade</string>
<string name="add_shortcut_title">Adicionar atalho à tela inicial</string>
<string name="add_shortcut_msg">Após ocultar o app do Magisk, seu nome e ícone ficarão difíceis de reconhecer. Deseja adicionar um atalho na tela inicial?</string>
<string name="install_unknown_denied">Permita a opção \"Instalar apps de fontes desconhecidas\" para ativar esta funcionalidade</string>
<string name="add_shortcut_title">Adicionar atalho ao ecrã inicial</string>
<string name="add_shortcut_msg">Após ocultar o app do Magisk, o seu nome e ícone serão difíceis de reconhecer. Deseja adicionar um atalho no ecrã inicial?</string>
<string name="app_not_found">Nenhum app encontrado para realizar esta ação</string>
<string name="reboot_apply_change">Reinicie para aplicar as mudanças</string>
<string name="reboot_apply_change">Reinicie para aplicar as alterações</string>
<string name="restore_app_confirmation">Isso irá restaurar o app oculto do Magisk de volta para o app original. Deseja realmente fazer isso?</string>
</resources>

View File

@@ -2,242 +2,255 @@
<!--Sections-->
<string name="modules">Modulet</string>
<string name="superuser">Super-përdoruesi</string>
<string name="logs">Regjistrat</string>
<string name="settings">Cilësimet</string>
<string name="superuser">Superuser</string>
<string name="logs">Regjistrimet</string>
<string name="settings">Parametrat</string>
<string name="install">Instalo</string>
<string name="section_home">Shtëpi</string>
<string name="section_theme">Tema</string>
<string name="denylist">Lista e mohimit</string>
<string name="section_home">Shtëpia</string>
<string name="section_theme">Temat</string>
<string name="denylist">Lista e ndaluar</string>
<!--Home-->
<string name="no_connection">Nuk ka lidhje interneti</string>
<string name="app_changelog">Ndryshimet</string>
<string name="loading">Po ngarkohet</string>
<string name="no_connection">Nuk ka lidhje të disponueshme</string>
<string name="app_changelog">Shënimet e ndryshimeve</string>
<string name="loading">Duke u ngarkuar</string>
<string name="update">Përditëso</string>
<string name="not_available">N/A</string>
<string name="hide">Fshih</string>
<string name="home_package">Paketa</string>
<string name="home_app_title">App</string>
<string name="home_notice_content">Shkarkoni Magisk VETEM nga faqja zyrtare e GitHub. Skedarët nga burime të panjohura mund të jenë me qëllim të keq! </string>
<string name="home_app_title">Aplikacioni</string>
<string name="home_notice_content">Shkarkoni Magisk VETËM nga faqja zyrtare në GitHub. Skedarët nga burime të panjohura mund të jenë të dëmshëm!</string>
<string name="home_support_title">Na mbështetni</string>
<string name="home_follow_title">Na ndiqni</string>
<string name="home_item_source">Burimi</string>
<string name="home_support_content">Magisk është, dhe gjithmonë do të jetë, falas dhe me burim të hapur. Sidoqoftë, mund të na tregoni se kujdeseni duke dërguar një donacion të vogël.</string>
<string name="home_support_content">Magisk është dhe do të mbetet gjithmonë falas dhe me burim të hapur. Megjithatë, mund të na mbështesni duke bërë një donacion.</string>
<string name="home_installed_version">Instaluar</string>
<string name="home_latest_version">E fundit</string>
<string name="invalid_update_channel">Kanali i përditësimit i pavlefshëm</string>
<string name="home_latest_version">Më i fundit</string>
<string name="invalid_update_channel">Kanal i pavlefshëm për përditësime</string>
<string name="uninstall_magisk_title">Çinstalo Magisk</string>
<string name="uninstall_magisk_msg">Të gjitha modulet do të çaktivizohen/hiqen!\nRrënja do të hiqet!\nTë dhënat tuaja potencialisht të koduara nëse jo tashmë!</string>
<string name="uninstall_magisk_msg">Të gjitha modulet do të çaktivizohen/hiqen!
Root-i do të hiqet!
Çdo memorie e brendshme që është çenkriptuar përmes Magisk do të rikriptohet!</string>
<!--Install-->
<string name="keep_force_encryption">Ruaj kriptimin me forcë</string>
<string name="keep_force_encryption">Ruaj enkriptimin e detyruar</string>
<string name="keep_dm_verity">Ruaj AVB 2.0/dm-verity</string>
<string name="recovery_mode">Recovery Mode</string>
<string name="recovery_mode">Mënyra Recovery</string>
<string name="install_options_title">Opsionet</string>
<string name="install_method_title">Metoda</string>
<string name="install_next">Tjetër</string>
<string name="install_start">Shkojme</string>
<string name="manager_download_install">Shtypni për ta shkarkuar dhe instaluarl</string>
<string name="direct_install">Instalimi i direkt (Rekomandohet)</string>
<string name="install_inactive_slot">Instaloni në slotin joaktiv(Pas OTA)</string>
<string name="install_inactive_slot_msg">Pajisja juaj do të detyrohet të fillojë në folenë aktuale joaktive pas një rindezje!\nPërdoreni këtë opsion vetëm pasi të keni përfunduar OTA.\nVazhdo?</string>
<string name="setup_title">Konfigurimet shtesë</string>
<string name="select_patch_file">Zgjidhni dhe Patch një skader</string>
<string name="patch_file_msg">Zgjidhni një imazh të papërpunuar (*.img) ose një skedar ODIN (*.tar) ose një payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Rinisje pas 5 sekondash…</string>
<string name="install_next">Vazhdoni</string>
<string name="install_start">Le të fillojmë</string>
<string name="manager_download_install">Shtypni për të shkarkuar dhe instaluar</string>
<string name="direct_install">Instalim i drejtpërdrejtë (Rekomandohet)</string>
<string name="install_inactive_slot">Instalo në slot-in joaktiv (Pas OTA)</string>
<string name="install_inactive_slot_msg">Pajisja juaj do të detyrohet të niset në slot-in joaktiv pas rinisjes!
Përdorni këtë opsion vetëm pasi OTA të ketë përfunduar.
Të vazhdoj?</string>
<string name="setup_title">Konfigurim shtesë</string>
<string name="select_patch_file">Zgjidh dhe përpuno një skedar</string>
<string name="patch_file_msg">Zgjidh një imazh të papërpunuar (*.img) ose një skedar ODIN (*.tar) ose një payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Rinisja pas 5 sekondash…</string>
<string name="flash_screen_title">Instalimi</string>
<!--Superuser-->
<string name="su_request_title">Kërkesë nga superpërdoruesi</string>
<string name="touch_filtered_warning">Për shkak se një aplikacion po errëson një kërkesë të superpërdoruesit, Magisk nuk mund të verifikojë përgjigjen tuaj</string>
<string name="su_request_title">Kërkesë Superuser</string>
<string name="touch_filtered_warning">Për shkak se një aplikacion po mbivendos kërkesën Superuser, Magisk nuk mund të verifikojë përgjigjen tuaj.</string>
<string name="deny">Refuzo</string>
<string name="prompt">Pyet</string>
<string name="prompt">Pyete</string>
<string name="restrict">Kufizo</string>
<string name="grant">Lejo</string>
<string name="su_warning">Jep akses të plotë në pajisjen tuaj.\nRefuzo nëse nuk jeni të sigurt!</string>
<string name="forever">Gjithmonë</string>
<string name="su_warning">Jep akses të plotë në pajisjen tuaj.
Refuzoni nëse nuk jeni të sigurt!</string>
<string name="forever">Përgjithmonë</string>
<string name="once">Një herë</string>
<string name="tenmin">10 minuta</string>
<string name="twentymin">20 minuta</string>
<string name="thirtymin">30 minuta</string>
<string name="sixtymin">60 minuta</string>
<string name="su_allow_toast">%1$s iu dha aksesi te Super-përdoruesi</string>
<string name="su_deny_toast">%1$s iu refuzua aksesi te Super -përdoruesi</string>
<string name="su_snack_grant">Aksesi i super-përdoruesit te %1$s është lenuar</string>
<string name="su_snack_deny">Aksesi i super-përdoruesit te %1$s është refuzuar</string>
<string name="su_snack_notif_on">Njoftimet e %1$s janë aktivizuar</string>
<string name="su_snack_notif_off">Njoftimet e %1$s janë çaktivizuar</string>
<string name="su_snack_log_on">Regjistrat e %1$s janë aktivizuar</string>
<string name="su_snack_log_off">Regjistrat e %1$s janë çaktivizuar</string>
<string name="su_revoke_title">drejtat?</string>
<string name="su_revoke_msg">Konfirmo për të hequr të drejtat e %1$s?</string>
<string name="toast">Dolli</string>
<string name="su_allow_toast">%1$s mori të drejtat Superuser</string>
<string name="su_deny_toast">%1$s u refuzua të drejtat Superuser</string>
<string name="su_snack_grant">%1$s mori të drejtat Superuser</string>
<string name="su_snack_deny">%1$s u refuzua të drejtat Superuser</string>
<string name="su_snack_notif_on">Njoftimet për %1$s u aktivizuan</string>
<string name="su_snack_notif_off">Njoftimet për %1$s u çaktivizuan</string>
<string name="su_snack_log_on">Regjistrimi për %1$s u aktivizua</string>
<string name="su_snack_log_off">Regjistrimi për %1$s u çaktivizua</string>
<string name="su_revoke_title">hiqen?</string>
<string name="su_revoke_msg">Konfirmoni heqjen e të drejtave Superuser për %1$s</string>
<string name="toast">Njoftim</string>
<string name="none">Asnjë</string>
<string name="superuser_toggle_notification">Njoftimet</string>
<string name="superuser_toggle_revoke">Të drejtat</string>
<string name="superuser_policy_none">Asnjë aplikacion nuk ka kërkuar akoma akses për super-përdoruesin.</string>
<string name="superuser_toggle_revoke">Hiq</string>
<string name="superuser_policy_none">Asnjë aplikacion nuk ka kërkuar ende leje Superuser.</string>
<!--Logs-->
<string name="log_data_none">Nuk ka regjistra, provoni të përdorni më shumë aplikacionet tuaja me SU</string>
<string name="log_data_magisk_none">Regjistrat Magisk janë bosh, kjo është e çuditshme</string>
<string name="menuSaveLog">Ruaj regjistrar</string>
<string name="menuClearLog">Pastro regjistrat tani</string>
<string name="logs_cleared">Regjistrat u pastuan me sukses</string>
<string name="log_data_none">Nuk keni regjistrime. Provojeni të përdorni më shumë aplikacionet me root.</string>
<string name="log_data_magisk_none">Regjistrimet e Magisk janë bosh — çuditërisht.</string>
<string name="menuSaveLog">Ruaj regjistrimin</string>
<string name="menuClearLog">Pastro regjistrimin tani</string>
<string name="logs_cleared">Regjistrimet u pastruan me sukses</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Target UID: %1$d</string>
<string name="target_pid">Montoni PID synuar ns: %s</string>
<string name="target_uid">UID i synuar: %1$d</string>
<string name="target_pid">PID i synuar: %s</string>
<string name="selinux_context">Konteksti SELinux: %s</string>
<string name="supp_group">Grupi suplementar: %s</string>
<string name="supp_group">Grupi shtesë: %s</string>
<!--MagiskHide-->
<string name="show_system_app">Shfaq aplikacionet e sistemit</string>
<string name="show_os_app">Shfaq aplikacionet e sistemit operativ</string>
<string name="hide_filter_hint">Kërko sipas emrit</string>
<string name="show_os_app">Shfaq aplikacionet e OS</string>
<string name="hide_filter_hint">Filtro sipas emrit</string>
<string name="hide_search">Kërko</string>
<!--Module-->
<string name="no_info_provided">(Nuk ka asnjë informacion)</string>
<string name="reboot_userspace">Rinisje e shpejtë</string>
<string name="reboot_recovery">Rinis te Recovery</string>
<string name="reboot_bootloader">Rinis te Bootloader</string>
<string name="reboot_download">Rinis te Download</string>
<string name="reboot_edl">Rinis te EDL</string>
<string name="reboot_safe_mode">Rinis në safe mode</string>
<string name="no_info_provided">(Nuk u dha informacion)</string>
<string name="reboot_userspace">Rinisje Normale</string>
<string name="reboot_recovery">Rinis Recovery</string>
<string name="reboot_bootloader">Rinis Bootloader</string>
<string name="reboot_download">Rinis Download</string>
<string name="reboot_edl">Rinis EDL</string>
<string name="reboot_safe_mode">Mënyra e sigurt</string>
<string name="module_version_author">%1$s nga %2$s</string>
<string name="module_state_remove">Hiqe</string>
<string name="module_action">Veprim</string>
<string name="module_state_restore">Rikëthe</string>
<string name="module_action_install_external">Instaloni nga sdcard</string>
<string name="update_available">Përditësimi dispozicion</string>
<string name="suspend_text_riru">Moduli u pezullua sepse %1$s është aktivizuar</string>
<string name="suspend_text_zygisk">Moduli është pezulluar sepse %1$s nuk është i aktivizuar</string>
<string name="zygisk_module_unloaded">Moduli Zygisk nuk është ngarkuar për shkak të papajtueshmërisë</string>
<string name="module_empty">Ska module të instaluar</string>
<string name="module_action">Veprimi</string>
<string name="module_state_restore">Rikthe</string>
<string name="module_action_install_external">Instalo nga memoria</string>
<string name="update_available">Përditësim i disponueshëm</string>
<string name="suspend_text_riru">Moduli u pezullua sepse %1$s është aktiv</string>
<string name="suspend_text_zygisk">Moduli u pezullua sepse %1$s nuk është aktiv</string>
<string name="zygisk_module_unloaded">Moduli Zygisk nuk u ngarkua për shkak të mospërputhjes</string>
<string name="module_empty">Nuk ka module të instaluara</string>
<string name="confirm_install">Të instalohet moduli %1$s?</string>
<string name="confirm_install_title">Konfirmo instalimin</string>
<string name="confirm_install_title">Konfirmim instalimi</string>
<!--Settings-->
<string name="settings_dark_mode_title">Mënyra e temës</string>
<string name="settings_dark_mode_message">Zgjidhni mënyrën që i përshtatet më shumë stilit tuaj!</string>
<string name="settings_dark_mode_light">Gjithmonë e bardhë</string>
<string name="settings_dark_mode_system">Sipas sistemit</string>
<string name="settings_dark_mode_dark">Gjithmonë e zezë</string>
<string name="settings_download_path_title">Vendodhje e shkarkimit</string>
<string name="settings_download_path_message">Shkarkimet do të ruhen në %1$s</string>
<string name="settings_hide_app_title">Fsheh aplikacionin Magisk</string>
<string name="settings_hide_app_summary">Instaloni një aplikacion përfaqësues me ID paketës të rastësishme dhe etiketë të personalizuar të aplikacionitl</string>
<string name="settings_restore_app_title">Rivendosni aplikacionin Magisk</string>
<string name="settings_restore_app_summary">un-fsheh aplikacionin dhe riktheni atë në APK origjinale</string>
<string name="settings_dark_mode_message">Zgjidh mënyrën që i përshtatet më shumë stilit tënd!</string>
<string name="settings_dark_mode_light">Gjithmonë e ndritshme</string>
<string name="settings_dark_mode_system">Ndiq sistemin</string>
<string name="settings_dark_mode_dark">Gjithmonë e errët</string>
<string name="settings_download_path_title">Rruga e shkarkimit</string>
<string name="settings_download_path_message">Skedarët do të ruhen në %1$s</string>
<string name="settings_hide_app_title">Fshi aplikacionin Magisk</string>
<string name="settings_hide_app_summary">Instalo një aplikacion proxy me një ID pakete të rastësishme dhe emër të personalizuar</string>
<string name="settings_restore_app_title">Rikthe aplikacionin Magisk</string>
<string name="settings_restore_app_summary">Zbulo aplikacionin dhe rikthe APK-në origjinale</string>
<string name="language">Gjuha</string>
<string name="system_default">(Parazgjedhja e sistemit)</string>
<string name="settings_check_update_title">Kontrollo për përditësime</string>
<string name="settings_check_update_summary">Kontrolloni automatikisht për përditësime në sfond</string>
<string name="settings_update_channel_title">Perditeso kanalin</string>
<string name="settings_update_stable">E qëndrueshme</string>
<string name="settings_check_update_summary">Kontrollo periodikisht për përditësimet në sfond</string>
<string name="settings_update_channel_title">Kanal për përditësime</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Kanal me porosi</string>
<string name="settings_update_custom_msg">Fut një URL të personalizuar</string>
<string name="settings_zygisk_summary">Drejtoni pjesë të Magisk në demonin zygote</string>
<string name="settings_denylist_title">Zbato Listën e Mohimit</string>
<string name="settings_denylist_summary">Proceset në listën e mohimit do të kenë të gjitha modifikimet e Magisk</string>
<string name="settings_denylist_config_title">Konfiguro Listën e Mohimit</string>
<string name="settings_denylist_config_summary">Zgjidhni proceset që do të përfshihen në listën e mohimit</string>
<string name="settings_hosts_title">Pritësit pa sistem</string>
<string name="settings_hosts_summary">Pritësit pa sistem mbështesin aplikacionet Adblock</string>
<string name="settings_hosts_toast">Moduli i hosteve pa sistem u shtua</string>
<string name="settings_app_name_hint">Emri i ri</string>
<string name="settings_app_name_helper">Aplikacioni do të ripaketohet me këtë emër</string>
<string name="settings_update_debug">Debug</string>
<string name="settings_update_custom">Custom</string>
<string name="settings_update_custom_msg">Fut një URL të personalizuar të kanalit</string>
<string name="settings_zygisk_summary">Ekzekuto pjesë të Magisk në demonin Zygote</string>
<string name="settings_denylist_title">Zbato listën e ndaluar</string>
<string name="settings_denylist_summary">Proceset në listën e ndaluar do të rikthehen pa modifikimet e Magisk</string>
<string name="settings_denylist_config_title">Konfiguro listën e ndaluar</string>
<string name="settings_denylist_config_summary">Zgjidh proceset që do të përfshihen në listën e ndaluar</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Mbështetje për systemless hosts për aplikacionet që bllokojnë reklamat</string>
<string name="settings_hosts_toast">U shtua moduli systemless hosts</string>
<string name="settings_app_name_hint">Emër i ri</string>
<string name="settings_app_name_helper">Aplikacioni do të ripaketizohet me këtë emër</string>
<string name="settings_app_name_error">Format i pavlefshëm</string>
<string name="settings_su_app_adb">Aplikacionet dhe ADB</string>
<string name="settings_su_app">Vetëm aplikacionet</string>
<string name="settings_su_adb">Vetëm ADB</string>
<string name="settings_su_disable">Çaktivizuar</string>
<string name="settings_su_request_10">10 Sekonda</string>
<string name="settings_su_request_15">15 Sekonda</string>
<string name="settings_su_request_20">20 Sekonda</string>
<string name="settings_su_request_30">30 Sekonda</string>
<string name="settings_su_request_45">45 Sekonda</string>
<string name="settings_su_request_60">60 Sekonda</string>
<string name="superuser_access">Aksesi i Super-përdorues</string>
<string name="settings_su_request_10">10 sekonda</string>
<string name="settings_su_request_15">15 sekonda</string>
<string name="settings_su_request_20">20 sekonda</string>
<string name="settings_su_request_30">30 sekonda</string>
<string name="settings_su_request_45">45 sekonda</string>
<string name="settings_su_request_60">60 sekonda</string>
<string name="superuser_access">Akses Superuser</string>
<string name="auto_response">Përgjigje automatike</string>
<string name="request_timeout">Koha për mbarimit të Kërkesës</string>
<string name="superuser_notification">Njoftimi i Super-përdoruesit</string>
<string name="settings_su_reauth_title">Ri-vërtetimi pas azhurnimit</string>
<string name="settings_su_reauth_summary">Ri-vërtetoni lejet e super-përdoruesit pas azhurnimit të aplikacionit</string>
<string name="settings_su_tapjack_title">Aktivizo mbrojtjen tapjacking</string>
<string name="settings_su_tapjack_summary">Dialogu i menjëhershëm i super-përdoruesit nuk do ti përgjigjet hyrjes ndërsa është i errësuar nga ndonjë dritare ose mbivendosje tjetër</string>
<string name="request_timeout">Koha e skadimit të kërkesës</string>
<string name="superuser_notification">Njoftimi Superuser</string>
<string name="settings_su_reauth_title">Riautentifikimi pas përditësimit</string>
<string name="settings_su_reauth_summary">Kërko sërish lejet Superuser pas përditësimit të aplikacioneve</string>
<string name="settings_su_tapjack_title">Mbrojtje nga mbivendosja e klikimeve</string>
<string name="settings_su_tapjack_summary">Dritarja e kërkesës Superuser nuk do të pranojë input kur është e mbuluar nga ndonjë dritare tjetër</string>
<string name="settings_su_auth_title">Autentifikimi i përdoruesit</string>
<string name="settings_su_auth_summary">Kërko autentifikim të përdoruesit gjatë kërkesave Superuser</string>
<string name="settings_su_auth_insecure">Nuk ka asnjë metodë autentifikimi të konfiguruar në pajisje</string>
<string name="settings_su_restrict_title">Kufizo aftësitë e root</string>
<string name="settings_su_restrict_summary">Do të kufizojë aplikacionet e reja Superuser si parazgjedhje. Kujdes: kjo mund të prishë shumicën e aplikacioneve. Mos e aktivizoni nëse nuk dini çfarë bëni.</string>
<string name="settings_customization">Personalizimi</string>
<string name="setting_add_shortcut_summary">Shtoni një shkurtore mjaft të mirë në ekranin fillestar në rast se emri dhe ikona janë të vështira për tu njohur pasi keni fshehur aplikacionin</string>
<string name="setting_add_shortcut_summary">Shto një shkurtore në ekranin bazë nëse emri/ikona bëhen të vështira për tu dalluar pas fshehjes së aplikacionit</string>
<string name="settings_doh_title">DNS mbi HTTPS</string>
<string name="settings_doh_description">Helmimi i paqartë nga DNS në disa kombe</string>
<string name="multiuser_mode">Mënyra Multi-përdoruesit</string>
<string name="settings_owner_only">Vetëm pronari i paisjes</string>
<string name="settings_owner_manage">Pronari i paisjes që e manaxhon</string>
<string name="settings_user_independent">I pavarur nga përdoruesi</string>
<string name="owner_only_summary">Vetëm pronari ka akses në rrënjë</string>
<string name="owner_manage_summary">Vetëm pronari mund të menaxhojë aksesin në rrënjë dhe të marrë kërkesat</string>
<string name="user_independent_summary">Çdo përdorues ka rregullat e veta të veçanta rrënjësore</string>
<string name="mount_namespace_mode">Mënyra e Montimit të Hapësirës Emërore</string>
<string name="settings_ns_global">Hapësira globale e emrave</string>
<string name="settings_ns_requester">Trashëgoni hapësirën e emrave</string>
<string name="settings_ns_isolate">Hapësira e izoluar e emrave</string>
<string name="global_summary">Të gjitha sesionet rrënjë përdorin hapësirën globale të emrave të montimit</string>
<string name="requester_summary">Seancat rrënjësore do të trashëgojnë hapësirën e emrave të kërkuesit të tyre</string>
<string name="isolate_summary">Çdo sesion rrënjë do të ketë hapësirën e vet të izoluar të emrave</string>
<string name="settings_su_auth_title">Vërtetimi i përdoruesit</string>
<string name="settings_su_auth_summary">Kërkoni vërtetimin e përdoruesit gjatë kërkesave të Superpërdoruesit</string>
<string name="settings_su_auth_insecure">Asnjë metodë vërtetimi nuk është konfiguruar në pajisje</string>
<string name="settings_doh_description">Zgjidhje për helmimin e DNS në disa shtete</string>
<string name="settings_random_name_title">Emër i rastësishëm</string>
<string name="settings_random_name_description">Rastësizo emrin e skedarit të daljes për imazhet e patch-uara dhe skedarët tar për të shmangur detektimin</string>
<string name="multiuser_mode">Mënyra multi-përdorues</string>
<string name="settings_owner_only">Vetëm pronari i pajisjes</string>
<string name="settings_owner_manage">Menaxhuar nga pronari</string>
<string name="settings_user_independent">I pavarur për përdoruesit</string>
<string name="owner_only_summary">Vetëm pronari ka akses root</string>
<string name="owner_manage_summary">Vetëm pronari mund të menaxhojë aksesin root dhe të marrë kërkesat</string>
<string name="user_independent_summary">Çdo përdorues ka rregullat e veta të root</string>
<string name="mount_namespace_mode">Mënyra e mount namespace</string>
<string name="settings_ns_global">Namespace global</string>
<string name="settings_ns_requester">Trashëgo namespace</string>
<string name="settings_ns_isolate">Namespace i izoluar</string>
<string name="global_summary">Të gjitha sesionet root përdorin namespace global</string>
<string name="requester_summary">Sesioni root trashëgon namespace-in e kërkuesit</string>
<string name="isolate_summary">Çdo sesion root do të ketë namespace të izoluar</string>
<!--Notifications-->
<string name="update_channel">Përditësimet e magisk</string>
<string name="updated_channel">Përditësimi përfundoi</string>
<string name="update_channel">Përditësimet e Magisk</string>
<string name="progress_channel">Njoftimet e progresit</string>
<string name="updated_channel">Përditësimi përfundoi</string>
<string name="download_complete">Shkarkimi përfundoi</string>
<string name="download_file_error">Gabim në shkarkimin e skedarit</string>
<string name="magisk_update_title">Përditësimi Magisk i disponueshëm!</string>
<string name="download_file_error">Gabim gjatë shkarkimit të skedarit</string>
<string name="magisk_update_title">Përditësim i ri i Magisk!</string>
<string name="updated_title">Magisk u përditësua</string>
<string name="updated_text">Prekni për të hapur aplikacionin</string>
<string name="updated_text">Shtypni për të hapur aplikacionin</string>
<!--Toasts, Dialogs-->
<string name="yes">Po</string>
<string name="no">Jo</string>
<string name="repo_install_title">Instalo %1$s %2$s(%3$d)</string>
<string name="download">Shkarko</string>
<string name="reboot">Rinis</string>
<string name="close">Mbylle</string>
<string name="release_notes">Shënimet e lëshimit</string>
<string name="flashing">Duke flashuar</string>
<string name="running">Duke vepruar...</string>
<string name="reboot">Rinise</string>
<string name="close">Mbyll</string>
<string name="release_notes">Shënimet e versionit</string>
<string name="flashing">Duke flashuar..</string>
<string name="running">Duke u ekzekutuar..</string>
<string name="done">U krye!</string>
<string name="done_action">Veprimi i ekzekutimit të %1$s u krye</string>
<string name="done_action">Veprimi i %1$s u krye</string>
<string name="failure">Dështoi!</string>
<string name="hide_app_title">Fshehja e aplikacionit Magisk</string>
<string name="hide_app_title">Duke fshehur aplikacionin Magisk..</string>
<string name="open_link_failed_toast">Nuk u gjet asnjë aplikacion për të hapur lidhjen</string>
<string name="complete_uninstall">Çinstalimi i plotë</string>
<string name="restore_img">Rivendosni imazhet</string>
<string name="restore_img_msg">Duke rivendosur…</string>
<string name="restore_done">Rivendosja u krye!</string>
<string name="restore_fail">Rezervimi i aksioneve nuk ekziston!</string>
<string name="complete_uninstall">Çinstalim i plotë</string>
<string name="restore_img">Rikthe imazhet</string>
<string name="restore_img_msg">Duke rikthyer..</string>
<string name="restore_done">Rikthimi u krye!</string>
<string name="restore_fail">Backup-i origjinal nuk ekziston!</string>
<string name="setup_fail">Konfigurimi dështoi</string>
<string name="env_fix_title">Kërkon Konfigurim shtesë</string>
<string name="env_fix_msg">Pajisja juaj ka nevojë për konfigurim shtesë që Magisk të funksionojë siç duhet. Dëshironi të vazhdoni dhe rindizni?</string>
<string name="env_full_fix_msg">Pajisja juaj ka nevojë për re-flashuar Magisk të funksionojë siç duhet. Ju lutemi ri-instaloni Magisk brenda aplikacionit, modaliteti i rikuperimit nuk mund të marrë informacionin e saktë të pajisjes.</string>
<string name="setup_msg">Konfigurimi i mjedisit të funksionimit…</string>
<string name="unsupport_magisk_title">Version Magjik i Pambështetur</string>
<string name="unsupport_magisk_msg">Ky version i aplikacionit nuk e mbështet versionin Magisk më të ulët se %1$s.\n\nAplikacioni do të sillet sikur të mos jetë i instaluar Magisk, ju lutemi azhurnoni Magisk sa më shpejt të jetë e mundur.</string>
<string name="env_fix_title">Kërkohet konfigurim shtesë</string>
<string name="env_fix_msg">Pajisja ka nevojë për konfigurim shtesë që Magisk të funksionojë si duhet. Dëshironi të vazhdoni dhe të rinisni pajisjen?</string>
<string name="env_full_fix_msg">Pajisja ka nevojë për ri-flash Magisk për të funksionuar saktë. Ju lutemi riinstaloni Magisk brenda aplikacionit; Recovery nuk mund të marrë informacionet e sakta të pajisjes.</string>
<string name="setup_msg">Duke ekzekutuar konfigurimin e mjedisit..</string>
<string name="unsupport_magisk_title">Version i Magisk i pambështetur</string>
<string name="unsupport_magisk_msg">Ky version i aplikacionit nuk mbështet versione të Magisk më të ulëta se %1$s.
Aplikacioni do të sillet sikur Magisk nuk është i instaluar. Ju lutemi përditësoni Magisk sa më shpejt të jetë e mundur.</string>
<string name="unsupport_general_title">Gjendje jonormale</string>
<string name="unsupport_system_app_msg">Drejtimi i këtij aplikacioni si një aplikacion sistemi nuk mbështetet. Ju lutemi kthejeni aplikacionin në një aplikacion përdoruesi.</string>
<string name="unsupport_other_su_msg">Një komandë \"su"\ që nuk i përket Magisk është zbuluar. Ju lutemi hiqni SU-në tjetër të pambështetur.</string>
<string name="unsupport_external_storage_msg">Magisk është instaluar në ruajtjen e jashtme. Ju lutemi zhvendosni aplikacionin në ruajtjen e brendshme.</string>
<string name="unsupport_nonroot_stub_msg">Aplikacioni nuk mund të vazhdojë të punojë në gjendjen e fshehur pasi rrënja ishte e humbur. Ju lutemi rivendoseni përsëri në APK-në origjinale.</string>
<string name="unsupport_system_app_msg">Ekzekutimi i këtij aplikacioni si aplikacion sistemi nuk mbështetet. Ju lutemi kthejeni në aplikacion përdoruesi.</string>
<string name="unsupport_other_su_msg">Është zbuluar një binar "su" që nuk është nga Magisk. Ju lutemi hiqni çdo zgjidhje tjetër root dhe/ose riinstaloni Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk është instaluar në memorien e jashtme. Lëvizni aplikacionin në memorien e brendshme.</string>
<string name="unsupport_nonroot_stub_msg">Aplikacioni i fshehur i Magisk nuk mund të vazhdojë të funksionojë sepse root u humb. Ju lutemi riktheni APK-në origjinale.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Jepni lejen e ruajtjes për të aktivizuar këtë funksion</string>
<string name="external_rw_permission_denied">Jepni lejen e magazinimit për të aktivizuar këtë funksion</string>
<string name="post_notifications_denied">Jepni lejen e njoftimeve për të aktivizuar këtë funksion</string>
<string name="install_unknown_denied">Lejo "instaloni aplikacione të panjohura" për të aktivizuar këtë funksion</string>
<string name="install_unknown_denied">Lejoni "Instalo aplikacione të panjohura" për të aktivizuar këtë funksion</string>
<string name="add_shortcut_title">Shto shkurtore në ekranin bazë</string>
<string name="add_shortcut_msg">Pas fshehjes së këtij aplikacioni, emri dhe ikona e tij mund të bëhen të vështira për tu njohur. Dëshironi të shtoni një shkurtore mjaft të bukur në ekranin bazë?</string>
<string name="app_not_found">Asnjë aplikacion nuk u gjet për të trajtuar këtë veprim</string>
<string name="add_shortcut_msg">Pas fshehjes së aplikacionit, emri dhe ikona mund të jenë të vështira për tu njohur. Dëshironi të shtoni një shkurtore të bukur në ekranin bazë?</string>
<string name="app_not_found">Nuk u gjet aplikacion për të kryer këtë veprim</string>
<string name="reboot_apply_change">Rinisni për të aplikuar ndryshimet</string>
<string name="restore_app_confirmation">Kjo do të rivendosë aplikacionin e fshehur në aplikacionin origjinal. A dëshironi vërtet ta bëni këtë?</string>
<string name="restore_app_confirmation">Kjo do të rikthejë aplikacionin e fshehur në gjendjen origjinale. Jeni të sigurt që dëshironi ta bëni këtë?</string>
</resources>

View File

@@ -1,101 +1,60 @@
<resources>
<!--Universal-->
<!--Author: Radoš Milićev (https://github.com/rammba)-->
<!--Welcome Activity-->
<!--Sections-->
<string name="modules">Модули</string>
<string name="superuser">Супер-корисник</string>
<string name="logs">Дневник</string>
<string name="logs">Логови</string>
<string name="settings">Подешавања</string>
<string name="install">Инсталација</string>
<string name="section_home">Почетно</string>
<string name="section_theme">Теме</string>
<string name="denylist">Листа забрана</string>
<!--Status Fragment-->
<string name="invalid_update_channel">Непостојећи Канал Ажурирања</string>
<!--Home-->
<string name="no_connection">Недоступна конекција</string>
<string name="app_changelog">Промене у апликацији</string>
<string name="loading">Учитавање…</string>
<string name="update">Ажурирање</string>
<string name="not_available">N/A</string>
<string name="hide">Сакриј</string>
<string name="home_package">Пакет</string>
<string name="home_app_title">Апл.</string>
<string name="home_notice_content">Преузмите Magisk САМО са званичне GitHub странице. Фајлови из непознатих извора могу бити малициозни!</string>
<string name="home_support_title">Подржите нас</string>
<string name="home_follow_title">Запратите нас</string>
<string name="home_item_source">Извор</string>
<string name="home_support_content">Magisk јесте и увек ће бити бесплатан и open source. Међутим, можете показати да вам је стало својом донацијом.</string>
<string name="home_installed_version">Инсталирано</string>
<string name="home_latest_version">Најновије</string>
<string name="invalid_update_channel">Невалидан канал ажурирања</string>
<string name="uninstall_magisk_title">Деинсталирај Magisk</string>
<string name="uninstall_magisk_msg">Сви модули ће бити онемогућени/уклоњени!\nКорен ће бити уклоњен!\nСвако неенкриптовано интерно складиште ће употребом Magisk-а бити поново енкриптовано!</string>
<!--Install Fragment-->
<!--Install-->
<string name="keep_force_encryption">Задржи форсирану енкрипцију</string>
<string name="keep_dm_verity">Задржи AVB 2.0/dm-verity</string>
<string name="uninstall_magisk_title">Унинсталирај Магиск</string>
<string name="uninstall_magisk_msg">Сви модули ће бити онеспособљени/уклоњени. Корен ће бити уклоњен, и потенцијално енкриптовати твоје податке уколико већ нису енкриптовани</string>
<string name="update">Ажурирање</string>
<!--Module Fragment-->
<string name="no_info_provided">(Без информација)</string>
<!--Repo Fragment-->
<string name="update_available">Ажурирање доступно</string>
<string name="home_installed_version">Инсталирано</string>
<!--Log Fragment-->
<string name="menuSaveLog">Сачувај дневник</string>
<string name="menuClearLog">Обриши дневник</string>
<string name="logs_cleared">Дневник успешно креиран</string>
<!--About Activity-->
<string name="app_changelog">Дневник промена апликације</string>
<!--Toasts, Dialogs-->
<string name="repo_install_title">Инсталирај %1$s %2$s(%3$d)</string>
<string name="download">Преузми</string>
<string name="reboot">Рестартуј</string>
<string name="magisk_update_title">Нови Адбејт Магиска Доступан!</string>
<string name="release_notes">Белешке обљављивања</string>
<string name="recovery_mode">Режим опоравка</string>
<string name="install_options_title">Опције</string>
<string name="install_method_title">Метод</string>
<string name="install_next">Наредно</string>
<string name="install_start">Почнимо</string>
<string name="manager_download_install">Притисни да преузмеш и инсталираш</string>
<string name="update_channel">Магиск Ажурирање</string>
<string name="flashing">Флешовање</string>
<string name="direct_install">Директна Инсталација (Препоручено)</string>
<string name="complete_uninstall">Комплетна Унинсталација</string>
<string name="restore_done">Повратак успешан!</string>
<string name="restore_fail">Фабрички бекап не постоји!</string>
<string name="download_file_error">Грешка при преузимању фајла</string>
<!--Settings Activity -->
<string name="language">Језик</string>
<string name="system_default">(Фабрички Система)</string>
<string name="settings_update_channel_title">Канал Ажурирања</string>
<string name="settings_update_stable">Стабилан</string>
<string name="settings_update_beta">Бета</string>
<string name="settings_update_custom">По наруџби</string>
<string name="settings_update_custom_msg">Унеси наруџбени УРЛ</string>
<string name="settings_hosts_title">Без-системски домаћини (hosts)</string>
<string name="settings_hosts_summary">Подршка без-системских домаћина за апликације за блокирање реклама</string>
<string name="settings_su_app_adb">Апликације и АДБ</string>
<string name="settings_su_app">Само Апликације</string>
<string name="settings_su_adb">Само АДБ</string>
<string name="settings_su_disable">Онемогућено</string>
<string name="settings_su_request_10">10 секунди</string>
<string name="settings_su_request_15">15 секунди</string>
<string name="settings_su_request_20">20 секунди</string>
<string name="settings_su_request_30">30 секунди</string>
<string name="settings_su_request_45">45 секунди</string>
<string name="settings_su_request_60">60 секунди</string>
<string name="superuser_access">Приступ Супер-кориснику</string>
<string name="auto_response">Аутоматски одговор</string>
<string name="request_timeout">Истек захтева</string>
<string name="superuser_notification">Нотификације Супер-корисника</string>
<string name="settings_su_reauth_title">Поново одобри после ажурирања</string>
<string name="settings_su_reauth_summary">Поново одобри дозволу Супер-корисника после ажурирања апликације</string>
<string name="multiuser_mode">Више-кориснички режим</string>
<string name="settings_owner_only">Власник уређаја само</string>
<string name="settings_owner_manage">Одређено од стране власника</string>
<string name="settings_user_independent">Независно од корисника</string>
<string name="owner_only_summary">Само власник има приступ корену</string>
<string name="owner_manage_summary">Само власник може да приступа корену и да прими захтеве за њега</string>
<string name="user_independent_summary">Сваки корисник има своја правила корена</string>
<string name="mount_namespace_mode">Постоље режима имена простора</string>
<string name="settings_ns_global">Глобално име простора</string>
<string name="settings_ns_requester">Наслеђено име простора</string>
<string name="settings_ns_isolate">Ограђено име простора</string>
<string name="global_summary">Све коренске сесије користе глобално име простора</string>
<string name="requester_summary">Коренске сесије ће наследити свој простор именовања</string>
<string name="isolate_summary">Свака коренска сесија ће имати свој изоловани простор именовања</string>
<string name="direct_install">Директна инсталација (Препоручено)</string>
<string name="install_inactive_slot">Инсталација на неактиван слот (Након OTA)</string>
<string name="install_inactive_slot_msg">Ваш уређај ће бити ФОРСИРАН да се покрене на тренутно неактивном слоту након поновног покретања!\nКористите опцију само кад се OTA заврши.\nНастави?</string>
<string name="setup_title">Додатне поставке</string>
<string name="select_patch_file">Изаберите фајл</string>
<string name="patch_file_msg">Изаберите слику (*.img) или ODIN tarfile (*.tar) или payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Поново покретање за 5 секунди…</string>
<string name="flash_screen_title">Инсталација</string>
<!--Superuser-->
<string name="su_request_title">Супер-кориснички захтев</string>
<string name="touch_filtered_warning">Magisk не може да верификује ваш одговор, јер апликација прикрива супер-кориснички захтев.</string>
<string name="deny">Забрани</string>
<string name="prompt">Захтев</string>
<string name="restrict">Ограничи</string>
<string name="grant">Дозволи</string>
<string name="su_warning">Пружа потпун приступ вашем уређају.\nЗабраните ако нисте сигурни!</string>
<string name="forever">Заувек</string>
@@ -104,20 +63,188 @@
<string name="twentymin">20 мин</string>
<string name="thirtymin">30 мин</string>
<string name="sixtymin">60 мин</string>
<string name="su_allow_toast">%1$s је добио права на Супер-корисника</string>
<string name="su_deny_toast">%1$s није добио права на Супер-корисника</string>
<string name="su_allow_toast">%1$s је добио права на супер-корисника</string>
<string name="su_deny_toast">%1$s није добио права на супер-корисника</string>
<string name="su_snack_grant">Супер-корисничка права од %1$s су пружена</string>
<string name="su_snack_deny">Супер-корисничка права од %1$s су одбијена</string>
<string name="su_snack_notif_on">Нотификације од %1$s су омогућене</string>
<string name="su_snack_notif_off">Нотификације од %1$s су онемогућене</string>
<string name="su_snack_log_on">Записивање у дневник за %1$s је омогућено</string>
<string name="su_snack_log_off">Записивање у дневник за %1$s је онемогућено</string>
<string name="su_snack_log_on">Логовање за %1$s је омогућено</string>
<string name="su_snack_log_off">Логовање за %1$s је онемогућено</string>
<string name="su_revoke_title">Опозови?</string>
<string name="su_revoke_msg">Потврди да опозовеш права од %1$s?</string>
<string name="toast">Тост</string>
<string name="none">Ниједан</string>
<string name="su_revoke_msg">Потврди да опозовеш права на супер-корисника од %1$s?</string>
<string name="toast">Toast</string>
<string name="none">Ништа</string>
<string name="superuser_toggle_notification">Нотификације</string>
<string name="superuser_toggle_revoke">Опозови</string>
<string name="superuser_policy_none">Ниједна апликација није тражила пермисије за супер-корисника још увек.</string>
<!--Superuser logs-->
<string name="target_uid">Циљани УИД: %1$d</string>
<!--Logs-->
<string name="log_data_none">Немате логова. Покушајте користити коренске апликације више.</string>
<string name="log_data_magisk_none">Magisk логови су празни, то је чудно.</string>
<string name="menuSaveLog">Сачувај лог</string>
<string name="menuClearLog">Уклони лог</string>
<string name="logs_cleared">Лог успешно уклоњен</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Циљани UID: %1$d</string>
<string name="target_pid">Циљани PID: %s</string>
<string name="selinux_context">SELinux контекст: %s</string>
<string name="supp_group">Допунска група: %s</string>
<!--MagiskHide-->
<string name="show_system_app">Прикажи системске апл.</string>
<string name="show_os_app">Прикажи апл. ОС-а</string>
<string name="hide_filter_hint">Филтрирај по имену</string>
<string name="hide_search">Претрага</string>
<!--Module-->
<string name="no_info_provided">(Без информација)</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="reboot_safe_mode">Сигуран мод</string>
<string name="module_version_author">%1$s од %2$s</string>
<string name="module_state_remove">Уклони</string>
<string name="module_action">Акција</string>
<string name="module_state_restore">Поврати</string>
<string name="module_action_install_external">Инсталирај из складишта</string>
<string name="update_available">Ажурирање доступно</string>
<string name="suspend_text_riru">Модул је суспендован јер је %1$s омогућено</string>
<string name="suspend_text_zygisk">Модул је суспендован јер %1$s није омогућено</string>
<string name="zygisk_module_unloaded">Zygisk модул није учитан због некомпатибилности</string>
<string name="module_empty">Ниједан модул није инсталиран</string>
<string name="confirm_install">Инсталирај модул %1$s?</string>
<string name="confirm_install_title">Потврда инсталације</string>
<!--Settings-->
<string name="settings_dark_mode_title">Тема</string>
<string name="settings_dark_mode_message">Изаберите тему која вам највише одговара!</string>
<string name="settings_dark_mode_light">Увек светло</string>
<string name="settings_dark_mode_system">Прати систем</string>
<string name="settings_dark_mode_dark">Увек тамно</string>
<string name="settings_download_path_title">Путања за преузимање</string>
<string name="settings_download_path_message">Фајлови ће бити сачувани на %1$s</string>
<string name="settings_hide_app_title">Сакриј Magisk апл.</string>
<string name="settings_hide_app_summary">Инсталирај proxy апликацију са насумичним ID-јем пакета и прилагођеном лабелом</string>
<string name="settings_restore_app_title">Поврати Magisk апл.</string>
<string name="settings_restore_app_summary">Откриј апл. и поврати оригинални APK</string>
<string name="language">Језик</string>
<string name="system_default">(Подразумевано системски)</string>
<string name="settings_check_update_title">Провери ажурирања</string>
<string name="settings_check_update_summary">Периодично провери ажурирања у позадини</string>
<string name="settings_update_channel_title">Канал ажурирања</string>
<string name="settings_update_stable">Стабилно</string>
<string name="settings_update_beta">Бета</string>
<string name="settings_update_debug">Debug</string>
<string name="settings_update_custom">Прилагођено</string>
<string name="settings_update_custom_msg">Унеси прилагођени URL канала</string>
<string name="settings_zygisk_summary">Покрени делове Magisk-а у Zygote daemon-у</string>
<string name="settings_denylist_title">Спроведи листу забрана</string>
<string name="settings_denylist_summary">Процеси на листи забрана ће повратити све Magisk измене</string>
<string name="settings_denylist_config_title">Конфигуриши листу забрана</string>
<string name="settings_denylist_config_summary">Изабери процесе који ће бити на листи забрана</string>
<string name="settings_hosts_title">Безсистемски домаћини (hosts)</string>
<string name="settings_hosts_summary">Подршка безсистемских домаћина за апликације блокирања реклама</string>
<string name="settings_hosts_toast">Модул безсистемских домаћина додат</string>
<string name="settings_app_name_hint">Ново име</string>
<string name="settings_app_name_helper">Апл. ће бити спакована под овим именом</string>
<string name="settings_app_name_error">Невалидан формат</string>
<string name="settings_su_app_adb">Апликације и ADB</string>
<string name="settings_su_app">Само апликације</string>
<string name="settings_su_adb">Само ADB</string>
<string name="settings_su_disable">Онемогућено</string>
<string name="settings_su_request_10">10 секунди</string>
<string name="settings_su_request_15">15 секунди</string>
<string name="settings_su_request_20">20 секунди</string>
<string name="settings_su_request_30">30 секунди</string>
<string name="settings_su_request_45">45 секунди</string>
<string name="settings_su_request_60">60 секунди</string>
<string name="superuser_access">Приступ супер-корисника</string>
<string name="auto_response">Аутоматски одговор</string>
<string name="request_timeout">Истек захтева</string>
<string name="superuser_notification">Нотификације супер-корисника</string>
<string name="settings_su_reauth_title">Поново одобри након ажурирања</string>
<string name="settings_su_reauth_summary">Поново тражи пермисије супер-корисника након ажурирања апликација</string>
<string name="settings_su_tapjack_title">Заштита од tapjacking-а</string>
<string name="settings_su_tapjack_summary">Prompt дијалог супер-корисника неће реаговати док је прикривен другим прозором или overlay-ем</string>
<string name="settings_su_auth_title">Аутентификација корисника</string>
<string name="settings_su_auth_summary">Тражи аутентификацију корисника током захтева супер-корисника</string>
<string name="settings_su_auth_insecure">Ниједан метод аутентификације није подешен на уређају</string>
<string name="settings_su_restrict_title">Ограничи коренске способности</string>
<string name="settings_su_restrict_summary">Подразумевано ограничава апл. супер-корисника. Упозорење: ово ће већину апликација скршити. Не омогућавај, осим ако знаш шта радиш.</string>
<string name="settings_customization">Прилагођавање</string>
<string name="setting_add_shortcut_summary">Додај лепу пречицу на почетни екран у случају да се име и иконица не препознају лако након скривања апликације</string>
<string name="settings_doh_title">DNS преко HTTPS-а</string>
<string name="settings_doh_description">Заобилазно решење DNS тровања у неким нацијама</string>
<string name="settings_random_name_title">Насумично име на излазу</string>
<string name="settings_random_name_description">Насумично име излазног фајла слика и tar фајлова ради спречавања детекције</string>
<string name="multiuser_mode">Вишекориснички режим</string>
<string name="settings_owner_only">Само власник уређаја</string>
<string name="settings_owner_manage">Одређено од стране власника</string>
<string name="settings_user_independent">Независно од корисника</string>
<string name="owner_only_summary">Само власник има приступ корену</string>
<string name="owner_manage_summary">Само власник може да приступа корену и да прима захтеве за њега</string>
<string name="user_independent_summary">Сваки корисник има своја правила корена</string>
<string name="mount_namespace_mode">Mount режим namespace-а</string>
<string name="settings_ns_global">Глобални namespace</string>
<string name="settings_ns_requester">Наслеђени namespace</string>
<string name="settings_ns_isolate">Изоловани namespace</string>
<string name="global_summary">Све коренске сесије користе глобални mount namespace</string>
<string name="requester_summary">Коренске сесије ће наследити namespace од подносиоца захтева</string>
<string name="isolate_summary">Свака коренска сесија ће имати свој изоловани namespace</string>
<!--Notifications-->
<string name="update_channel">Ажурирања Magisk-а</string>
<string name="progress_channel">Нотификације о прогресу</string>
<string name="updated_channel">Ажурирање завршено</string>
<string name="download_complete">Преузимање завршено</string>
<string name="download_file_error">Грешка при преузимању фајла</string>
<string name="magisk_update_title">Ажурирање Magisk-а доступно!</string>
<string name="updated_title">Magisk је ажуриран</string>
<string name="updated_text">Кликни да отвориш апликацију</string>
<!--Toasts, Dialogs-->
<string name="yes">Да</string>
<string name="no">Не</string>
<string name="repo_install_title">Инсталирај %1$s %2$s(%3$d)</string>
<string name="download">Преузми</string>
<string name="reboot">Поново покрени</string>
<string name="close">Затвори</string>
<string name="release_notes">Release notes</string>
<string name="flashing">Флешовање…</string>
<string name="running">Покретање…</string>
<string name="done">Завршено!</string>
<string name="done_action">Покретање акције %1$s завршено</string>
<string name="failure">Неуспешно!</string>
<string name="hide_app_title">Скривање Magisk апликације…</string>
<string name="open_link_failed_toast">Није пронађена апликација за отварање линка</string>
<string name="complete_uninstall">Комплетна деинсталација</string>
<string name="restore_img">Поврати слике</string>
<string name="restore_img_msg">Повратак…</string>
<string name="restore_done">Повратак успешан!</string>
<string name="restore_fail">Фабрички бекап не постоји!</string>
<string name="setup_fail">Неуспешна поставка</string>
<string name="env_fix_title">Потребно додатно подешавање</string>
<string name="env_fix_msg">Ваш уређај захтева додатно подешавање да би Magisk радио како треба. Да ли желите наставити и покренути поново?</string>
<string name="env_full_fix_msg">Ваш уређај захтева поновно флешовање да би Magisk радио како треба. Реинсталирајте Magisk кроз апликацију, режим опоравка не може добити тачне информације о уређају.</string>
<string name="setup_msg">Покретање подешавања окружења…</string>
<string name="unsupport_magisk_title">Неподржана верзија Magisk-а</string>
<string name="unsupport_magisk_msg">Ова верзија апликације не подржава Magisk верзије мање од %1$s.\n\nАпликација ће се понашати као да Magisk није инсталиран. Молимо ажурирајте Magisk што пре.</string>
<string name="unsupport_general_title">Ненормално стање</string>
<string name="unsupport_system_app_msg">Покретање апликације као системске није подржано. Молимо поставите апликацију да буде корисничка.</string>
<string name="unsupport_other_su_msg">Детектован \"su\" binary који није Magisk-ов. Молимо уклоните конкурентно коренско решење и/или реинсталирајте Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk је инсталиран на екстерно складиште. Молимо померите апл. у интерно складиште.</string>
<string name="unsupport_nonroot_stub_msg">Скривена Magisk апликација не може наставити са радом јер је корен изгубљен. Молимо повратите оригинални APK.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Дозволите пермисију за складиште да бисте омогућили ову функционалност</string>
<string name="post_notifications_denied">Дозволите пермисију за нотификације да бисте омогућили ову функционалност</string>
<string name="install_unknown_denied">Дозволите \"инсталирање непознатих апликација\" да бисте омогућили ову функционалност</string>
<string name="add_shortcut_title">Додај пречицу на почетни екран</string>
<string name="add_shortcut_msg">Након скривања апликације, њено име и иконицу ћете тешко препознати. Желите ли додати лепу пречицу на почетни екран?</string>
<string name="app_not_found">Није пронађена апликација за ову акцију</string>
<string name="reboot_apply_change">Поново покрени да примениш измене</string>
<string name="restore_app_confirmation">Ово ће вратити скривену апликацију на оригиналну. Да ли стварно то желите?</string>
</resources>

View File

@@ -5,116 +5,114 @@
<string name="superuser">Süper Kullanıcı</string>
<string name="logs">Günlükler</string>
<string name="settings">Ayarlar</string>
<string name="install">Yükle</string>
<string name="install">Kur</string>
<string name="section_home">Ana Sayfa</string>
<string name="section_theme">Temalar</string>
<string name="denylist">Reddetme Listesi</string>
<string name="denylist">Red Listesi</string>
<!--Home-->
<string name="no_connection">Bağlantı yok</string>
<string name="no_connection">Bağlantı Yok</string>
<string name="app_changelog">Değişiklik Günlüğü</string>
<string name="loading">Yükleniyor…</string>
<string name="update">Güncelle</string>
<string name="not_available">Yok</string>
<string name="not_available">Mevcut Değil</string>
<string name="hide">Gizle</string>
<string name="home_package">Paket</string>
<string name="home_app_title">Uygulama</string>
<string name="home_notice_content">Magisk\'i YALNIZCA resmi GitHub sayfasından indirin. Bilinmeyen kaynaklardan gelen dosyalar zararlı olabilir!</string>
<string name="home_support_title">Bizi Destekleyin</string>
<string name="home_notice_content">Magisk\'i YALNIZCA resmi GitHub sayfasından indirin. Bilinmeyen kaynaklardan gelen dosyalar kötü amaçlı olabilir!</string>
<string name="home_support_title">Bize Destek Olun</string>
<string name="home_follow_title">Bizi Takip Edin</string>
<string name="home_item_source">Kaynak</string>
<string name="home_support_content">Magisk her zaman ücretsiz veık kaynak olacaktır. Ancak, bir bağış yaparak bize destek olabilirsiniz.</string>
<string name="home_installed_version">Yüklü Sürüm</string>
<string name="home_latest_version">En Son Sürüm</string>
<string name="invalid_update_channel">Geçersiz Güncelleme Kanalı</string>
<string name="home_support_content">Magisk ücretsizdir,ık kaynaklıdır ve her zaman öyle kalacaktır. Ancak, bağış yaparak bize değer verdiğinizi gösterebilirsiniz.</string>
<string name="home_installed_version">Yüklü</string>
<string name="home_latest_version">En Son</string>
<string name="invalid_update_channel">Geçersiz güncelleme kanalı</string>
<string name="uninstall_magisk_title">Magisk\'i Kaldır</string>
<string name="uninstall_magisk_msg">Tüm modüller devre dışı bırakılacak/kaldırılacak!\nKök kaldırılacak!\nMagisk kullanılarak şifrelenmemiş herhangi bir dahili depolama yeniden şifrelenecek!</string>
<string name="uninstall_magisk_msg">Tüm modüller devre dışı bırakılacak/kaldırılacak!\nRoot kaldırılacak!\nMagisk kullanılarak şifresi çözülen dahili depolama birimleri yeniden şifrelenecek!</string>
<!--Install-->
<string name="keep_force_encryption">Zorla şifrelemeyi koru</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity\'yi koru</string>
<string name="keep_force_encryption">Zorunlu Şifrelemeyi Koru</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity Koru</string>
<string name="recovery_mode">Kurtarma Modu</string>
<string name="install_options_title">Seçenekler</string>
<string name="install_method_title">Yöntem</string>
<string name="install_next">Sonraki</string>
<string name="install_start">Hadi başlayalım</string>
<string name="manager_download_install">İndirmek ve yüklemek için basın</string>
<string name="direct_install">Doğrudan Yükleme (Önerilir)</string>
<string name="install_inactive_slot">Etkin Olmayan Slot\'a Yükle (OTA Sonrası)</string>
<string name="install_inactive_slot_msg">Cihazınız yeniden başlatıldıktan sonra zorunlu olarak mevcut etkin olmayan slota önyükleme yapılacaktır!\nBu seçeneği yalnızca OTA tamamlandıktan sonra kullanın.\nDevam etmek istiyor musunuz?</string>
<string name="install_start">Hadi Başlayalım</string>
<string name="manager_download_install">İndirmek ve kurmak için basın</string>
<string name="direct_install">Doğrudan kurulum (Önerilen)</string>
<string name="install_inactive_slot">Etkin olmayan slota kur (OTA sonrası)</string>
<string name="install_inactive_slot_msg">Cihazınız, yeniden başlattıktan sonra mevcut etkin olmayan slota önyükleme yapmaya ZORLANACAKTIR!\nBu seçeneği yalnızca OTA güncellemesi yapıldıktan sonra kullanın.\nDevam edilsin mi?</string>
<string name="setup_title">Ek Kurulum</string>
<string name="select_patch_file">Bir Dosya Seç ve Yama Yap</string>
<string name="patch_file_msg">Ham bir görüntü (*.img) veya bir ODIN tar dosyası (*.tar) veya bir payload.bin (*.bin) seçin</string>
<string name="select_patch_file">Bir dosya sin ve yamalayın</string>
<string name="patch_file_msg">Ham bir imaj (*.img), bir ODIN tar dosyası (*.tar) veya bir payload.bin (*.bin) seçin</string>
<string name="reboot_delay_toast">5 saniye içinde yeniden başlatılıyor…</string>
<string name="flash_screen_title">Yükleniyor</string>
<string name="flash_screen_title">Kuruluyor</string>
<!--Superuser-->
<string name="su_request_title">Süper Kullanıcı İsteği</string>
<string name="touch_filtered_warning">Bir uygulama bir Süper Kullanıcı isteğini engellediği için Magisk yanıtınızı doğrulayamıyor</string>
<string name="touch_filtered_warning">Bir uygulama Süper Kullanıcı isteğini engellediği için Magisk yanıtınızı doğrulayamıyor.</string>
<string name="deny">Reddet</string>
<string name="prompt">İstem</string>
<string name="prompt">Sor</string>
<string name="restrict">Kısıtla</string>
<string name="grant">İzin Ver</string>
<string name="su_warning">Cihazınıza tam erişim sağlar.\nEmin değilseniz reddedin!</string>
<string name="forever">Daima</string>
<string name="once">Bir kez</string>
<string name="tenmin">10 dakika</string>
<string name="twentymin">20 dakika</string>
<string name="thirtymin">30 dakika</string>
<string name="sixtymin">60 dakika</string>
<string name="su_allow_toast">%1$s uygulamasının süper kullanıcı hakları verildi</string>
<string name="su_deny_toast">%1$s uygulamasının süper kullanıcı hakları reddedildi</string>
<string name="su_snack_grant">%1$s uygulamasının süper kullanıcı hakları verildi</string>
<string name="su_snack_deny">%1$s uygulamasının süper kullanıcı hakları reddedildi</string>
<string name="su_snack_notif_on">%1$s uygulamasının bildirimleri etkinleştirildi</string>
<string name="su_snack_notif_off">%1$s uygulamasının bildirimleri devre dışı bırakıldı</string>
<string name="su_snack_log_on">%1$s uygulamasının günlüğü etkinleştirildi</string>
<string name="su_snack_log_off">%1$s uygulamasının günlüğü devre dışı bırakıldı</string>
<string name="su_revoke_title">İptal Et?</string>
<string name="su_revoke_msg">%1$s uygulamasının süper kullanıcı haklarını iptal etmek istediğinize emin misiniz?</string>
<string name="toast">Bildirim</string>
<string name="forever">Her Zaman</string>
<string name="once">Bir Kez</string>
<string name="tenmin">10 Dakika</string>
<string name="twentymin">20 Dakika</string>
<string name="thirtymin">30 Dakika</string>
<string name="sixtymin">60 Dakika</string>
<string name="su_allow_toast">%1$s uygulamasına Süper Kullanıcı hakları verildi</string>
<string name="su_deny_toast">%1$s uygulamasının Süper Kullanıcı hakları reddedildi</string>
<string name="su_snack_grant">%1$s uygulamasının Süper Kullanıcı hakları verildi</string>
<string name="su_snack_deny">%1$s uygulamasının Süper Kullanıcı hakları reddedildi</string>
<string name="su_snack_notif_on">%1$s bildirimleri etkinleştirildi</string>
<string name="su_snack_notif_off">%1$s bildirimleri devre dışı bırakıldı</string>
<string name="su_snack_log_on">%1$s için günlük kaydı etkinleştirildi</string>
<string name="su_snack_log_off">%1$s için günlük kaydı devre dışı bırakıldı</string>
<string name="su_revoke_title">İptal Edilsin mi?</string>
<string name="su_revoke_msg">%1$s uygulamasının Süper Kullanıcı haklarını iptal etmeyi onaylayın</string>
<string name="toast">Bildirim Penceresi</string>
<string name="none">Yok</string>
<string name="superuser_toggle_notification">Bildirimler</string>
<string name="superuser_toggle_revoke">İptal Et</string>
<string name="superuser_policy_none">Henüz hiçbir uygulama Süper Kullanıcı izni istemedi.</string>
<!--Logs-->
<string name="log_data_none">Günlük kullanmıyorsunuz, root (kök) uygulamalarınızı daha çok kullanmayı deneyin</string>
<string name="log_data_magisk_none">Magisk günlükleri boş, bu tuhaf</string>
<string name="menuSaveLog">Günlüğü kaydet</string>
<string name="menuClearLog">Günlüğü şimdi temizle</string>
<string name="logs_cleared">Günlük kaydı başarıyla temizlendi</string>
<string name="log_data_none">Günlüğünüz temiz. Root uygulamalarınızı daha fazla kullanmayı deneyin.</string>
<string name="log_data_magisk_none">Magisk günlükleri boş, bu garip.</string>
<string name="menuSaveLog">Günlüğü Kaydet</string>
<string name="menuClearLog">Günlüğü Şimdi Temizle</string>
<string name="logs_cleared">Günlük başarıyla temizlendi</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Hedef UID: %1$d</string>
<string name="target_pid">Mount ns hedef PID: %s</string>
<string name="target_pid">Hedef PID: %s</string>
<string name="selinux_context">SELinux bağlamı: %s</string>
<string name="supp_group">Ek grup: %s</string>
<!--SafetyNet-->
<!--MagiskHide-->
<string name="show_system_app">Sistem uygulamalarını göster</string>
<string name="show_os_app">İşletim sistemi uygulamalarını göster</string>
<string name="hide_filter_hint">İsme göre filtrele</string>
<string name="show_system_app">Sistem Uygulamalarını Göster</string>
<string name="show_os_app">İS Uygulamalarını Göster</string>
<string name="hide_filter_hint">Ada göre filtrele</string>
<string name="hide_search">Ara</string>
<!--Module-->
<string name="no_info_provided">(Bilgi verilmedi)</string>
<string name="reboot_userspace">Hızlı yeniden başlat</string>
<string name="reboot_recovery">Kurtarma modunda yeniden başlat</string>
<string name="reboot_bootloader">Önyükleyici modunda yeniden başlat</string>
<string name="reboot_download">İndirme modunda yeniden başlat</string>
<string name="reboot_edl">EDL modunda yeniden başlat</string>
<string name="reboot_safe_mode">Güvenli mod</string>
<string name="module_version_author">%1$s / %2$s</string>
<string name="no_info_provided">(Bilgi sağlanmadı)</string>
<string name="reboot_userspace">Hızlı Yeniden Başlat</string>
<string name="reboot_recovery">Kurtarma Modunda Yeniden Başlat</string>
<string name="reboot_bootloader">Önyükleyici Modunda Yeniden Başlat</string>
<string name="reboot_download">Download Modunda Yeniden Başlat</string>
<string name="reboot_edl">EDL Modunda Yeniden Başlat</string>
<string name="reboot_safe_mode">Güvenli Mod</string>
<string name="module_version_author">%1$s, Geliştirici: %2$s</string>
<string name="module_state_remove">Kaldır</string>
<string name="module_action">Eylem</string>
<string name="module_state_restore">Geri Yükle</string>
<string name="module_action_install_external">Depolamadan yükle</string>
<string name="update_available">Güncelleme Mevcut</string>
<string name="update_available">Güncelleme mevcut</string>
<string name="suspend_text_riru">Modül, %1$s etkin olduğu için askıya alındı</string>
<string name="suspend_text_zygisk">Modül, %1$s etkin olmadığı için askıya alındı</string>
<string name="zygisk_module_unloaded">Uyumsuzluk nedeniyle Zygisk modülü yüklenmedi</string>
<string name="zygisk_module_unloaded">Zygisk modülü uyumsuzluk nedeniyle yüklenmedi</string>
<string name="module_empty">Yüklü modül yok</string>
<string name="confirm_install">%1$s modülü yüklensin mi?</string>
<string name="confirm_install_title">Yükleme Onayı</string>
@@ -127,121 +125,125 @@
<string name="settings_dark_mode_dark">Her Zaman Karanlık</string>
<string name="settings_download_path_title">İndirme Yolu</string>
<string name="settings_download_path_message">Dosyalar %1$s konumuna kaydedilecek</string>
<string name="settings_hide_app_title">Magisk uygulamasını gizle</string>
<string name="settings_hide_app_summary">Rastgele bir paket kimliği ve özel uygulama etiketi olan bir vekil (proxy) uygulaması yükleyin</string>
<string name="settings_restore_app_title">Magisk uygulamasını geri yükle</string>
<string name="settings_restore_app_summary">Uygulamayı göster ve orijinal APK\'yı geri yükle</string>
<string name="settings_hide_app_title">Magisk Uygulamasını Gizle</string>
<string name="settings_hide_app_summary">Rastgele bir paket kimliği ve özel uygulama etiketi ile bir proxy uygulaması yükleyin</string>
<string name="settings_restore_app_title">Magisk Uygulamasını Geri Yükle</string>
<string name="settings_restore_app_summary">Uygulamanın gizliliğini kaldırın ve orijinal APK\'yi geri yükleyin</string>
<string name="language">Dil</string>
<string name="system_default">(Sistem Varsayılanı)</string>
<string name="settings_check_update_title">Güncellemeleri Kontrol Et</string>
<string name="settings_check_update_summary">Arka planda düzenli olarak güncellemeleri kontrol et</string>
<string name="settings_check_update_summary">Arka planda periyodik olarak güncellemeleri kontrol et</string>
<string name="settings_update_channel_title">Güncelleme Kanalı</string>
<string name="settings_update_stable">Kararlı</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_debug">Hata Ayıklama</string>
<string name="settings_update_custom">Özel</string>
<string name="settings_update_custom_msg">Özel kanal URL\'si girin</string>
<string name="settings_zygisk_summary">Magisk\'in bazı bölümlerini zygote daemon\'unda çalıştır</string>
<string name="settings_denylist_title">Reddetme Listesini Zorla</string>
<string name="settings_denylist_summary">Reddetme Listesindeki işlemler tüm Magisk değişikliklerini geri alacak</string>
<string name="settings_denylist_config_title">Reddetme Listesini Yapılandır</string>
<string name="settings_denylist_config_summary">Reddetme Listesine dahil edilecek işlemleri seçin</string>
<string name="settings_hosts_title">Sistemsiz ana makineler (systemless hosts)</string>
<string name="settings_hosts_summary">Reklam engelleme uygulamaları için sistemsiz ana makineler (systemless hosts) desteği</string>
<string name="settings_hosts_toast">Sistemsiz ana makineler (systemless hosts) modülü eklendi</string>
<string name="settings_update_custom_msg">Özel bir kanal URL\'si girin</string>
<string name="settings_zygisk_summary">Magisk\'in bazı kısımlarını Zygote daemon içinde çalıştırın</string>
<string name="settings_denylist_title">Red Listesini Uygula</string>
<string name="settings_denylist_summary">Red listesindeki işlemlerin tüm Magisk değişiklikleri geri alınacak</string>
<string name="settings_denylist_config_title">Red Listesini Yapılandır</string>
<string name="settings_denylist_config_summary">Red listesine dahil edilecek işlemleri seçin</string>
<string name="settings_hosts_title">Sistemsiz Hosts</string>
<string name="settings_hosts_summary">Reklam engelleme uygulamaları için sistemsiz hosts desteği</string>
<string name="settings_hosts_toast">Sistemsiz hosts modülü eklendi</string>
<string name="settings_app_name_hint">Yeni ad</string>
<string name="settings_app_name_helper">Uygulama bu isimle yeniden paketlenecek</string>
<string name="settings_app_name_helper">Uygulama bu adla yeniden paketlenecek</string>
<string name="settings_app_name_error">Geçersiz format</string>
<string name="settings_su_app_adb">Uygulamalar ve ADB</string>
<string name="settings_su_app">Sadece Uygulamalar</string>
<string name="settings_su_adb">Sadece ADB</string>
<string name="settings_su_disable">Devre Dışı</string>
<string name="settings_su_request_10">10 saniye</string>
<string name="settings_su_request_15">15 saniye</string>
<string name="settings_su_request_20">20 saniye</string>
<string name="settings_su_request_30">30 saniye</string>
<string name="settings_su_request_45">45 saniye</string>
<string name="settings_su_request_60">60 saniye</string>
<string name="settings_su_request_10">10 Saniye</string>
<string name="settings_su_request_15">15 Saniye</string>
<string name="settings_su_request_20">20 Saniye</string>
<string name="settings_su_request_30">30 Saniye</string>
<string name="settings_su_request_45">45 Saniye</string>
<string name="settings_su_request_60">60 Saniye</string>
<string name="superuser_access">Süper Kullanıcı Erişimi</string>
<string name="auto_response">Otomatik Yanıt</string>
<string name="request_timeout">İstek Zaman Aşımı</string>
<string name="superuser_notification">Süper Kullanıcı Bildirimi</string>
<string name="settings_su_reauth_title">Yükseltme sonrası yeniden doğrulama yap</string>
<string name="settings_su_reauth_summary">Uygulama güncellemelerinden sonra Süper Kullanıcı izinlerini tekrar iste</string>
<string name="settings_su_tapjack_title">Tapjacking Koruması</string>
<string name="settings_su_tapjack_summary">Süper Kullanıcı istemi diyalogu, başka bir pencere veya katman tarafından gizlendiğinde girdilere yanıt vermeyecektir</string>
<string name="settings_su_auth_title">Kullanıcı Kimlik Doğrulama</string>
<string name="settings_su_auth_summary">Süper Kullanıcı isteklerinde kullanıcı kimlik doğrulaması iste</string>
<string name="settings_su_reauth_title">Yükseltmeden Sonra Yeniden Kimlik Doğrula</string>
<string name="settings_su_reauth_summary">Uygulamaları yükselttikten sonra tekrar Süper Kullanıcı izinlerini iste</string>
<string name="settings_su_tapjack_title">Dokunma Saldırısı Koruması</string>
<string name="settings_su_tapjack_summary">Süper Kullanıcı istek penceresi, başka bir pencere veya katman tarafından engellendiğinde girdilere yanıt vermeyecektir</string>
<string name="settings_su_auth_title">Kullanıcı Kimlik Doğrulaması</string>
<string name="settings_su_auth_summary">Süper Kullanıcı istekleri sırasında kullanıcı kimlik doğrulaması iste</string>
<string name="settings_su_auth_insecure">Cihazda yapılandırılmış bir kimlik doğrulama yöntemi yok</string>
<string name="settings_customization">Özelleştir</string>
<string name="setting_add_shortcut_summary">Uygulamayı gizledikten sonra adı ve simgeyi tanımakta zorlanıyorsanız ana ekrana güzel bir kısayol ekle</string>
<string name="settings_doh_title">DNS üzerinden HTTPS</string>
<string name="settings_doh_description">Bazı ülkelerde DNS zehirlemesine karşı geçici çözüm</string>
<string name="settings_random_name_title">Çıkış adını rastgele seç</string>
<string name="settings_random_name_description">Algılamayı önlemek için yamalı resimlerin ve tar dosyalarının çıkış dosya adını rastgele seç</string>
<string name="multiuser_mode">Çok Kullanıcılı Mod</string>
<string name="settings_owner_only">Yalnızca Cihaz Sahibi</string>
<string name="settings_owner_manage">Cihaz Sahibi Yönetiminde</string>
<string name="settings_su_restrict_title">Root Yeteneklerini Kısıtla</string>
<string name="settings_su_restrict_summary">Yeni Süper Kullanıcı uygulamalarını varsayılan olarak kısıtlayacaktır. Uyarı: Bu, çoğu uygulamayı bozacaktır. Ne yaptığınızı bilmiyorsanız etkinleştirmeyin.</string>
<string name="settings_customization">Özelleştirme</string>
<string name="setting_add_shortcut_summary">Uygulamayı gizledikten sonra adı ve simgesi tanınması zor olursa ana ekrana güzel bir kısayol ekleyin</string>
<string name="settings_doh_title">HTTPS üzerinden DNS</string>
<string name="settings_doh_description">Bazı ülkelerdeki DNS zehirlenmesini aşmak için geçici çözüm</string>
<string name="settings_random_name_title">Çıktı Adını Rastgele Yap</string>
<string name="settings_random_name_description">Tespit edilmesini önlemek için yamalanmış imajların ve tar dosyalarının çıktı dosya adını rastgele yapın</string>
<string name="multiuser_mode">Çoklu Kullanıcı Modu</string>
<string name="settings_owner_only">Sadece Cihaz Sahibi</string>
<string name="settings_owner_manage">Cihaz Sahibi Tarafından Yönetilen</string>
<string name="settings_user_independent">Kullanıcıdan Bağımsız</string>
<string name="owner_only_summary">Yalnızca sahip kök (root) erişimine sahiptir</string>
<string name="owner_manage_summary">Yalnızca sahip kök (root) erişimini yönetebilir ve istek uyarılarını alabilir</string>
<string name="user_independent_summary">Her kullanıcının kendi ayrı kök (root) kuralları vardır</string>
<string name="owner_only_summary">Sadece cihaz sahibi root erişimine sahiptir</string>
<string name="owner_manage_summary">Sadece cihaz sahibi root erişimini yönetebilir ve istekleri alabilir</string>
<string name="user_independent_summary">Her kullanıcının kendi ayrı root kuralları vardır</string>
<string name="mount_namespace_mode">Bağlama Ad Alanı Modu</string>
<string name="settings_ns_global">Küresel Ad Alanı</string>
<string name="settings_ns_global">Genel Ad Alanı</string>
<string name="settings_ns_requester">Ad Alanını Devral</string>
<string name="settings_ns_isolate">İzolasyon Ad Alanı</string>
<string name="global_summary">Tüm kök (root) oturumları küresel bağlama ad alanını kullanır</string>
<string name="requester_summary">Kök (root) oturumları isteyicisinin ad alanını devralacak</string>
<string name="isolate_summary">Her kök (root) oturumu kendi izole ad alanına sahip olacak</string>
<string name="settings_ns_isolate">Yalıtılmış Ad Alanı</string>
<string name="global_summary">Tüm root oturumları genel bağlama ad alanını kullanır</string>
<string name="requester_summary">Root oturumları, istekçilerinin ad alanını devralır</string>
<string name="isolate_summary">Her root oturumunun kendi yalıtılmış ad alanı olacaktır</string>
<!--Notifications-->
<string name="update_channel">Magisk Güncellemeleri</string>
<string name="progress_channel">İlerleme Bildirimleri</string>
<string name="updated_channel">Güncelleme Tamamlandı</string>
<string name="update_channel">Magisk güncellemeleri</string>
<string name="progress_channel">İlerleme bildirimleri</string>
<string name="updated_channel">Güncelleme tamamlandı</string>
<string name="download_complete">İndirme tamamlandı</string>
<string name="download_file_error">Dosya indirilirken hata oluştu</string>
<string name="magisk_update_title">Magisk Güncellemesi Mevcut!</string>
<string name="updated_title">Magisk Güncellendi</string>
<string name="magisk_update_title">Magisk güncellemesi mevcut!</string>
<string name="updated_title">Magisk güncellendi</string>
<string name="updated_text">Uygulamayı açmak için dokunun</string>
<!--Toasts, Dialogs-->
<string name="yes">Mevcut</string>
<string name="no">Mevcut Değil</string>
<string name="repo_install_title">%1$s %2$s(%3$d) Kur</string>
<string name="yes">Evet</string>
<string name="no">Hayır</string>
<string name="repo_install_title">%1$s %2$s(%3$d) Yüklensin mi?</string>
<string name="download">İndir</string>
<string name="reboot">Yeniden Başlat</string>
<string name="close">Kapat</string>
<string name="release_notes">Sürüm Notları</string>
<string name="flashing">Yükleniyor...</string>
<string name="done">Tamamlandı!</string>
<string name="flashing">Flaşlanıyor…</string>
<string name="running">Çalışıyor…</string>
<string name="done">Bitti!</string>
<string name="done_action">%1$s eylemi tamamlandı</string>
<string name="failure">Başarısız!</string>
<string name="hide_app_title">Magisk uygulaması gizleniyor…</string>
<string name="open_link_failed_toast">Bağlantıyımak için uygulama bulunamadı</string>
<string name="open_link_failed_toast">Bağlantıyıacak bir uygulama bulunamadı</string>
<string name="complete_uninstall">Tamamen Kaldır</string>
<string name="restore_img">Görüntüleri Geri Yükle</string>
<string name="restore_img_msg">Geri Yükleniyor...</string>
<string name="restore_img">İmajları Geri Yükle</string>
<string name="restore_img_msg">Geri yükleniyor</string>
<string name="restore_done">Geri yükleme tamamlandı!</string>
<string name="restore_fail">Stok yedeği mevcut değil!</string>
<string name="setup_fail">Kurulum başarısız oldu</string>
<string name="env_fix_title">Ek Ayar Gerekiyor</string>
<string name="env_fix_msg">Magisk\'in düzgün çalışabilmesi için cihazınızın ek ayarlar yapması gerekiyor. Devam etmek ve yeniden başlatmak istiyor musunuz?</string>
<string name="env_full_fix_msg">Cihazınızın düzgün çalışabilmesi için Magisk\'in yeniden yüklenmesi gerekiyor. Lütfen Magisk\'i uygulama içinde yeniden yükleyin, kurtarma modu doğru cihaz bilgilerini alamaz.</string>
<string name="setup_msg">Ortam kurulumu yapılıyor...</string>
<string name="env_fix_title">Ek Kurulum Gerektiriyor</string>
<string name="env_fix_msg">Cihazınızın Magisk\'in düzgün çalışması için ek kuruluma ihtiyacı var. Devam edip yeniden başlatmak ister misiniz?</string>
<string name="env_full_fix_msg">Cihazınızın düzgün çalışması için Magisk\'i yeniden flaşlamanız gerekiyor. Lütfen Magisk\'i uygulama içinden yeniden kurun, Kurtarma modu doğru cihaz bilgisini alamaz.</string>
<string name="setup_msg">Çalışma ortamı kuruluyor…</string>
<string name="unsupport_magisk_title">Desteklenmeyen Magisk Sürümü</string>
<string name="unsupport_magisk_msg">Bu uygulama sürümü, %1$s altındaki Magisk sürümlerini desteklemiyor.\n\nUygulama, Magisk yüklü değilmiş gibi davranacaktır, lütfen en kısa sürede Magisk\'i güncelleyin.</string>
<string name="unsupport_magisk_msg">Uygulamanın bu sürümü, %1$s sürümünden daha düşük Magisk sürümlerini desteklemiyor.\n\nUygulama, Magisk yüklü değilmiş gibi davranacaktır. Lütfen Magisk\'i en kısa sürede güncelleyin.</string>
<string name="unsupport_general_title">Anormal Durum</string>
<string name="unsupport_system_app_msg">Bu uygulamanın sistem uygulaması olarak çalıştırılması desteklenmiyor. Lütfen uygulamayı kullanıcı uygulamasına geri döndürün.</string>
<string name="unsupport_other_su_msg">Magisk\'ten gelmeyen bir "su" ikili dosyası tespit edildi. Lütfen herhangi bir rakip kök (root) çözümünü kaldırın ve/veya Magisk\'i yeniden yükleyin.</string>
<string name="unsupport_external_storage_msg">Magisk harici depolamaya yüklendi. Lütfen uygulamayı dahili depolamaya taşıyın.</string>
<string name="unsupport_nonroot_stub_msg">Gizli Magisk uygulaması kök (root) erişimi kaybolduğu için çalışmaya devam edemez. Lütfen orijinal APK\'yı geri yükleyin.</string>
<string name="unsupport_system_app_msg">Bu uygulamanın bir sistem uygulaması olarak çalıştırılması desteklenmiyor. Lütfen uygulamayı bir kullanıcı uygulamasına geri döndürün.</string>
<string name="unsupport_other_su_msg">Magisk\'e ait olmayan bir "su" ikili dosyası tespit edildi. Lütfen rakip root çözümlerini kaldırın ve/veya Magisk\'i yeniden yükleyin.</string>
<string name="unsupport_external_storage_msg">Magisk harici depolamaya kurulmuş. Lütfen uygulamayı dahili depolamaya taşıyın.</string>
<string name="unsupport_nonroot_stub_msg">Gizlenmiş Magisk uygulaması, root kaybolduğu için çalışmaya devam edemiyor. Lütfen orijinal APK\'yi geri yükleyin.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Bu işlevselliği etkinleştirmek için depolama izni verin</string>
<string name="post_notifications_denied">Bu işlevselliği etkinleştirmek için bildirim izni verin</string>
<string name="install_unknown_denied">Bu işlevselliği etkinleştirmek için "bilinmeyen uygulamaları yükle" iznini verin</string>
<string name="add_shortcut_title">Ana ekrana kısayol ekle</string>
<string name="add_shortcut_msg">Bu uygulamayı gizledikten sonra adı ve simgesi tanınmayabilir. Ana ekrana güzel bir kısayol eklemek ister misiniz?</string>
<string name="app_not_found">Bu lemi gerçekleştirecek uygulama bulunamadı</string>
<string name="external_rw_permission_denied">Bu işlevi etkinleştirmek için depolama izni verin</string>
<string name="post_notifications_denied">Bu işlevi etkinleştirmek için bildirim izni verin</string>
<string name="install_unknown_denied">Bu işlevi etkinleştirmek için "Bilinmeyen uygulamaları yükle" iznini verin</string>
<string name="add_shortcut_title">Ana Ekrana Kısayol Ekle</string>
<string name="add_shortcut_msg">Bu uygulamayı gizledikten sonra adı ve simgesi tanınması zor olabilir. Ana ekrana güzel bir kısayol eklemek ister misiniz?</string>
<string name="app_not_found">Bu eylemi gerçekleştirecek bir uygulama bulunamadı</string>
<string name="reboot_apply_change">Değişiklikleri uygulamak için yeniden başlatın</string>
<string name="restore_app_confirmation">Bu, gizli uygulamayı orijinal uygulamaya geri yükleyecektir. Gerçekten bunu yapmak istiyor musunuz?</string>
<string name="restore_app_confirmation">Bu, gizlenmiş uygulamayı orijinal uygulamaya geri yükleyecektir. Bunu gerçekten yapmak istiyor musunuz?</string>
</resources>

View File

@@ -0,0 +1,234 @@
<resources>
<string name="modules">ماڈیولز</string>
<string name="superuser">سپر یوزر</string>
<string name="logs">لاگز</string>
<string name="settings">سیٹنگز</string>
<string name="install">انسٹال کریں</string>
<string name="section_home">ہوم</string>
<string name="section_theme">تھیمز</string>
<string name="denylist">مسترد فہرست</string>
<string name="no_connection">کوئی کنکشن دستیاب نہیں</string>
<string name="app_changelog">ایپ چینج لاگ</string>
<string name="loading">لوڈ ہو رہا ہے…</string>
<string name="update">اپ ڈیٹ</string>
<string name="not_available">دستیاب نہیں</string>
<string name="hide">چھپائیں</string>
<string name="home_package">پیکیج</string>
<string name="home_app_title">ایپ</string>
<string name="home_notice_content">صرف آفیشل گٹ ہب پیج سے Magisk ڈاؤن لوڈ کریں۔ نامعلوم ذرائع سے فائلیں نقصان دہ ہو سکتی ہیں!</string>
<string name="home_support_title">ہماری مدد کریں</string>
<string name="home_follow_title">ہمیں فالو کریں</string>
<string name="home_item_source">ذریعہ</string>
<string name="home_support_content">Magisk ہمیشہ مفت اور اوپن سورس رہے گا۔ تاہم، آپ عطیہ کر کے ہمیں اپنی دیکھ بھال کا اظہار کر سکتے ہیں۔</string>
<string name="home_installed_version">انسٹال شدہ</string>
<string name="home_latest_version">تازہ ترین</string>
<string name="invalid_update_channel">غلط اپ ڈیٹ چینل</string>
<string name="uninstall_magisk_title">Magisk اَن انسٹال کریں</string>
<string name="uninstall_magisk_msg">تمام ماڈیولز غیر فعال/ہٹا دیے جائیں گے!\nروٹ ہٹا دیا جائے گا!\nMagisk کے استعمال کے ذریعے غیر اینکرپٹ کی گئی کوئی بھی اندرونی اسٹوریج دوبارہ اینکرپٹ ہو جائے گی!</string>
<string name="keep_force_encryption">جبری انکرپشن کو محفوظ رکھیں</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity کو محفوظ رکھیں</string>
<string name="recovery_mode">ریکوری موڈ</string>
<string name="install_options_title">آپشنز</string>
<string name="install_method_title">طریقہ</string>
<string name="install_next">اگلا</string>
<string name="install_start">چلو شروع کرتے ہیں</string>
<string name="manager_download_install">ڈاؤن لوڈ اور انسٹال کرنے کے لیے دبائیں</string>
<string name="direct_install">براہ راست انسٹال (تجویز کردہ)</string>
<string name="install_inactive_slot">غیر فعال سلاٹ میں انسٹال کریں (OTA کے بعد)</string>
<string name="install_inactive_slot_msg">ریبوٹ کے بعد آپ کا آلہ زبردستی موجودہ غیر فعال سلاٹ میں بوٹ ہو جائے گا!\nیہ آپشن صرف OTA مکمل ہونے کے بعد استعمال کریں۔\nجاری رکھیں؟</string>
<string name="setup_title">اضافی سیٹ اپ</string>
<string name="select_patch_file">پیچ فائل منتخب اور پیچ کریں</string>
<string name="patch_file_msg">ایک خام امیج (*.img) یا ایک ODIN ٹار فائل (*.tar) یا ایک payload.bin (*.bin) منتخب کریں</string>
<string name="reboot_delay_toast">5 سیکنڈ میں ریبوٹ ہو رہا ہے…</string>
<string name="flash_screen_title">انسٹالیشن</string>
<string name="su_request_title">سپر یوزر کی درخواست</string>
<string name="touch_filtered_warning">چونکہ ایک ایپ سپر یوزر کی درخواست کو دھندلا کر رہی ہے، اس لیے Magisk آپ کے جواب کی تصدیق نہیں کر سکتا</string>
<string name="deny">منع کریں</string>
<string name="prompt">پوچھیں</string>
<string name="grant">اجازت دیں</string>
<string name="su_warning">اپنے آلے تک مکمل رسائی کی اجازت دیں۔\nاگر آپ کو یقین نہیں ہے تو منع کریں!</string>
<string name="forever">ہمیشہ کے لیے</string>
<string name="once">ایک بار</string>
<string name="tenmin">10 منٹ</string>
<string name="twentymin">20 منٹ</string>
<string name="thirtymin">30 منٹ</string>
<string name="sixtymin">60 منٹ</string>
<string name="su_allow_toast">%1$s کو سپر یوزر کے حقوق دیئے گئے</string>
<string name="su_deny_toast">%1$s کو سپر یوزر کے حقوق سے انکار کر دیا گیا</string>
<string name="su_snack_grant">%1$s کے سپر یوزر حقوق دیئے گئے</string>
<string name="su_snack_deny">%1$s کے سپر یوزر حقوق سے انکار کر دیا گیا</string>
<string name="su_snack_notif_on">%1$s کی اطلاعات فعال ہیں</string>
<string name="su_snack_notif_off">%1$s کی اطلاعات غیر فعال ہیں</string>
<string name="su_snack_log_on">%1$s کی لاگنگ فعال ہے</string>
<string name="su_snack_log_off">%1$s کی لاگنگ غیر فعال ہے</string>
<string name="su_revoke_title">منسوخ کریں؟</string>
<string name="su_revoke_msg">%1$s کے سپر یوزر حقوق منسوخ کرنے کی تصدیق کریں</string>
<string name="toast">ٹوسٹ</string>
<string name="none">کوئی نہیں</string>
<string name="superuser_toggle_notification">اطلاعات</string>
<string name="superuser_toggle_revoke">منسوخ کریں</string>
<string name="superuser_policy_none">ابھی تک کسی ایپ نے سپر یوزر کی اجازت نہیں مانگی ہے۔</string>
<string name="log_data_none">آپ لاگ فری ہیں، اپنی روٹ ایپس کو مزید استعمال کرنے کی کوشش کریں</string>
<string name="log_data_magisk_none">Magisk لاگز خالی ہیں، یہ عجیب بات ہے</string>
<string name="menuSaveLog">لاگ محفوظ کریں</string>
<string name="menuClearLog">ابھی لاگ صاف کریں</string>
<string name="logs_cleared">لاگ کامیابی سے صاف ہو گیا</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">ٹارگٹ UID: %1$d</string>
<string name="target_pid">ماؤنٹ این ایس ٹارگٹ PID: %s</string>
<string name="selinux_context">SELinux سیاق و سباق: %s</string>
<string name="supp_group">اضافی گروپ: %s</string>
<string name="show_system_app">سسٹم ایپس دکھائیں</string>
<string name="show_os_app">OS ایپس دکھائیں</string>
<string name="hide_filter_hint">نام سے فلٹر کریں</string>
<string name="hide_search">تلاش کریں</string>
<string name="no_info_provided">(کوئی معلومات فراہم نہیں کی گئی)</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="reboot_safe_mode">محفوظ موڈ</string>
<string name="module_version_author">%2$s کی جانب سے %1$s</string>
<string name="module_state_remove">ہٹائیں</string>
<string name="module_state_restore">بحال کریں</string>
<string name="module_action_install_external">اسٹوریج سے انسٹال کریں</string>
<string name="update_available">اپ ڈیٹ دستیاب ہے</string>
<string name="suspend_text_riru">ماڈیول معطل کر دیا گیا کیونکہ %1$s فعال ہے</string>
<string name="suspend_text_zygisk">ماڈیول معطل کر دیا گیا کیونکہ %1$s فعال نہیں ہے</string>
<string name="zygisk_module_unloaded">غیر مطابقت کی وجہ سے Zygisk ماڈیول لوڈ نہیں ہوا</string>
<string name="module_empty">کوئی ماڈیول انسٹال نہیں ہے</string>
<string name="confirm_install">ماڈیول %1$s انسٹال کریں؟</string>
<string name="confirm_install_title">انسٹالیشن کی تصدیق</string>
<string name="settings_dark_mode_title">تھیم موڈ</string>
<string name="settings_dark_mode_message">وہ موڈ منتخب کریں جو آپ کے انداز کے مطابق ہو!</string>
<string name="settings_dark_mode_light">ہمیشہ لائٹ</string>
<string name="settings_dark_mode_system">سسٹم کی پیروی کریں</string>
<string name="settings_dark_mode_dark">ہمیشہ ڈارک</string>
<string name="settings_download_path_title">ڈاؤن لوڈ کا راستہ</string>
<string name="settings_download_path_message">فائلیں %1$s میں محفوظ کی جائیں گی</string>
<string name="settings_hide_app_title">Magisk ایپ کو چھپائیں</string>
<string name="settings_hide_app_summary">ایک رینڈم پیکیج ID اور کسٹم ایپ لیبل کے ساتھ ایک پراکسی ایپ انسٹال کریں</string>
<string name="settings_restore_app_title">Magisk ایپ کو بحال کریں</string>
<string name="settings_restore_app_summary">ایپ کو ان ہائیڈ کریں اور اصل APK کو بحال کریں</string>
<string name="language">زبان</string>
<string name="system_default">(سسٹم ڈیفالٹ)</string>
<string name="settings_check_update_title">اپ ڈیٹس چیک کریں</string>
<string name="settings_check_update_summary">وقفے وقفے سے پس منظر میں اپ ڈیٹس چیک کریں</string>
<string name="settings_update_channel_title">اپ ڈیٹ چینل</string>
<string name="settings_update_stable">مستحکم</string>
<string name="settings_update_beta">بیٹا</string>
<string name="settings_update_custom">کسٹم</string>
<string name="settings_update_custom_msg">ایک کسٹم چینل URL درج کریں</string>
<string name="settings_zygisk_summary">zygote ڈیمن میں Magisk کے کچھ حصے چلائیں</string>
<string name="settings_denylist_title">مسترد فہرست نافذ کریں</string>
<string name="settings_denylist_summary">مسترد فہرست میں موجود عملوں میں Magisk کی تمام ترامیم کو کالعدم قرار دیا جائے گا</string>
<string name="settings_denylist_config_title">مسترد فہرست کی تشکیل کریں</string>
<string name="settings_denylist_config_summary">مسترد فہرست میں شامل کرنے کے لیے عمل منتخب کریں</string>
<string name="settings_hosts_title">سسٹم لیس ہوسٹس</string>
<string name="settings_hosts_summary">ایڈ بلاکنگ ایپس کے لیے سسٹم لیس ہوسٹس سپورٹ</string>
<string name="settings_hosts_toast">سسٹم لیس ہوسٹس ماڈیول شامل کیا گیا</string>
<string name="settings_app_name_hint">نیا نام</string>
<string name="settings_app_name_helper">ایپ کو اس نام سے دوبارہ پیک کیا جائے گا</string>
<string name="settings_app_name_error">غلط فارمیٹ</string>
<string name="settings_su_app_adb">ایپس اور ADB</string>
<string name="settings_su_app">صرف ایپس</string>
<string name="settings_su_adb">صرف ADB</string>
<string name="settings_su_disable">غیر فعال</string>
<string name="settings_su_request_10">10 سیکنڈ</string>
<string name="settings_su_request_15">15 سیکنڈ</string>
<string name="settings_su_request_20">20 سیکنڈ</string>
<string name="settings_su_request_30">30 سیکنڈ</string>
<string name="settings_su_request_45">45 سیکنڈ</string>
<string name="settings_su_request_60">60 سیکنڈ</string>
<string name="superuser_access">سپر یوزر تک رسائی</string>
<string name="auto_response">خودکار جواب</string>
<string name="request_timeout">درخواست کا وقت ختم</string>
<string name="superuser_notification">سپر یوزر اطلاع</string>
<string name="settings_su_reauth_title">اپ گریڈ کے بعد دوبارہ تصدیق کریں</string>
<string name="settings_su_reauth_summary">ایپس کو اپ گریڈ کرنے کے بعد دوبارہ سپر یوزر کی اجازتیں مانگیں</string>
<string name="settings_su_tapjack_title">ٹیپ جیکنگ سے تحفظ</string>
<string name="settings_su_tapjack_summary">سپر یوزر پرامپٹ ڈائیلاگ کسی دوسری ونڈو یا اوورلے سے دھندلا ہونے کے دوران ان پٹ کا جواب نہیں دے گا</string>
<string name="settings_su_auth_title">صارف کی تصدیق</string>
<string name="settings_su_auth_summary">سپر یوزر کی درخواستوں کے دوران صارف کی تصدیق طلب کریں</string>
<string name="settings_su_auth_insecure">آلے پر کوئی تصدیقی طریقہ کار تشکیل نہیں دیا گیا ہے</string>
<string name="settings_customization">حسب ضرورت سازی</string>
<string name="setting_add_shortcut_summary">اگر ایپ کو چھپانے کے بعد اس کا نام اور آئیکن پہچاننا مشکل ہو جائے تو ہوم اسکرین پر ایک خوبصورت شارٹ کٹ شامل کریں</string>
<string name="settings_doh_title">HTTPS پر DNS</string>
<string name="settings_doh_description">بعض ممالک میں DNS زہر آلودگی کا حل</string>
<string name="settings_random_name_title">بے ترتیب آؤٹ پٹ نام</string>
<string name="settings_random_name_description">پتہ لگانے سے بچنے کے لیے پیچ شدہ امیجز اور ٹار فائلوں کے آؤٹ پٹ فائل کے نام کو بے ترتیب بنائیں</string>
<string name="multiuser_mode">ملٹی یوزر موڈ</string>
<string name="settings_owner_only">صرف آلہ کا مالک</string>
<string name="settings_owner_manage">آلہ کے مالک کے زیر انتظام</string>
<string name="settings_user_independent">صارف سے آزاد</string>
<string name="owner_only_summary">صرف مالک کو روٹ تک رسائی حاصل ہے</string>
<string name="owner_manage_summary">صرف مالک روٹ تک رسائی کا انتظام کر سکتا ہے اور درخواست کے اشارے وصول کر سکتا ہے</string>
<string name="user_independent_summary">ہر صارف کے اپنے علیحدہ روٹ کے قواعد ہیں</string>
<string name="mount_namespace_mode">ماؤنٹ نیم اسپیس موڈ</string>
<string name="settings_ns_global">عالمی نیم اسپیس</string>
<string name="settings_ns_requester">نیم اسپیس وراثت میں حاصل کریں</string>
<string name="settings_ns_isolate">آئسولیٹڈ نیم اسپیس</string>
<string name="isolate_summary">ہر روٹ سیشن کی اپنی آئسولیٹڈ نیم اسپیس ہوگی</string>
<string name="update_channel">Magisk اپ ڈیٹس</string>
<string name="progress_channel">پیش رفت کی اطلاعات</string>
<string name="updated_channel">اپ ڈیٹ مکمل</string>
<string name="download_complete">ڈاؤن لوڈ مکمل</string>
<string name="download_file_error">فائل ڈاؤن لوڈ کرنے میں خرابی</string>
<string name="magisk_update_title">Magisk اپ ڈیٹ دستیاب ہے!</string>
<string name="updated_title">Magisk اپ ڈیٹ ہو گیا</string>
<string name="updated_text">ایپ کھولنے کے لیے ٹیپ کریں</string>
<string name="yes">ہاں</string>
<string name="no">نہیں</string>
<string name="repo_install_title">%1$s %2$s (%3$d) انسٹال کریں</string>
<string name="download">ڈاؤن لوڈ</string>
<string name="reboot">ریبوٹ</string>
<string name="close">بند کریں</string>
<string name="release_notes">ریلیز نوٹ</string>
<string name="flashing">فلیش ہو رہا ہے…</string>
<string name="done">ہو گیا!</string>
<string name="failure">ناکام!</string>
<string name="hide_app_title">Magisk ایپ کو چھپایا جا رہا ہے…</string>
<string name="open_link_failed_toast">لنک کھولنے کے لیے کوئی ایپ نہیں ملی</string>
<string name="complete_uninstall">مکمل ان انسٹال</string>
<string name="restore_img">تصاویر بحال کریں</string>
<string name="restore_img_msg">بحال ہو رہا ہے…</string>
<string name="restore_done">بحالی مکمل ہو گئی!</string>
<string name="restore_fail">اسٹاک بیک اپ موجود نہیں ہے!</string>
<string name="setup_fail">سیٹ اپ ناکام ہو گیا</string>
<string name="env_full_fix_msg">Magisk کو صحیح طریقے سے کام کرنے کے لیے آپ کے آلے کو دوبارہ فلیش کرنے کی ضرورت ہے۔ براہ کرم ایپ کے اندر Magisk کو دوبارہ انسٹال کریں، ریکوری موڈ درست ڈیوائس کی معلومات حاصل نہیں کر سکتا۔</string>
<string name="env_fix_title">اضافی سیٹ اپ درکار ہے</string>
<string name="env_fix_msg">Magisk کو صحیح طریقے سے کام کرنے کے لیے آپ کے آلے کو اضافی سیٹ اپ کی ضرورت ہے۔ کیا آپ جاری رکھنا چاہتے ہیں اور ریبوٹ کرنا چاہتے ہیں؟</string>
<string name="setup_msg">ماحول کا سیٹ اپ چل رہا ہے…</string>
<string name="unsupport_magisk_title">Magisk کا غیر تعاون یافتہ ورژن</string>
<string name="unsupport_magisk_msg">ایپ کا یہ ورژن %1$s سے کم Magisk ورژنز کو سپورٹ نہیں کرتا ہے۔\n\nایپ ایسے برتاؤ کرے گی جیسے کوئی Magisk انسٹال نہیں ہے، براہ کرم جلد از جلد Magisk کو اپ گریڈ کریں۔</string>
<string name="unsupport_general_title">غیر معمولی حالت</string>
<string name="unsupport_system_app_msg">سسٹم ایپ کے طور پر اس ایپ کو چلانا تعاون یافتہ نہیں ہے۔ براہ کرم ایپ کو صارف ایپ میں واپس کریں۔</string>
<string name="unsupport_other_su_msg">Magisk کے علاوہ کسی اور "su" بائنری کا پتہ چلا ہے۔ براہ کرم کسی بھی مسابقتی روٹ حل کو ہٹا دیں اور/یا Magisk کو دوبارہ انسٹال کریں۔</string>
<string name="unsupport_external_storage_msg">Magisk بیرونی اسٹوریج پر انسٹال ہے۔ براہ کرم ایپ کو اندرونی اسٹوریج میں منتقل کریں۔</string>
<string name="unsupport_nonroot_stub_msg">چھپی ہوئی Magisk ایپ کام جاری نہیں رکھ سکتی کیونکہ روٹ ختم ہو گیا ہے۔ براہ کرم اصل APK کو بحال کریں۔</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">اس فعالیت کو فعال کرنے کے لیے اسٹوریج کی اجازت دیں</string>
<string name="post_notifications_denied">اس فعالیت کو فعال کرنے کے لیے اطلاعات کی اجازت دیں</string>
<string name="install_unknown_denied">اس فعالیت کو فعال کرنے کے لیے "نامعلوم ایپس انسٹال کریں" کی اجازت دیں</string>
<string name="add_shortcut_title">ہوم اسکرین پر شارٹ کٹ شامل کریں</string>
<string name="add_shortcut_msg">اس ایپ کو چھپانے کے بعد، اس کا نام اور آئیکن پہچاننا مشکل ہو سکتا ہے۔ کیا آپ ہوم اسکرین پر ایک خوبصورت شارٹ کٹ شامل کرنا چاہتے ہیں؟</string>
<string name="app_not_found">اس عمل کو سنبھالنے کے لیے کوئی ایپ نہیں ملی</string>
<string name="reboot_apply_change">تبدیلیاں لاگو کرنے کے لیے ریبوٹ کریں</string>
<string name="restore_app_confirmation">یہ چھپی ہوئی ایپ کو اصل ایپ میں بحال کردے گا۔ کیا آپ واقعی ایسا کرنا چاہتے ہیں؟</string>
</resources>

View File

@@ -54,6 +54,7 @@
<string name="touch_filtered_warning">由于某个应用遮挡了超级用户请求界面,因此 Magisk 无法验证您的回应</string>
<string name="deny">拒绝</string>
<string name="prompt">提示</string>
<string name="restrict">受限</string>
<string name="grant">允许</string>
<string name="su_warning">将授予对该设备的最高权限。\n如果不确定请拒绝</string>
<string name="forever">永久</string>
@@ -173,6 +174,8 @@
<string name="settings_su_auth_title">身份验证</string>
<string name="settings_su_auth_summary">对超级用户请求验证身份</string>
<string name="settings_su_auth_insecure">设备未配置验证方式</string>
<string name="settings_su_restrict_title">限制超级用户权能</string>
<string name="settings_su_restrict_summary">默认限制新的超级用户应用。警告,这会破坏大多数应用,不建议启用。</string>
<string name="settings_customization">个性化</string>
<string name="setting_add_shortcut_summary">在隐藏后难以识别名称和图标的情况下,添加快捷方式到桌面</string>
<string name="settings_doh_title">安全 DNSDoH</string>

View File

@@ -63,9 +63,7 @@
<string-array name="update_channel">
<item>@string/settings_update_stable</item>
<item>@string/settings_update_beta</item>
<item>@string/settings_update_debug</item>
<item>@string/settings_update_custom</item>
<item>Canary</item>
<item>Debug</item>
</string-array>
</resources>

View File

@@ -19,41 +19,41 @@
<string name="hide">Hide</string>
<string name="home_package">Package</string>
<string name="home_app_title">App</string>
<string name="home_notice_content">Download Magisk ONLY from the official GitHub page. Files from unknown sources can be malicious!</string>
<string name="home_support_title">Support Us</string>
<string name="home_follow_title">Follow Us</string>
<string name="home_item_source">Source</string>
<string name="home_support_content">Magisk is, and always will be, free, and open source. You can however show us that you care by making a donation.</string>
<string name="home_support_content">Magisk is, and always will be, free, and open source. However, you can show us that you care by making a donation.</string>
<string name="home_installed_version">Installed</string>
<string name="home_latest_version">Latest</string>
<string name="invalid_update_channel">Invalid Update Channel</string>
<string name="invalid_update_channel">Invalid update channel</string>
<string name="uninstall_magisk_title">Uninstall Magisk</string>
<string name="uninstall_magisk_msg">All modules will be disabled/removed!\nRoot will be removed!\nAny internal storage unencrypted through the use of Magisk will be re-encrypted!</string>
<!--Install-->
<string name="keep_force_encryption">Preserve force encryption</string>
<string name="keep_dm_verity">Preserve AVB 2.0/dm-verity</string>
<string name="recovery_mode">Recovery Mode</string>
<string name="recovery_mode">Recovery mode</string>
<string name="install_options_title">Options</string>
<string name="install_method_title">Method</string>
<string name="install_next">Next</string>
<string name="install_start">Let\'s go</string>
<string name="manager_download_install">Press to download and install</string>
<string name="direct_install">Direct Install (Recommended)</string>
<string name="install_inactive_slot">Install to Inactive Slot (After OTA)</string>
<string name="direct_install">Direct install (Recommended)</string>
<string name="install_inactive_slot">Install to inactive slot (After OTA)</string>
<string name="install_inactive_slot_msg">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="setup_title">Additional Setup</string>
<string name="select_patch_file">Select and Patch a File</string>
<string name="setup_title">Additional setup</string>
<string name="select_patch_file">Select and patch a file</string>
<string name="patch_file_msg">Select a raw image (*.img) or an ODIN tarfile (*.tar) or a payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Rebooting in 5 seconds…</string>
<string name="flash_screen_title">Installation</string>
<!--Superuser-->
<string name="su_request_title">Superuser Request</string>
<string name="touch_filtered_warning">Because an app is obscuring a Superuser request, Magisk can\'t verify your response</string>
<string name="su_request_title">Superuser request</string>
<string name="touch_filtered_warning">Because an app is obscuring a Superuser request, Magisk can\'t verify your response.</string>
<string name="deny">Deny</string>
<string name="prompt">Prompt</string>
<string name="restrict">Restrict</string>
<string name="grant">Grant</string>
<string name="su_warning">Grants full access to your device.\nDeny if you\'re not sure!</string>
<string name="forever">Forever</string>
@@ -74,25 +74,22 @@
<string name="su_revoke_msg">Confirm to revoke %1$s Superuser rights</string>
<string name="toast">Toast</string>
<string name="none">None</string>
<string name="superuser_toggle_notification">Notifications</string>
<string name="superuser_toggle_revoke">Revoke</string>
<string name="superuser_policy_none">No apps have asked for Superuser permission yet.</string>
<!--Logs-->
<string name="log_data_none">You\'re log-free, try using your root apps more</string>
<string name="log_data_magisk_none">Magisk logs are empty, that\'s weird</string>
<string name="log_data_none">You\'re log-free. Try using your root apps more.</string>
<string name="log_data_magisk_none">Magisk logs are empty, that\'s weird.</string>
<string name="menuSaveLog">Save log</string>
<string name="menuClearLog">Clear log now</string>
<string name="logs_cleared">Log successfully cleared</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Target UID: %1$d</string>
<string name="target_pid">Mount ns target PID: %s</string>
<string name="target_pid">Target PID: %s</string>
<string name="selinux_context">SELinux context: %s</string>
<string name="supp_group">Supplementary group: %s</string>
<!--SafetyNet-->
<!--MagiskHide-->
<string name="show_system_app">Show system apps</string>
<string name="show_os_app">Show OS apps</string>
@@ -112,20 +109,20 @@
<string name="module_action">Action</string>
<string name="module_state_restore">Restore</string>
<string name="module_action_install_external">Install from storage</string>
<string name="update_available">Update Available</string>
<string name="update_available">Update available</string>
<string name="suspend_text_riru">Module suspended because %1$s is enabled</string>
<string name="suspend_text_zygisk">Module suspended because %1$s is not enabled</string>
<string name="suspend_text_zygisk">Module suspended because %1$s isn\'t enabled</string>
<string name="zygisk_module_unloaded">Zygisk module not loaded due to incompatibility</string>
<string name="module_empty">No module installed</string>
<string name="confirm_install">Install module %1$s?</string>
<string name="confirm_install_title">Install Confirmation</string>
<string name="confirm_install_title">Install confirmation</string>
<!--Settings-->
<string name="settings_dark_mode_title">Theme Mode</string>
<string name="settings_dark_mode_title">Theme mode</string>
<string name="settings_dark_mode_message">Select mode which best suits your style!</string>
<string name="settings_dark_mode_light">Always Light</string>
<string name="settings_dark_mode_system">Follow System</string>
<string name="settings_dark_mode_dark">Always Dark</string>
<string name="settings_dark_mode_light">Always light</string>
<string name="settings_dark_mode_system">Follow system</string>
<string name="settings_dark_mode_dark">Always dark</string>
<string name="settings_download_path_title">Download path</string>
<string name="settings_download_path_message">Files will be saved to %1$s</string>
<string name="settings_hide_app_title">Hide the Magisk app</string>
@@ -133,15 +130,16 @@
<string name="settings_restore_app_title">Restore the Magisk app</string>
<string name="settings_restore_app_summary">Unhide the app and restore the original APK</string>
<string name="language">Language</string>
<string name="system_default">(System Default)</string>
<string name="settings_check_update_title">Check Updates</string>
<string name="system_default">(System default)</string>
<string name="settings_check_update_title">Check for updates</string>
<string name="settings_check_update_summary">Periodically check for updates in the background</string>
<string name="settings_update_channel_title">Update Channel</string>
<string name="settings_update_channel_title">Update channel</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_debug">Debug</string>
<string name="settings_update_custom">Custom</string>
<string name="settings_update_custom_msg">Insert a custom channel URL</string>
<string name="settings_zygisk_summary">Run parts of Magisk in the zygote daemon</string>
<string name="settings_zygisk_summary">Run parts of Magisk in the Zygote daemon</string>
<string name="settings_denylist_title">Enforce DenyList</string>
<string name="settings_denylist_summary">Processes on the denylist will have all Magisk modifications reverted</string>
<string name="settings_denylist_config_title">Configure DenyList</string>
@@ -162,48 +160,48 @@
<string name="settings_su_request_30">30 seconds</string>
<string name="settings_su_request_45">45 seconds</string>
<string name="settings_su_request_60">60 seconds</string>
<string name="superuser_access">Superuser Access</string>
<string name="auto_response">Automatic Response</string>
<string name="request_timeout">Request Timeout</string>
<string name="superuser_notification">Superuser Notification</string>
<string name="superuser_access">Superuser access</string>
<string name="auto_response">Automatic response</string>
<string name="request_timeout">Request timeout</string>
<string name="superuser_notification">Superuser notification</string>
<string name="settings_su_reauth_title">Reauthenticate after upgrade</string>
<string name="settings_su_reauth_summary">Ask for Superuser permissions again after upgrading apps</string>
<string name="settings_su_tapjack_title">Tapjacking Protection</string>
<string name="settings_su_tapjack_summary">The Superuser prompt dialog will not respond to input while obscured by any other window or overlay</string>
<string name="settings_su_auth_title">User Authentication</string>
<string name="settings_su_tapjack_title">Tapjacking protection</string>
<string name="settings_su_tapjack_summary">The Superuser prompt dialog won\'t respond to input while obscured by any other window or overlay</string>
<string name="settings_su_auth_title">User authentication</string>
<string name="settings_su_auth_summary">Ask for user authentication during Superuser requests</string>
<string name="settings_su_auth_insecure">No authentication method is configured on the device</string>
<string name="settings_su_restrict_title">Restrict root capabilities</string>
<string name="settings_su_restrict_summary">Will restrict new Superuser apps by default. Warning: this will break most apps. Don\'t enable it unless you know what you\'re doing.</string>
<string name="settings_customization">Customization</string>
<string name="setting_add_shortcut_summary">Add a pretty shortcut to the home screen in case the name and icon are difficult to recognize after hiding the app</string>
<string name="settings_doh_title">DNS over HTTPS</string>
<string name="settings_doh_description">Workaround DNS poisoning in some nations</string>
<string name="settings_random_name_title">Randomize output name</string>
<string name="settings_random_name_description">Randomize the output file name of patched images and tar files to prevent detection</string>
<string name="multiuser_mode">Multiuser Mode</string>
<string name="settings_owner_only">Device Owner Only</string>
<string name="settings_owner_manage">Device Owner Managed</string>
<string name="settings_user_independent">User-Independent</string>
<string name="multiuser_mode">Multiuser mode</string>
<string name="settings_owner_only">Device owner only</string>
<string name="settings_owner_manage">Device owner managed</string>
<string name="settings_user_independent">User-independent</string>
<string name="owner_only_summary">Only owner has root access</string>
<string name="owner_manage_summary">Only owner can manage root access and receive request prompts</string>
<string name="user_independent_summary">Each user has their own separate root rules</string>
<string name="mount_namespace_mode">Mount Namespace Mode</string>
<string name="settings_ns_global">Global Namespace</string>
<string name="settings_ns_requester">Inherit Namespace</string>
<string name="settings_ns_isolate">Isolated Namespace</string>
<string name="mount_namespace_mode">Mount namespace mode</string>
<string name="settings_ns_global">Global namespace</string>
<string name="settings_ns_requester">Inherit namespace</string>
<string name="settings_ns_isolate">Isolated namespace</string>
<string name="global_summary">All root sessions use the global mount namespace</string>
<string name="requester_summary">Root sessions will inherit their requester\'s namespace</string>
<string name="isolate_summary">Each root session will have its own isolated namespace</string>
<!--Notifications-->
<string name="update_channel">Magisk Updates</string>
<string name="progress_channel">Progress Notifications</string>
<string name="updated_channel">Update Complete</string>
<string name="update_channel">Magisk updates</string>
<string name="progress_channel">Progress notifications</string>
<string name="updated_channel">Update complete</string>
<string name="download_complete">Download complete</string>
<string name="download_file_error">Error downloading file</string>
<string name="magisk_update_title">Magisk Update Available!</string>
<string name="updated_title">Magisk Updated</string>
<string name="magisk_update_title">Magisk update available!</string>
<string name="updated_title">Magisk updated</string>
<string name="updated_text">Tap to open app</string>
<!--Toasts, Dialogs-->
@@ -221,27 +219,27 @@
<string name="failure">Failed!</string>
<string name="hide_app_title">Hiding the Magisk app…</string>
<string name="open_link_failed_toast">No app found to open the link</string>
<string name="complete_uninstall">Complete Uninstall</string>
<string name="restore_img">Restore Images</string>
<string name="complete_uninstall">Complete uninstall</string>
<string name="restore_img">Restore images</string>
<string name="restore_img_msg">Restoring…</string>
<string name="restore_done">Restoration done!</string>
<string name="restore_fail">Stock backup does not exist!</string>
<string name="restore_fail">Stock backup doesn\'t exist!</string>
<string name="setup_fail">Setup failed</string>
<string name="env_fix_title">Requires Additional Setup</string>
<string name="env_fix_title">Requires additional setup</string>
<string name="env_fix_msg">Your device needs additional setup for Magisk to work properly. Do you want to proceed and reboot?</string>
<string name="env_full_fix_msg">Your device needs reflash Magisk to work properly. Please reinstall Magisk within app, recovery mode cannot get correct device info.</string>
<string name="env_full_fix_msg">Your device needs reflash Magisk to work properly. Please reinstall Magisk within app, Recovery mode cannot get correct device info.</string>
<string name="setup_msg">Running environment setup…</string>
<string name="unsupport_magisk_title">Unsupported Magisk Version</string>
<string name="unsupport_magisk_msg">This version of the app does not support Magisk versions lower than %1$s.\n\nThe app will behave as if no Magisk is installed, please upgrade Magisk as soon as possible.</string>
<string name="unsupport_general_title">Abnormal State</string>
<string name="unsupport_system_app_msg">Running this app as a system app is not supported. Please revert the app to a user app.</string>
<string name="unsupport_magisk_title">Unsupported Magisk version</string>
<string name="unsupport_magisk_msg">This version of the app doesn\'t support Magisk versions lower than %1$s.\n\nThe app will behave as if no Magisk is installed. Please update Magisk as soon as possible.</string>
<string name="unsupport_general_title">Abnormal state</string>
<string name="unsupport_system_app_msg">Running this app as a system app isn\'t supported. Please revert the app to a user app.</string>
<string name="unsupport_other_su_msg">A \"su\" binary not from Magisk has been detected. Please remove any competing root solution and/or reinstall Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk is installed to external storage. Please move the app to internal storage.</string>
<string name="unsupport_nonroot_stub_msg">The hidden Magisk app cannot continue to work because root was lost. Please restore the original APK.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Grant storage permission to enable this functionality</string>
<string name="post_notifications_denied">Grant notifications permission to enable this functionality</string>
<string name="install_unknown_denied">Allow "install unknown apps" to enable this functionality</string>
<string name="install_unknown_denied">Allow \"Install unknown apps\" to enable this functionality</string>
<string name="add_shortcut_title">Add shortcut to home screen</string>
<string name="add_shortcut_msg">After hiding this app, its name and icon might become difficult to recognize. Do you want to add a pretty shortcut to the home screen?</string>
<string name="app_not_found">No app found to handle this action</string>

View File

@@ -30,5 +30,4 @@ android.nonFinalResIds=false
# Magisk
magisk.stubVersion=40
magisk.versionCode=28102
magisk.ondkVersion=r28.2
magisk.versionCode=30600

View File

@@ -1,18 +1,17 @@
[versions]
kotlin = "2.1.0"
android = "8.8.0"
ksp = "2.1.0-1.0.29"
kotlin = "2.2.21"
android = "8.13.1"
ksp = "2.3.3"
rikka = "1.3.0"
navigation = "2.8.4"
navigation = "2.9.6"
libsu = "6.0.0"
moshi = "1.15.1"
okhttp = "4.12.0"
retrofit = "2.11.0"
room = "2.6.1"
okhttp = "5.3.2"
retrofit = "3.0.0"
room = "2.8.4"
[libraries]
bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version = "1.80" }
commons-compress = { module = "org.apache.commons:commons-compress", version = "1.27.1" }
bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version = "1.83" }
commons-compress = { module = "org.apache.commons:commons-compress", version = "1.28.0" }
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
retrofit-scalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" }
@@ -20,18 +19,16 @@ markwon-core = { module = "io.noties.markwon:core", version = "4.6.2" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
okhttp-dnsoverhttps = { module = "com.squareup.okhttp3:okhttp-dnsoverhttps", version.ref = "okhttp" }
okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" }
moshi-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" }
timber = { module = "com.jakewharton.timber:timber", version = "5.0.1" }
jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "7.1.0.202411261347-r" }
# AndroidX
activity = { module = "androidx.activity:activity", version = "1.10.0" }
appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.0" }
core-ktx = { module = "androidx.core:core-ktx", version = "1.15.0" }
core-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.0.1" }
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.2.0" }
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version = "1.8.5" }
activity = { module = "androidx.activity:activity", version = "1.12.0" }
appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.1" }
core-ktx = { module = "androidx.core:core-ktx", version = "1.17.0" }
core-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.2.0" }
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.2.1" }
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version = "1.8.9" }
navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigation" }
navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigation" }
profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version = "1.4.1" }
@@ -40,13 +37,13 @@ room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
transition = { module = "androidx.transition:transition", version = "1.5.1" }
collection-ktx = { module = "androidx.collection:collection-ktx", version = "1.4.5" }
material = { module = "com.google.android.material:material", version = "1.12.0" }
jdk-libs = { module = "com.android.tools:desugar_jdk_libs_nio", version = "2.1.3" }
test-runner = { module = "androidx.test:runner", version = "1.6.2" }
test-rules = { module = "androidx.test:rules", version = "1.6.1" }
test-junit = { module = "androidx.test.ext:junit", version = "1.2.1" }
transition = { module = "androidx.transition:transition", version = "1.6.0" }
collection-ktx = { module = "androidx.collection:collection-ktx", version = "1.5.0" }
material = { module = "com.google.android.material:material", version = "1.13.0" }
jdk-libs = { module = "com.android.tools:desugar_jdk_libs_nio", version = "2.1.5" }
test-runner = { module = "androidx.test:runner", version = "1.7.0" }
test-rules = { module = "androidx.test:rules", version = "1.7.0" }
test-junit = { module = "androidx.test.ext:junit", version = "1.3.0" }
test-uiautomator = { module = "androidx.test.uiautomator:uiautomator", version = "2.3.0" }
# topjohnwu
@@ -65,5 +62,6 @@ android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref
ksp-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
navigation-safe-args-plugin = { module = "androidx.navigation:navigation-safe-args-gradle-plugin", version.ref = "navigation" }
lsparanoid-plugin = { module = "org.lsposed.lsparanoid:gradle-plugin", version = "0.6.0" }
moshi-plugin = { module = "dev.zacsweers.moshix:dev.zacsweers.moshix.gradle.plugin", version = "0.34.1" }
[plugins]

BIN
app/gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -205,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
@@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.

View File

@@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell

View File

@@ -8,4 +8,4 @@ dependencyResolutionManagement {
}
}
rootProject.name = "Magisk"
include(":app:apk", ":app:core", ":app:shared", ":app:stub", ":app:test", ":native")
include(":apk", ":core", ":shared", ":stub", ":test")

View File

@@ -25,6 +25,7 @@
<application
android:allowBackup="false"
android:enableOnBackInvokedCallback="false"
android:label="Magisk"
android:requestLegacyExternalStorage="true"
android:supportsRtl="true"

View File

@@ -7,12 +7,12 @@ public class ProviderInstaller {
private static final String GMS_PACKAGE_NAME = "com.google.android.gms";
public static boolean install(Context context) {
public static void install(Context context) {
try {
// Check if gms is a system app
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(GMS_PACKAGE_NAME, 0);
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
return false;
return;
}
// Try installing new SSL provider from Google Play Service
@@ -22,9 +22,7 @@ public class ProviderInstaller {
.loadClass("com.google.android.gms.common.security.ProviderInstallerImpl")
.getMethod("insertProvider", Context.class)
.invoke(null, gms);
} catch (Exception e) {
return false;
} catch (Exception ignored) {
}
return true;
}
}

View File

@@ -13,24 +13,28 @@ android {
namespace = "com.topjohnwu.magisk"
val canary = !Config.version.contains(".")
val url = if (canary) null
else "https://github.com/topjohnwu/Magisk/releases/download/v${Config.version}/Magisk-v${Config.version}.apk"
val base = "https://github.com/topjohnwu/Magisk/releases/download/"
val url = base + "v${Config.version}/Magisk-v${Config.version}.apk"
val canaryUrl = base + "canary-${Config.versionCode}/"
defaultConfig {
applicationId = "com.topjohnwu.magisk"
versionCode = 1
versionName = "1.0"
buildConfigField("String", "APK_URL", url?.let { "\"$it\"" } ?: "null" )
buildConfigField("String", "APK_URL", "\"$url\"")
buildConfigField("int", "STUB_VERSION", Config.stubVersion)
}
buildTypes {
release {
if (canary) buildConfigField("String", "APK_URL", "\"${canaryUrl}app-release.apk\"")
proguardFiles("proguard-rules.pro")
isMinifyEnabled = true
isShrinkResources = false
}
debug {
if (canary) buildConfigField("String", "APK_URL", "\"${canaryUrl}app-debug.apk\"")
}
}
buildFeatures {
@@ -41,5 +45,5 @@ android {
setupStubApk()
dependencies {
implementation(project(":app:shared"))
implementation(project(":shared"))
}

View File

@@ -27,8 +27,6 @@ import com.topjohnwu.magisk.net.Networking;
import com.topjohnwu.magisk.net.Request;
import com.topjohnwu.magisk.utils.APKInstall;
import org.json.JSONException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
@@ -48,13 +46,8 @@ import javax.crypto.spec.SecretKeySpec;
public class DownloadActivity extends Activity {
private static final String APP_NAME = "Magisk";
private static final String JSON_URL = BuildConfig.DEBUG ?
"https://topjohnwu.github.io/magisk-files/debug.json" :
"https://topjohnwu.github.io/magisk-files/canary.json";
private String apkLink = BuildConfig.APK_URL;
private Context themed;
private ProgressDialog dialog;
private boolean dynLoad;
@Override
@@ -75,11 +68,7 @@ public class DownloadActivity extends Activity {
ProviderInstaller.install(this);
if (Networking.checkNetworkStatus(this)) {
if (BuildConfig.APK_URL == null) {
fetchCanary();
} else {
showDialog();
}
showDialog();
} else {
new AlertDialog.Builder(themed)
.setCancelable(false)
@@ -115,23 +104,10 @@ public class DownloadActivity extends Activity {
.show();
}
private void fetchCanary() {
dialog = ProgressDialog.show(themed, "", "", true);
request(JSON_URL).getAsJSONObject(json -> {
dialog.dismiss();
try {
apkLink = json.getJSONObject("magisk").getString("link");
showDialog();
} catch (JSONException e) {
error(e);
}
});
}
private void dlAPK() {
dialog = ProgressDialog.show(themed, getString(dling), getString(dling) + " " + APP_NAME, true);
ProgressDialog.show(themed, getString(dling), getString(dling) + " " + APP_NAME, true);
// Download and upgrade the app
var request = request(apkLink).setExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
var request = request(BuildConfig.APK_URL).setExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (dynLoad) {
request.getAsFile(StubApk.current(this), file -> StubApk.restartProcess(this));
} else {

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">عليك الترقية Magisk لإكمال تهيئة التطبيق. هل تريد التنزيل والتثبيت؟</string>
<string name="no_internet_msg">يرجى اللإتصال بالإنترنت! ترقية Magisk مطلوبة.</string>
<string name="upgrade_msg">عليك بتحديث ماجيسك لإكمال تهيئة التطبيق. هل تريد التنزيل والتثبيت؟</string>
<string name="no_internet_msg">يرجى الإتصال بالإنترنت! تحديث ماجيسك مطلوب.</string>
<string name="dling">جارٍ التنزيل</string>
<string name="relaunch_app">يرجى إعادة تشغيل التطبيق يدوياً</string>
</resources>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Author: Radoš Milićev (https://github.com/rammba)-->
<resources>
<string name="upgrade_msg">Ažurirajte Magisk da biste završili postavljanje. Preuzmi i instaliraj?</string>
<string name="no_internet_msg">Molimo povežite se na internet! Neophodno je ažuriranje Magisk-a.</string>
<string name="dling">Preuzimanje</string>
<string name="relaunch_app">Molimo pokrenite aplikaciju ponovo</string>
</resources>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Setup complete karne ke liye full Magisk install karna hoga. Abhi download aur install karein?</string>
<string name="no_internet_msg">Full Magisk upgrade ke liye Internet se connect hona zaroori hai!</string>
<string name="dling">Download ho raha hai…</string>
<string name="relaunch_app">App ko reopen karo</string>
</resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Atualize para o Magisk completo para finalizar a configuração. Deseja baixar e instalar?</string>
<string name="no_internet_msg">Por favor, conecte-se à internet! É necessário atualizar para o Magisk completo.</string>
<string name="dling">Baixando</string>
<string name="upgrade_msg">Atualize para o Magisk completo para finalizar a configuração. Deseja descarregar e instalar?</string>
<string name="no_internet_msg">Por favor, ligue-se à internet! É necessário atualizar para o Magisk completo.</string>
<string name="dling">A descarregar</string>
<string name="relaunch_app">Por favor, reinicie o app manualmente.</string>
</resources>

View File

@@ -1 +1,8 @@
<resources></resources>
<?xml version="1.0" encoding="utf-8"?>
<!--Author: Radoš Milićev (https://github.com/rammba)-->
<resources>
<string name="upgrade_msg">Ажурирајте Magisk да бисте завршили постављање. Преузми и инсталирај?</string>
<string name="no_internet_msg">Молимо повежите се на интернет! Неопходно је ажурирање Magisk-а.</string>
<string name="dling">Преузимање</string>
<string name="relaunch_app">Молимо покрените апликацију поново</string>
</resources>

View File

@@ -20,7 +20,7 @@ android {
}
}
setupAppCommon()
setupTestApk()
dependencies {
implementation(libs.test.runner)

View File

@@ -1,7 +0,0 @@
plugins {
id("MagiskPlugin")
}
tasks.register("clean", Delete::class) {
delete(rootProject.layout.buildDirectory)
}

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