Compare commits

...

278 Commits
v26.0 ... v26.3

Author SHA1 Message Date
topjohnwu
5a16418543 Release Magisk v26.3 2023-09-04 00:01:46 -07:00
topjohnwu
7297aba15a Add v26.3 release notes 2023-09-03 23:54:45 -07:00
Ylarod
bc5d5f9502 Update details.md
The `MAGISKTMP` changed to `/debug_ramdisk` since https://github.com/topjohnwu/Magisk/pull/6931
2023-09-03 23:46:25 -07:00
vvb2060
1761986c1b Update zh-rCN translation 2023-09-03 23:43:07 -07:00
topjohnwu
1e034e3e0e Update libsu 2023-09-03 23:41:17 -07:00
topjohnwu
bbf9756bfa Release new canary build 2023-09-02 06:20:10 -07:00
topjohnwu
96e559fb0e Skip cargo build if possible 2023-09-02 06:03:39 -07:00
topjohnwu
4c45775131 Update BusyBox 2023-09-02 05:45:18 -07:00
LoveSy
c072b4254d Wrap rename and renameat 2023-09-02 04:24:24 -07:00
topjohnwu
2dbb812126 Disable stack protector on x86 static executables
Close #7274
2023-09-01 23:04:19 -07:00
topjohnwu
be50f17f55 Update to ONDK r26.0
Close #7264
2023-09-01 23:01:49 -07:00
残页
6f77f190f2 Fix processPayload 2023-08-31 20:30:10 -07:00
topjohnwu
6bdc57cbe4 Release new canary build 2023-08-30 01:22:02 -07:00
残页
de00f1d5a9 Always check mounts to detect legacy SAR on bootmode 2023-08-30 01:02:19 -07:00
残页
e9b9bf987b Fix syntax error in util_functions.sh 2023-08-29 15:33:03 -07:00
topjohnwu
f4b6385f9f Disable boot vbmeta patch when found vbmeta.img 2023-08-28 22:54:55 -07:00
topjohnwu
75d905a56d Fix device detection scripts and logic 2023-08-28 22:13:36 -07:00
topjohnwu
b1363ee479 Do not allow user to configure boot vbmeta patching 2023-08-28 22:13:36 -07:00
topjohnwu
51afe43a30 Cleanup util_functions 2023-08-28 22:13:36 -07:00
残页
189c03c047 Add canyie to developer list 2023-08-28 13:21:58 -07:00
topjohnwu
ae9d270a32 Release new canary build 2023-08-28 01:25:07 -07:00
topjohnwu
e47e869f6b Update full changelog 2023-08-28 01:15:14 -07:00
topjohnwu
c39038a439 Update README 2023-08-28 01:13:25 -07:00
topjohnwu
69174e2c13 Release Magisk v26.2 2023-08-28 01:04:28 -07:00
Chris Renshaw
474268a0af manager.sh: add ro.boot.vbmeta.size + ro.product.ab_ota_partitions to vbmeta check
ro.boot.vbmeta.device doesn't seem to be in use on all A/B devices
2023-08-28 00:45:14 -07:00
topjohnwu
eadb0307fa Add v26.2 release notes 2023-08-27 23:48:49 -07:00
topjohnwu
5a5d0d5d72 Add missing permissions 2023-08-27 23:29:34 -07:00
topjohnwu
a1273bc467 Update dependencies 2023-08-27 22:44:51 -07:00
topjohnwu
0c28a916be Use cxx_name 2023-08-24 00:50:38 -07:00
BlackMesa123
0ba573b789 Additional Samsung devices install guide refactoring
Signed-off-by: BlackMesa123 <giangrecosalvo9@gmail.com>
2023-08-18 17:24:25 -07:00
BlackMesa123
ec42ee152c Refactor Samsung devices install guide
Signed-off-by: BlackMesa123 <giangrecosalvo9@gmail.com>
2023-08-18 17:24:25 -07:00
I3elphegor
abcb487361 Update czech translation of strings.xml
Added and translated new strings.
2023-08-18 17:19:36 -07:00
vvb2060
d12d9e82f1 Force kernel to load rootfs only for legacy SAR devices 2023-08-18 17:18:34 -07:00
topjohnwu
275208e81b Update Rust dependencies 2023-08-17 21:24:29 -07:00
topjohnwu
41226c12b8 Update to ONDK r25.7 2023-08-15 17:10:20 -07:00
topjohnwu
f86c66c99d Officially support API 34 2023-08-11 09:46:45 -07:00
topjohnwu
93876b5fd3 Update dependencies, AGP, and SDK level 2023-08-11 09:38:59 -07:00
topjohnwu
b5b14ce343 Use cxx_name instead of rust_name 2023-08-10 21:22:53 -07:00
topjohnwu
350d0d600c Update build script 2023-08-08 01:05:32 -07:00
topjohnwu
f924ffcbf3 Merge files 2023-08-08 00:57:58 -07:00
VD $ VD171 @ Priv8
0f5963f231 Update PORTUGUESE Translation 2023-08-08 00:54:01 -07:00
Arbri çoçka
1961ff2c40 Update strings.xml Albania 2023-08-08 00:53:38 -07:00
vvb2060
40003691d6 manager.sh: check vbmeta device by getprop 2023-08-08 00:53:21 -07:00
topjohnwu
8290358241 Release new canary build 2023-08-05 23:27:06 -07:00
kubalav
ee34f775c3 Update Slovak translation 2023-08-05 23:19:34 -07:00
vvb2060
feb47cd88c sulog: add migration 2023-08-02 21:18:05 -07:00
vvb2060
c6efb51f61 sulog: add more info 2023-08-02 21:18:05 -07:00
Hen_Ry
a5acf33ccd Update De translation 2023-08-02 21:17:12 -07:00
vvb2060
ab9ee449e4 suBiometric: fix open app on second user will auto disable biometric
second user does not support biometric, but the config of app ignores user
2023-08-02 21:16:06 -07:00
vvb2060
9571b6f9be SuperuserViewModel: fix updatePolicy
Starting biometrics may cause the SuperuserFragment to lost focus. After onResume(), doLoadWork() will refresh the itemsPolicies, so notify property changed will work on wrong items. Fixed by snapshotting items to be refreshed before starting biometrics.
2023-08-02 09:29:14 -07:00
vvb2060
207d7fd3f6 SuRequestViewModel: fix await RootService on the main thread 2023-08-02 09:21:25 -07:00
南宫雪珊
bcdcfa1104 Update scripts/avd_magisk.sh 2023-08-02 09:12:00 -07:00
vvb2060
e0a4230dac avd_magisk: hide stderr 2023-08-02 09:12:00 -07:00
topjohnwu
17ba5cba3e Print permissive rules 2023-08-02 09:11:22 -07:00
topjohnwu
f2e109ad7d Update libselinux and libsepol 2023-08-01 18:07:53 -07:00
topjohnwu
c83e141a1c Support dumping sepolicy rules 2023-08-01 18:03:54 -07:00
topjohnwu
6089cc36de Update xperm parsing 2023-07-31 09:28:27 -07:00
topjohnwu
9638dc0a66 Fix perror 2023-07-25 21:03:04 -07:00
Andrew Gunnerson
b191a14a23 magiskpolicy: Fix old xperms being cleared when adding new xperms
This commit updates sepol_impl::add_xperm_rule() so that it loads the
current xperm bits from the existing avtab entry before setting or
clearing xperm bits. This fixes new allowxperm rules causing old xperm
rules within the same xperm specified/driver to be removed.

Fixes: #7176

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2023-07-24 23:52:28 -07:00
topjohnwu
cf1bc82537 Random small refactoring 2023-07-24 23:49:20 -07:00
残页
6141bb5bb3 Fix MagiskInstaller.patchBoot() error catching 2023-07-21 12:05:33 -07:00
topjohnwu
4d2b62da0d Do not override global variables in document 2023-07-21 12:04:42 -07:00
topjohnwu
39383229d1 Update dependencies
Close #7128
2023-07-20 18:35:53 -07:00
topjohnwu
08bfbb154a Release new canary build 2023-07-17 23:20:07 -07:00
残页
d390ca2fdf Avoid using IconCompat.createFromIcon() that doesn't support bitmap icon 2023-07-17 21:46:47 -07:00
topjohnwu
7ad77a14ae Remove unused line 2023-07-17 21:43:09 -07:00
topjohnwu
f33343b4e6 Remove unused code and logic 2023-07-17 18:58:48 -07:00
topjohnwu
af65d07456 Support AVB1.0 signing and verification in magiskboot 2023-07-17 18:57:50 -07:00
topjohnwu
16d728f379 Partially document global variables in scripts 2023-07-17 16:07:16 -07:00
topjohnwu
c97ab690b6 Segment memory mapped boot image region 2023-07-13 21:01:49 -07:00
topjohnwu
4caed73fe0 Always include boot image when processing tar
Credits: @BlackMesa123

Fix #7132, close #7133
2023-07-09 02:04:42 -07:00
BlackMesa123
4856da1584 Ignore userdata.img in Samsung tar firmware packages
Signed-off-by: BlackMesa123 <giangrecosalvo9@gmail.com>
2023-07-06 17:37:12 -07:00
LoveSy
0a07018fec No need to use submodule for argh 2023-07-06 15:28:39 -07:00
LoveSy
64c82e1f2c Refine cpio argh
we can use argh to handle `--help` now
2023-07-06 15:07:06 -07:00
topjohnwu
e8e8afa6c2 Properly handle visibility 2023-07-06 11:12:27 -07:00
LoveSy
af2207433d Fix error logging
ok_or will unconditionally creates a LoggedResult, which prints
an error even it successes. Use ok_or_else which lazily creates
a LoggedResult only if it fails.
2023-07-06 11:01:57 -07:00
LoveSy
75ba62d588 Fix stub resource loading on Android 9, 10
They can only load resources from zip files

Co-authored-by: canyie <a1364259@163.com>
Co-authored-by: 南宫雪珊 <vvb2060@gmail.com>
2023-07-06 04:53:26 -07:00
LoveSy
606d97ae4d Trace location from LoggedError
Co-authored-by: topjohnwu <topjohnwu@gmail.com>
2023-07-05 18:55:23 -07:00
topjohnwu
d778b0b0a7 Custom help message when using argh
Help messages generated from argh is nearly useless and very hard to
customize. Fork argh and disable all code for generating help messages.

Use a closure to print the help message when handling EarlyExit.
2023-07-05 17:05:39 -07:00
topjohnwu
5ee6daf126 Handle cpio commands properly 2023-07-03 21:57:28 -07:00
Fs00
43b9a09c9b Update Italian app strings 2023-06-30 15:57:56 -07:00
Fs00
8475a2bb94 Update Italian stub strings 2023-06-30 15:57:56 -07:00
Rom
d8692de2f4 Update French translation 2023-06-30 15:57:37 -07:00
LoveSy
33a9abc946 Fix backup fails when ramdisk does not exist 2023-06-30 15:57:09 -07:00
topjohnwu
ee943afbc9 Cleanup SHA hash implementation 2023-06-30 15:50:52 -07:00
LoveSy
1f7c3e9f14 Use rust to calculate sha 2023-06-30 14:06:02 -07:00
topjohnwu
46770db18b Rename stuffs 2023-06-30 03:03:51 -07:00
vvb2060
92f980601c Fix close 2023-06-30 02:43:38 -07:00
vvb2060
d0b8c16651 Fix file permission 2023-06-30 02:43:38 -07:00
LoveSy
a470ee6f93 Fix mmap block device 2023-06-30 01:06:51 -07:00
vvb2060
ff1c56683d Skip magisk32 for 64bit only avd 2023-06-29 20:45:51 -07:00
topjohnwu
4ee4cbada6 Standardize logging and error handling
- Introduce new types: LoggedResult and LoggedError
- Introduce new extension methods to log and add additional msgs
- Never exit when logging error messages in Rust (all errors should be
  handled by using Result and Rust's error propagation)
- Remove all usages of anyhow as it doesn't fit Magisk's use cases
2023-06-29 17:14:53 -07:00
topjohnwu
dbc2236dd2 Release new canary build 2023-06-23 02:39:07 -07:00
topjohnwu
a8c4a33e91 Avoid using trait object 2023-06-23 02:32:29 -07:00
topjohnwu
279f955a84 Minor changes 2023-06-23 01:50:33 -07:00
topjohnwu
fbd1dbb20c Manage MenuProvider with lifecycle state 2023-06-22 16:12:35 -07:00
topjohnwu
6c09fc2e64 Move addMenuProvider into onStart 2023-06-22 15:47:12 -07:00
LoveSy
f3304b482c Fix sulog prompt always shows 2023-06-22 15:27:34 -07:00
LoveSy
0a85ef61c3 Call removeMenuProvider on Fragment::onStop 2023-06-22 15:27:23 -07:00
topjohnwu
dc26ad7125 Address clippy warnings 2023-06-22 02:36:31 -07:00
LoveSy
24b1c607f3 Replace clap with argh 2023-06-22 02:36:31 -07:00
topjohnwu
732a161b67 Minor cleanup 2023-06-22 02:23:27 -07:00
topjohnwu
9c7cf340a1 Move pattern matching to Rust 2023-06-21 16:47:20 -07:00
topjohnwu
399b9e5eba Move hexpatch to Rust 2023-06-20 18:17:26 -07:00
topjohnwu
5805573625 Update clean operation 2023-06-20 14:50:02 -07:00
topjohnwu
a6b1149b9f Minor cleanup 2023-06-20 14:36:07 -07:00
LoveSy
51e985ae7f Use quick-protobuf 2023-06-20 14:36:07 -07:00
vvb2060
9929b25339 Move su request path to magisk tmp 2023-06-20 03:29:06 -07:00
topjohnwu
2359cfc480 Small refactor 2023-06-20 00:21:51 -07:00
topjohnwu
81493475f9 Directly use rust::Vec 2023-06-20 00:21:51 -07:00
Arbri çoçka
0493829231 Update strings.xml sq 2023-06-16 14:15:31 -07:00
VD $ VD171 @ Priv8
e2d1952ad9 Update PORTUGUESE Translation 2023-06-16 14:14:46 -07:00
LoveSy
7450965458 Update Chinese translation
Co-authored-by: 南宫雪珊 <vvb2060@gmail.com>
2023-06-16 14:13:46 -07:00
Vladimír Kubala
f45384685b Update Slovak translation 2023-06-16 14:13:01 -07:00
topjohnwu
8abcccc262 Fix typo 2023-06-16 01:49:44 -07:00
LoveSy
a9c89cbbbb Read certificate in Rust
Co-authored-by: topjohnwu <topjohnwu@gmail.com>
2023-06-16 01:49:44 -07:00
topjohnwu
d2eaa6e6c1 Fix scripts on Windows 2023-06-15 05:57:19 -07:00
LoveSy
53257b6ea1 Fix find_apk_path 2023-06-15 04:09:45 -07:00
LoveSy
c874391be4 Box CpioEntry 2023-06-15 04:09:17 -07:00
LoveSy
7e8e013832 Fix two typo 2023-06-15 04:09:17 -07:00
topjohnwu
037f46f7f0 Fix copy_cstr 2023-06-15 04:00:32 -07:00
topjohnwu
d3e1c496ca Upgrade ONDK to r25.6 2023-06-15 01:26:54 -07:00
topjohnwu
d7d0a44693 Remove randomness from Magisk 2023-06-14 17:05:49 -07:00
topjohnwu
9d6f6764cb Use Metadata instead of direct stat syscall 2023-06-12 14:58:13 -07:00
topjohnwu
cb3ab63815 Replace all CStr usage to Utf8CStr 2023-06-12 13:57:15 -07:00
topjohnwu
caae932117 Remove unnecessary lifetime markers 2023-06-12 13:56:20 -07:00
LoveSy
e9cf27eb5a Fix map_file 2023-06-12 13:55:58 -07:00
LoveSy
6ee6685f4c AVD test on API 34 2023-06-12 03:23:27 -07:00
LoveSy
d15017b777 Add arg requirement for cpio extract 2023-06-12 02:40:50 -07:00
LoveSy
a9387e63e1 Fix Utf8CStr::as_ref() -> OsStr 2023-06-12 02:40:50 -07:00
topjohnwu
23c1f0111b Improve Rust implementation
- Move mmap_file implementation into Rust
- Introduce Utf8CStr as the better c-string type to use
2023-06-12 02:40:50 -07:00
LoveSy
866386e21f Use to_string instead of to_owned 2023-06-12 02:40:50 -07:00
LoveSy
bf10496fa9 Add log for restore 2023-06-12 02:40:50 -07:00
LoveSy
607e6547a7 No check rm -r 2023-06-12 02:40:50 -07:00
topjohnwu
6b21091fe2 Fix compile errors and cleanup 2023-06-12 02:40:50 -07:00
topjohnwu
e58f98e844 Update cargo files 2023-06-12 02:40:50 -07:00
LoveSy
b8cb9cd84d Refactor magiskboot cpio 2023-06-12 02:40:50 -07:00
LoveSy
c1038ac6f9 Remove permissve update_engine 2023-06-10 13:17:37 -07:00
LoveSy
c556dd0aac Increase sccache hit rate 2023-06-10 13:17:16 -07:00
LoveSy
d2fbcd07b7 Use sccache on non CI env 2023-06-10 13:14:12 -07:00
LoveSy
bf6359abaa Fix release build 2023-06-10 13:10:54 -07:00
topjohnwu
d1621845b8 Fix typo 2023-06-10 01:50:18 -07:00
topjohnwu
f33f1d25d0 Move find_apk_path to Rust 2023-06-10 01:40:45 -07:00
topjohnwu
40f25f4d56 Introduce directory traversal 2023-06-09 02:00:37 -07:00
topjohnwu
e13775ec2c Directly use memmem in contains 2023-06-07 16:52:52 -07:00
topjohnwu
ee4dad7a13 Bridge C++ bytes with Rust &[u8] 2023-06-07 16:49:40 -07:00
topjohnwu
5e2ef1b7f4 Better bytes support in C++ 2023-06-06 17:11:42 -07:00
topjohnwu
f8c38eab74 Proper Windows support 2023-06-05 02:27:02 -07:00
topjohnwu
305e8b3d14 Improve bootimg const correctness 2023-06-03 05:10:22 -07:00
topjohnwu
2a654e5d7f Improve byte_data const correctness 2023-06-03 03:16:03 -07:00
topjohnwu
57afae3425 Cleanup cpio codebase 2023-06-03 00:31:20 -07:00
topjohnwu
feb44f875e Migrate PREINITDEVICE in recovery mode
Close #6917
2023-06-02 16:49:04 -07:00
topjohnwu
7eebe62bb6 Do not realpath ANDROID_SDK_ROOT 2023-06-02 15:36:45 -07:00
topjohnwu
9ea9f01933 Resolve clippy errors and warnings 2023-05-31 01:08:33 -07:00
topjohnwu
665c6bdc4b Provide easy access to the cargo command 2023-05-31 01:08:33 -07:00
topjohnwu
c79bc83275 Update dependencies 2023-05-30 01:32:43 -07:00
topjohnwu
c30fbdf145 Simplify logging code 2023-05-29 01:27:40 -07:00
topjohnwu
f12951bd1d Fix typo 2023-05-29 00:30:55 -07:00
nikk gitanes
52f2e8c4a0 allow fast switch access with d-pad on superuser tab 2023-05-28 23:51:37 -07:00
nikk gitanes
1b2af1ed6d correlate nextFocusRight 2023-05-28 23:51:18 -07:00
nikk gitanes
0f9b2a7df8 make module card clickable and highlight when focused 2023-05-28 23:51:18 -07:00
topjohnwu
f2846694e1 Cleanup some code 2023-05-28 23:50:52 -07:00
topjohnwu
e668dbf6f7 Update AGP 2023-05-28 17:57:53 -07:00
topjohnwu
d77a368176 Move dependency version into workspace 2023-05-28 17:30:33 -07:00
topjohnwu
ad0da08610 Update native clean operation 2023-05-28 17:30:20 -07:00
topjohnwu
0c52385ad4 Update to use ONDK r25.4 2023-05-27 01:57:02 -07:00
topjohnwu
5b8b48ccc1 Properly support streamable input 2023-05-26 14:07:11 -07:00
topjohnwu
659b9c6fee Support extracting any partition from payload.bin 2023-05-26 13:36:47 -07:00
LoveSy
ec31cab5a7 Add zip and payload.bin support to Magisk app 2023-05-26 13:36:47 -07:00
vvb2060
dd93556ad8 Faster get magisk tmpfs path 2023-05-25 01:03:27 -07:00
topjohnwu
533aeadd38 Update cstr macro 2023-05-25 01:03:04 -07:00
topjohnwu
18d0cedbe2 Parse rule files with Rust 2023-05-24 19:11:56 -07:00
topjohnwu
5a94ef9106 Fix init rust code setup 2023-05-23 21:50:13 -07:00
topjohnwu
8e8f01f8b5 Move project common code into include 2023-05-23 21:30:30 -07:00
topjohnwu
7087badf87 Release new canary build 2023-05-23 21:02:33 -07:00
topjohnwu
47d2d4e3a5 Update su cmdline parsing 2023-05-23 20:51:23 -07:00
topjohnwu
6c47d8f556 Support 32 bit only AVD patch
Close #7010
2023-05-23 18:12:06 -07:00
topjohnwu
8c9d0314fb Use sccache for all native builds in CI 2023-05-23 17:52:10 -07:00
topjohnwu
69144942e3 Fix fortify
Close #7009, fix #7003
2023-05-23 16:31:24 -07:00
topjohnwu
5627053b74 Move su folder into core 2023-05-23 01:36:25 -07:00
topjohnwu
0f666de5e6 Organize headers 2023-05-22 21:36:15 -07:00
LoveSy
eddc862fa3 Use POSIX format 2023-05-22 18:14:59 -07:00
LoveSy
4327682120 Add mnt ns attach support for su 2023-05-22 18:14:59 -07:00
LoveSy
af5bdee78f Reimplement su -z 2023-05-22 18:14:59 -07:00
LoveSy
0e36e86dbf Support settings gids of su 2023-05-22 18:14:59 -07:00
LoveSy
f95478f1f1 Truncate file only if needed 2023-05-22 00:51:42 -07:00
topjohnwu
9fe8741a02 Export get_prop to Rust 2023-05-21 23:51:30 -07:00
topjohnwu
a5768e02ea Cleanup byte_channel implementation 2023-05-20 14:19:40 -07:00
topjohnwu
f5aaff2b1e Cleanup filter_out_stream implementation 2023-05-20 01:28:10 -07:00
topjohnwu
655f778171 Better cxx binding codegen 2023-05-19 15:59:40 -07:00
topjohnwu
2e77a426b2 Fix build script 2023-05-19 15:32:14 -07:00
topjohnwu
2bcf2e76f1 Generate cxx binding in build.rs 2023-05-19 15:16:54 -07:00
topjohnwu
57bd450798 Split input and output streams 2023-05-19 04:19:43 -07:00
topjohnwu
582cad1b8d Cleanup libc hacks 2023-05-19 03:23:43 -07:00
topjohnwu
6ca2a3d841 Update libsystemproperties 2023-05-19 03:22:50 -07:00
topjohnwu
91773c3311 Support only read properties from storage 2023-05-19 01:53:40 -07:00
topjohnwu
dc61033b2c Support persist props bypassing property_service 2023-05-18 23:36:46 -07:00
topjohnwu
f8d62a4b6c Move resetprop under core 2023-05-18 22:15:49 -07:00
topjohnwu
1d2145b1b7 Improve argument parsing and help message 2023-05-18 21:54:54 -07:00
topjohnwu
1f7f84b74a Remove unnecessary class 2023-05-18 20:38:33 -07:00
topjohnwu
cd7a335d0f Cleanup implementation 2023-05-18 20:26:20 -07:00
topjohnwu
17569005a4 Remove sysprop fallback
The library now supports mapping as ro
2023-05-18 15:47:50 -07:00
topjohnwu
f36b21bae5 Support get property context
Co-authored-by: canyie <a1364259@163.com>
Co-authored-by: vvb2060 <vvb2060@gmail.com>
2023-05-18 14:46:36 -07:00
topjohnwu
fe1ca52f6d Simplify prop_cb 2023-05-16 02:41:39 -07:00
topjohnwu
1be647a279 Put all FFI into same module 2023-05-16 02:41:39 -07:00
topjohnwu
2ea1a47bec Fix color printing 2023-05-16 02:41:39 -07:00
Ernest
2d799dae0d Update app/src/main/res/values-lt/strings.xml
Co-authored-by: LoveSy <631499712@qq.com>
2023-05-14 23:54:57 -07:00
Ernest
c6408babac Update strings.xml
Updated all strings.
2023-05-14 23:54:57 -07:00
topjohnwu
a8c1ed8795 Update development docs 2023-05-13 02:38:03 -07:00
topjohnwu
e3cb5f8ddd Support setting ANDROID_STUDIO 2023-05-13 02:38:03 -07:00
topjohnwu
e160e211dd Format build.py with black 2023-05-13 02:38:03 -07:00
topjohnwu
22d05ca399 Update time handling code 2023-05-13 02:38:03 -07:00
vvb2060
bd2651057d Simplify prefs migration 2023-05-11 16:29:01 -07:00
topjohnwu
1610092ec4 Increase wait timeout 2023-05-10 16:13:45 -07:00
LoveSy
b9e6937996 Make magisk node ro as well 2023-05-10 00:13:18 -07:00
topjohnwu
a207f03952 Run tests in parallel 2023-05-10 00:10:19 -07:00
topjohnwu
851153dd7c Fix avd_test.sh 2023-05-09 23:11:11 -07:00
topjohnwu
583ffc8177 Reduce cpp logging overhead 2023-05-09 19:14:08 -07:00
topjohnwu
7518092ad2 Implement logging purely in Rust 2023-05-09 18:54:38 -07:00
topjohnwu
8c2ad3883a Update avd_magisk.sh 2023-05-09 17:33:20 -07:00
topjohnwu
d364554425 Remove unused code 2023-05-06 01:48:47 -07:00
vvb2060
726ffdcd98 Fix meizu rootfs type 2023-05-06 00:06:59 -07:00
vvb2060
f9d22cf8ee New magisk tmp dir: /debug_ramdisk
Co-authored-by: LoveSy <shana@zju.edu.cn>
2023-05-06 00:04:11 -07:00
vvb2060
ee50da566f Cancel recursive bind 2023-05-06 00:04:11 -07:00
vvb2060
9f7d410959 Use pathname local socket 2023-05-06 00:04:11 -07:00
vvb2060
bc94ea4334 Update SELinux policy 2023-05-06 00:04:11 -07:00
topjohnwu
c0c9204848 Add ResultExt 2023-05-05 23:57:34 -07:00
topjohnwu
c0d1bf63bc Clean up logging on C++ side 2023-05-05 01:14:56 -07:00
StoyanDimitrov
bbda0cdffe Update strings.xml 2023-05-05 00:39:19 -07:00
topjohnwu
7b5ff99cd1 Reorganize code 2023-05-04 21:37:08 -07:00
topjohnwu
21ddb26db8 Perform proto codegen in build script 2023-05-04 21:37:08 -07:00
LoveSy
7bf2e3875f Support extract boot image from payload.bin 2023-05-04 21:37:08 -07:00
topjohnwu
b136aba1e2 Implement magiskinit logging in Rust 2023-05-02 16:49:43 -07:00
topjohnwu
0d84f80b3c Update AGP 2023-05-02 16:28:14 -07:00
topjohnwu
af45aeb771 Extract busybox from APK for AVD 2023-05-02 16:28:02 -07:00
topjohnwu
1c5a435e1f Update cxx-rs 2023-05-01 14:53:07 -07:00
Soo-Hwan Na
0ea1257dcd Update Korean translation 2023-05-01 12:08:12 -07:00
Mohamadreza Nakhleh
4c92677b5a (translate)
update some Persian (Farsi,فارسی) translations and add more Persian equivalent
2023-05-01 12:07:50 -07:00
fadlyas07
979260bd62 app: l10n: Update Indonesian translations
* Added new strings based on the latest source.
* Rephrase "bisa" (informal) to "dapat" (formal).

Change-Id: I7c29951adff7e5dc086e6044571ff4cdb6366966
2023-05-01 12:07:21 -07:00
topjohnwu
f7de649a36 Update ODNK requirement to r25.3 2023-04-29 15:12:04 -07:00
topjohnwu
0cf0d2b821 Move avd_hack boolean out of init class 2023-04-25 23:34:45 -07:00
vvb2060
3733c9a091 CI: add avd test 2023-04-25 23:00:59 -07:00
vvb2060
e9f32e4f68 Set text and background color 2023-04-25 23:00:59 -07:00
vvb2060
68c2817d40 Enable avd hack for debug build 2023-04-25 23:00:59 -07:00
naxitoo
83d837d868 Update/refine Spanish translations 2023-04-18 11:53:22 -04:00
I3elphegor
093eb15ee1 Update strings.xml
Incorrectly placed punctuation marks have been removed. Word order and some expressions have been corrected. The style of the menu headings and descriptions has been unified in the settings.
2023-04-18 11:22:44 -04:00
VD $ VD171 @ Priv8
c6412c1b1b Update PORTUGUESE translation 2023-04-18 11:22:03 -04:00
serkanege
1151393d74 tr language update 2023-04-18 11:21:32 -04:00
topjohnwu
468f3efb13 Update dependencies 2023-04-13 14:19:34 -07:00
LoveSy
d6b19b9d4c Upgrade gradle 2023-04-13 14:19:30 -07:00
Ilya Kushnir
709f25f600 Fix changelog index 2023-04-12 02:46:21 -07:00
topjohnwu
4b16e4b026 Update README 2023-04-11 12:51:22 -07:00
topjohnwu
cdfbc02922 Release new canary build 2023-04-11 02:04:15 -07:00
topjohnwu
d0c9384233 Release Magisk v26.1 2023-04-11 01:57:30 -07:00
topjohnwu
2488668b06 Add v26.1 release notes 2023-04-11 01:52:45 -07:00
LoveSy
52a98cbd51 Temp workaround for module file context 2023-04-10 19:30:37 -07:00
serkanege
1840c4c486 Update strings.xml 2023-04-10 19:30:11 -07:00
serkanege
34080f3958 Update strings.xml 2023-04-10 19:30:11 -07:00
topjohnwu
e9b76b6aa5 Add monochrome adaptive icon support
Close #6867
2023-04-10 19:29:32 -07:00
Jakub K
b7799b53d9 Updated Czech translation
Added missing strings and updated few.
2023-04-09 21:24:55 -07:00
Lishoo
1e206515c7 Update PL strings
Update PL strings
2023-04-08 21:15:19 -07:00
sn-o-w
6bb313184d Update Romanian 2023-04-08 21:15:02 -07:00
l3ng
2763992434 Update Azerbaijani
Co-authored-by: LoveSy <631499712@qq.com>
2023-04-08 21:14:41 -07:00
osm0sis
18fe0e6442 Fix scripts
manager.sh + boot_patch.sh:
- all listed files from boot_patch.sh header are required for boot patching, but stub.apk was being removed so install_magisk via addon.d.sh would fail without it; leave it in place

addon.d.sh:
- remove old redundant recovery_actions call (it's also performed by setup_flashable in initialize)
- print ABI to match flash_script.sh output

boot_patch.sh:
- catch and abort on any errors from ramdisk.cpio patching in the future

util_functions.sh:
- fix hiding of mount_partitions /system_root umount stderr
- quote mount_apex .pb DEST name parsing charset for safety even though both work

Fixes #6828
2023-04-08 21:13:40 -07:00
zjw
a70c73bffd Fix config file path
$MAGISKTMP was redefined in commit 4e2b88b
2023-04-08 21:10:54 -07:00
topjohnwu
b4ae3493a6 Use ext4 partitions for preinit first
Fix #6841, close #6847
2023-04-08 20:30:40 -07:00
残页
1a16004b20 Add help message for magisk --preinit-device 2023-04-08 18:32:34 -07:00
topjohnwu
56707b8119 Make FilterList more accurate 2023-04-08 18:32:00 -07:00
LoveSy
c3f9533ddc Fix inconsistency of FilterableDiffObservableList
`update` should also update sublist
2023-04-08 18:32:00 -07:00
Rom
3b3abd63cc Update FR translation 2023-04-07 03:08:27 -07:00
Hen_Ry
411d3ed4e9 Update DE strings 2023-04-07 03:07:46 -07:00
LoveSy
f29cc26103 Correctly get displayName of live uri 2023-04-06 02:03:09 -07:00
Ilya Kushnir
1cd595a598 Update RU strings 2023-04-06 01:10:48 -07:00
topjohnwu
22e023b58d Set notes on main thread 2023-04-06 00:53:06 -07:00
topjohnwu
7be958e35d Fix crash when revoke root permission 2023-04-06 00:40:26 -07:00
topjohnwu
69b66ef637 Make core package more self contained 2023-04-05 23:04:33 -07:00
topjohnwu
daf8653c38 Release new canary build 2023-04-05 11:13:51 -07:00
topjohnwu
e2545e57cf Update README badges 2023-04-05 11:07:40 -07:00
296 changed files with 10378 additions and 10001 deletions

View File

@@ -2,17 +2,17 @@ name: Magisk Build
on:
push:
branches: [ master ]
branches: [master]
paths:
- 'app/**'
- 'native/**'
- 'stub/**'
- 'buildSrc/**'
- 'build.py'
- 'gradle.properties'
- '.github/workflows/build.yml'
- "app/**"
- "native/**"
- "stub/**"
- "buildSrc/**"
- "build.py"
- "gradle.properties"
- ".github/workflows/build.yml"
pull_request:
branches: [ master ]
branches: [master]
workflow_dispatch:
jobs:
@@ -22,36 +22,24 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
env:
NDK_CCACHE: ccache
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPILERCHECK: "%compiler% -dumpmachine; %compiler% -dumpversion"
RUSTC_WRAPPER: sccache
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Check out
uses: actions/checkout@v3
with:
submodules: 'recursive'
submodules: "recursive"
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
distribution: "temurin"
java-version: "17"
- name: Set up Python 3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Set up ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ runner.os }}-${{ github.sha }}
restore-keys: ${{ runner.os }}
python-version: "3.x"
- name: Set up sccache
uses: hendrikmuhs/ccache-action@v1.2
@@ -59,6 +47,7 @@ jobs:
variant: sccache
key: ${{ runner.os }}-${{ github.sha }}
restore-keys: ${{ runner.os }}
max-size: 10000M
- name: Cache Gradle dependencies
uses: actions/cache@v3
@@ -106,3 +95,40 @@ jobs:
with:
name: ${{ github.sha }}-symbols
path: app/build/outputs
test:
name: Test on ${{ matrix.api }}
runs-on: macos-latest
needs: build
strategy:
fail-fast: false
matrix:
api: [23, 26, 28, 29, 34]
steps:
- name: Check out
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: "temurin"
java-version: "17"
- name: Set up Python 3
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: ${{ github.sha }}
path: out
- name: AVD test
run: |
brew install coreutils
scripts/avd_test.sh ${{ matrix.api }}

6
.gitmodules vendored
View File

@@ -19,9 +19,6 @@
[submodule "nanopb"]
path = native/src/external/nanopb
url = https://github.com/nanopb/nanopb.git
[submodule "mincrypt"]
path = native/src/external/mincrypt
url = https://github.com/topjohnwu/mincrypt.git
[submodule "pcre"]
path = native/src/external/pcre
url = https://android.googlesource.com/platform/external/pcre
@@ -43,6 +40,9 @@
[submodule "lsplt"]
path = native/src/external/lsplt
url = https://github.com/LSPosed/LSPlt.git
[submodule "system_properties"]
path = native/src/external/system_properties
url = https://github.com/topjohnwu/system_properties.git
[submodule "termux-elf-cleaner"]
path = tools/termux-elf-cleaner
url = https://github.com/termux/termux-elf-cleaner.git

View File

@@ -18,14 +18,15 @@ Some highlight features:
[Github](https://github.com/topjohnwu/Magisk/) is the only source where you can get official Magisk information and downloads.
[![](https://img.shields.io/badge/Magisk-v25.2-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v25.2)
[![](https://img.shields.io/badge/Magisk%20Beta-v25.2-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v25.2)
[![](https://img.shields.io/badge/Magisk-v26.1-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v26.1)
[![](https://img.shields.io/badge/Magisk%20Beta-v26.2-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v26.2)
[![](https://img.shields.io/badge/Magisk-Canary-red)](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-release.apk)
[![](https://img.shields.io/badge/Magisk-Debug-red)](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-debug.apk)
## Useful Links
- [Installation Instruction](https://topjohnwu.github.io/Magisk/install.html)
- [Building and Development](https://topjohnwu.github.io/Magisk/build.html)
- [Magisk Documentation](https://topjohnwu.github.io/Magisk/)
## Bug Reports
@@ -36,30 +37,6 @@ For installation issues, upload both boot image and install logs.<br>
For Magisk issues, upload boot logcat or dmesg.<br>
For Magisk app crashes, record and upload the logcat when the crash occurs.
## Building and Development
- Magisk builds on any OS Android Studio supports. Install Android Studio and do the initial setups.
- Clone sources: `git clone --recurse-submodules https://github.com/topjohnwu/Magisk.git`
- Install Python 3.8+ \
(Windows only: select **'Add Python to PATH'** in installer, and run `pip install colorama` after install)
- Configure to use the JDK bundled in Android Studio:
- macOS: `export JAVA_HOME="/Applications/Android Studio.app/Contents/jre/Contents/Home"`
- Linux: `export PATH="/path/to/androidstudio/jre/bin:$PATH"`
- Windows: Add `C:\Path\To\Android Studio\jre\bin` to environment variable `PATH`
- Set environment variable `ANDROID_SDK_ROOT` to the Android SDK folder (can be found in Android Studio settings)
- Run `./build.py ndk` to let the script download and install NDK for you
- To start building, run `build.py` to see your options. \
For each action, use `-h` to access help (e.g. `./build.py all -h`)
- To start development, open the project with Android Studio. The IDE can be used for both app (Kotlin/Java) and native sources.
- Optionally, set custom configs with `config.prop`. A sample `config.prop.sample` is provided.
## Signing and Distribution
- The certificate of the key used to sign the final Magisk APK product is also directly embedded into some executables. In release builds, Magisk's root daemon will enforce this certificate check and reject and forcefully uninstall any non-matching Magisk apps to protect users from malicious and unverified Magisk APKs.
- To do any development on Magisk itself, switch to an **official debug build and reinstall Magisk** to bypass the signature check.
- To distribute your own Magisk builds signed with your own keys, set your signing configs in `config.prop`.
- Check [Google's Documentation](https://developer.android.com/studio/publish/app-signing.html#generate-key) for more details on generating your own key.
## Translation Contributions
Default string resources for the Magisk app and its stub APK are located here:

View File

@@ -74,13 +74,13 @@ dependencies {
implementation("com.github.topjohnwu:indeterminate-checkbox:1.0.7")
implementation("com.github.topjohnwu:lz4-java:1.7.1")
implementation("com.jakewharton.timber:timber:5.0.1")
implementation("org.bouncycastle:bcpkix-jdk18on:1.72")
implementation("org.bouncycastle:bcpkix-jdk18on:1.76")
implementation("dev.rikka.rikkax.layoutinflater:layoutinflater:1.3.0")
implementation("dev.rikka.rikkax.insets:insets:1.3.0")
implementation("dev.rikka.rikkax.recyclerview:recyclerview-ktx:1.3.1")
implementation("dev.rikka.rikkax.recyclerview:recyclerview-ktx:1.3.2")
implementation("io.noties.markwon:core:4.6.2")
val vLibsu = "5.0.5"
val vLibsu = "5.2.1"
implementation("com.github.topjohnwu.libsu:core:${vLibsu}")
implementation("com.github.topjohnwu.libsu:service:${vLibsu}")
implementation("com.github.topjohnwu.libsu:nio:${vLibsu}")
@@ -90,21 +90,21 @@ dependencies {
implementation("com.squareup.retrofit2:converter-moshi:${vRetrofit}")
implementation("com.squareup.retrofit2:converter-scalars:${vRetrofit}")
val vOkHttp = "4.10.0"
val vOkHttp = "4.11.0"
implementation("com.squareup.okhttp3:okhttp:${vOkHttp}")
implementation("com.squareup.okhttp3:logging-interceptor:${vOkHttp}")
implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:${vOkHttp}")
val vMoshi = "1.14.0"
val vMoshi = "1.15.0"
implementation("com.squareup.moshi:moshi:${vMoshi}")
kapt("com.squareup.moshi:moshi-kotlin-codegen:${vMoshi}")
val vRoom = "2.5.1"
val vRoom = "2.6.0-beta01"
implementation("androidx.room:room-runtime:${vRoom}")
implementation("androidx.room:room-ktx:${vRoom}")
kapt("androidx.room:room-compiler:${vRoom}")
val vNav = "2.5.3"
val vNav = "2.7.1"
implementation("androidx.navigation:navigation-fragment-ktx:${vNav}")
implementation("androidx.navigation:navigation-ui-ktx:${vNav}")
@@ -112,10 +112,10 @@ dependencies {
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.recyclerview:recyclerview:1.3.0")
implementation("androidx.fragment:fragment-ktx:1.5.6")
implementation("androidx.recyclerview:recyclerview:1.3.1")
implementation("androidx.fragment:fragment-ktx:1.6.1")
implementation("androidx.transition:transition:1.4.1")
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.core:core-splashscreen:1.0.0")
implementation("com.google.android.material:material:1.8.0")
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("com.google.android.material:material:1.9.0")
}

View File

@@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" />
<uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION" />

View File

@@ -1,12 +0,0 @@
package androidx.lifecycle;
import android.content.Context;
import androidx.annotation.NonNull;
public class ProcessLifecycleAccessor {
public static void init(@NonNull Context context) {
LifecycleDispatcher.init(context);
ProcessLifecycleOwner.init(context);
}
}

View File

@@ -10,9 +10,9 @@ import androidx.databinding.DataBindingUtil
import androidx.databinding.OnRebindCallback
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.navigation.NavDirections
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.ktx.startAnimations
abstract class BaseFragment<Binding : ViewDataBinding> : Fragment(), ViewModelHolder {
@@ -38,6 +38,9 @@ abstract class BaseFragment<Binding : ViewDataBinding> : Fragment(), ViewModelHo
it.setVariable(BR.viewModel, viewModel)
it.lifecycleOwner = viewLifecycleOwner
}
if (this is MenuProvider) {
activity?.addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.STARTED)
}
savedInstanceState?.let { viewModel.onRestoreState(it) }
return binding.root
}
@@ -67,8 +70,6 @@ abstract class BaseFragment<Binding : ViewDataBinding> : Fragment(), ViewModelHo
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (this is MenuProvider)
activity?.addMenuProvider(this, viewLifecycleOwner)
binding.addOnRebindCallback(object : OnRebindCallback<Binding>() {
override fun onPreBind(binding: Binding): Boolean {
this@BaseFragment.onPreBind(binding)
@@ -92,5 +93,4 @@ abstract class BaseFragment<Binding : ViewDataBinding> : Fragment(), ViewModelHo
fun NavDirections.navigate() {
navigation?.currentDestination?.getAction(actionId)?.let { navigation!!.navigate(this) }
}
}

View File

@@ -5,13 +5,18 @@ import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.res.use
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
import com.google.android.material.snackbar.Snackbar
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.base.BaseActivity
import rikka.insets.WindowInsetsHelper
@@ -97,3 +102,14 @@ abstract class UIActivity<Binding : ViewDataBinding> : BaseActivity(), ViewModel
else -> Unit
}
}
fun ViewGroup.startAnimations() {
val transition = AutoTransition()
.setInterpolator(FastOutSlowInInterpolator())
.setDuration(400)
.excludeTarget(R.id.main_toolbar, true)
TransitionManager.beginDelayedTransition(
this,
transition
)
}

View File

@@ -34,7 +34,8 @@ object VMFactory : ViewModelProvider.Factory {
HomeViewModel::class.java -> HomeViewModel(ServiceLocator.networkService)
LogViewModel::class.java -> LogViewModel(ServiceLocator.logRepo)
SuperuserViewModel::class.java -> SuperuserViewModel(ServiceLocator.policyDB)
InstallViewModel::class.java -> InstallViewModel(ServiceLocator.networkService)
InstallViewModel::class.java ->
InstallViewModel(ServiceLocator.networkService, ServiceLocator.markwon)
SuRequestViewModel::class.java ->
SuRequestViewModel(ServiceLocator.policyDB, ServiceLocator.timeoutPrefs)
else -> modelClass.newInstance()

View File

@@ -5,10 +5,10 @@ import android.app.Application
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import androidx.lifecycle.ProcessLifecycleAccessor
import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.utils.DispatcherExecutor
import com.topjohnwu.magisk.core.utils.ProcessLifecycle
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.core.utils.ShellInit
import com.topjohnwu.magisk.core.utils.refreshLocale
@@ -81,7 +81,7 @@ open class App() : Application() {
override fun onCreate() {
super.onCreate()
ProcessLifecycleAccessor.init(this)
ProcessLifecycle.init(this)
}
override fun onConfigurationChanged(newConfig: Configuration) {

View File

@@ -1,22 +1,19 @@
package com.topjohnwu.magisk.core
import android.annotation.SuppressLint
import android.content.SharedPreferences
import android.util.Xml
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.repository.BoolDBPropertyNoWrite
import com.topjohnwu.magisk.core.repository.DBConfig
import com.topjohnwu.magisk.core.repository.PreferenceConfig
import com.topjohnwu.magisk.core.utils.refreshLocale
import com.topjohnwu.magisk.ui.theme.Theme
import kotlinx.coroutines.GlobalScope
import org.xmlpull.v1.XmlPullParser
import java.io.File
import java.io.InputStream
object Config : PreferenceConfig, DBConfig {
@@ -25,13 +22,12 @@ object Config : PreferenceConfig, DBConfig {
override val context get() = ServiceLocator.deContext
override val coroutineScope get() = GlobalScope
@get:SuppressLint("ApplySharedPref")
val prefsFile: File get() {
// Flush prefs to disk
prefs.edit().apply {
remove(Key.ASKED_HOME)
}.commit()
return File("${context.filesDir.parent}/shared_prefs", "${fileName}.xml")
private val prefsFile = File("${context.filesDir.parent}/shared_prefs", "${fileName}.xml")
@SuppressLint("ApplySharedPref")
fun getPrefsFile(): File {
prefs.edit().remove(Key.ASKED_HOME).commit()
return prefsFile
}
object Key {
@@ -118,7 +114,6 @@ object Config : PreferenceConfig, DBConfig {
@JvmField var keepVerity = false
@JvmField var keepEnc = false
@JvmField var patchVbmeta = false
@JvmField var recovery = false
var bootId by preference(Key.BOOT_ID, "")
@@ -172,9 +167,8 @@ object Config : PreferenceConfig, DBConfig {
fun load(pkg: String?) {
// Only try to load prefs when fresh install and a previous package name is set
if (pkg != null && prefs.all.isEmpty()) runCatching {
context.contentResolver.openInputStream(Provider.preferencesUri(pkg))?.use {
prefs.edit { parsePrefs(it) }
}
context.contentResolver.openInputStream(Provider.preferencesUri(pkg))?.writeTo(prefsFile)
return
}
prefs.edit {
@@ -191,52 +185,4 @@ object Config : PreferenceConfig, DBConfig {
}
}
}
private fun SharedPreferences.Editor.parsePrefs(input: InputStream) {
runCatching {
val parser = Xml.newPullParser()
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
parser.setInput(input, "UTF-8")
parser.nextTag()
parser.require(XmlPullParser.START_TAG, null, "map")
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.eventType != XmlPullParser.START_TAG)
continue
val key: String = parser.getAttributeValue(null, "name")
fun value() = parser.getAttributeValue(null, "value")!!
when (parser.name) {
"string" -> {
parser.require(XmlPullParser.START_TAG, null, "string")
putString(key, parser.nextText())
parser.require(XmlPullParser.END_TAG, null, "string")
}
"boolean" -> {
parser.require(XmlPullParser.START_TAG, null, "boolean")
putBoolean(key, value().toBoolean())
parser.nextTag()
parser.require(XmlPullParser.END_TAG, null, "boolean")
}
"int" -> {
parser.require(XmlPullParser.START_TAG, null, "int")
putInt(key, value().toInt())
parser.nextTag()
parser.require(XmlPullParser.END_TAG, null, "int")
}
"long" -> {
parser.require(XmlPullParser.START_TAG, null, "long")
putLong(key, value().toLong())
parser.nextTag()
parser.require(XmlPullParser.END_TAG, null, "long")
}
"float" -> {
parser.require(XmlPullParser.START_TAG, null, "int")
putFloat(key, value().toFloat())
parser.nextTag()
parser.require(XmlPullParser.END_TAG, null, "int")
}
else -> parser.next()
}
}
}
}
}

View File

@@ -13,8 +13,8 @@ import android.util.DisplayMetrics
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.unwrap
import com.topjohnwu.magisk.core.utils.syncLocale
import com.topjohnwu.magisk.ktx.unwrap
lateinit var AppApkPath: String

View File

@@ -1,14 +1,13 @@
package com.topjohnwu.magisk.core
import android.os.Build
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.getProperty
import com.topjohnwu.magisk.core.model.UpdateInfo
import com.topjohnwu.magisk.core.repository.NetworkService
import com.topjohnwu.magisk.core.utils.NetworkObserver
import com.topjohnwu.magisk.ktx.getProperty
import com.topjohnwu.superuser.ShellUtils.fastCmd
val isRunningAsStub get() = Info.stub != null
@@ -28,17 +27,17 @@ object Info {
// Device state
@JvmStatic val env by lazy { loadState() }
@JvmField var isSAR = false
var legacySAR = false
var isAB = false
@JvmField val isZygiskEnabled = System.getenv("ZYGISK_ENABLED") == "1"
@JvmStatic val isFDE get() = crypto == "block"
@JvmField var ramdisk = false
@JvmField var vbmeta = false
var patchBootVbmeta = false
var crypto = ""
var noDataExec = false
var isRooted = false
@JvmField var hasGMS = true
val isSamsung = Build.MANUFACTURER.equals("samsung", ignoreCase = true)
@JvmField val isEmulator =
getProperty("ro.kernel.qemu", "0") == "1" ||
getProperty("ro.boot.qemu", "0") == "1"
@@ -52,6 +51,11 @@ object Info {
}
}
val showSuperUser: Boolean get() {
return env.isActive && (Const.USER_ID == 0
|| Config.suMultiuserMode == Config.Value.MULTIUSER_MODE_USER)
}
private fun loadState(): Env {
val v = fastCmd("magisk -v").split(":".toRegex())
return Env(

View File

@@ -16,7 +16,7 @@ class Provider : BaseProvider() {
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? {
return when (uri.encodedPath ?: return null) {
"/prefs_file" -> ParcelFileDescriptor.open(Config.prefsFile, MODE_READ_ONLY)
"/prefs_file" -> ParcelFileDescriptor.open(Config.getPrefsFile(), MODE_READ_ONLY)
else -> super.openFile(uri, mode)
}
}

View File

@@ -18,10 +18,10 @@ import androidx.activity.result.contract.ActivityResultContracts.RequestPermissi
import androidx.appcompat.app.AppCompatActivity
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.reflectField
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.utils.RequestInstall
import com.topjohnwu.magisk.core.wrap
import com.topjohnwu.magisk.ktx.reflectField
import com.topjohnwu.magisk.utils.Utils
interface ContentResultCallback: ActivityResultCallback<Uri>, Parcelable {
fun onActivityLaunch() {}
@@ -110,7 +110,7 @@ abstract class BaseActivity : AppCompatActivity() {
getContent.launch(type)
callback.onActivityLaunch()
} catch (e: ActivityNotFoundException) {
Utils.toast(R.string.app_not_found, Toast.LENGTH_SHORT)
toast(R.string.app_not_found, Toast.LENGTH_SHORT)
}
}

View File

@@ -1,15 +1,27 @@
package com.topjohnwu.magisk.core.data
import androidx.room.*
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.topjohnwu.magisk.core.model.su.SuLog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.*
@Database(version = 1, entities = [SuLog::class], exportSchema = false)
@Database(version = 2, entities = [SuLog::class], exportSchema = false)
abstract class SuLogDatabase : RoomDatabase() {
abstract fun suLogDao(): SuLogDao
companion object {
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) = with(database) {
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 ''")
}
}
}
}
@Dao

View File

@@ -1,6 +1,6 @@
package com.topjohnwu.magisk.core.data.magiskdb
import com.topjohnwu.magisk.ktx.await
import com.topjohnwu.magisk.core.ktx.await
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

View File

@@ -9,9 +9,10 @@ import com.topjohnwu.magisk.core.data.SuLogDatabase
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.data.magiskdb.SettingsDao
import com.topjohnwu.magisk.core.data.magiskdb.StringDao
import com.topjohnwu.magisk.core.ktx.deviceProtectedContext
import com.topjohnwu.magisk.core.repository.LogRepository
import com.topjohnwu.magisk.core.repository.NetworkService
import com.topjohnwu.magisk.ktx.deviceProtectedContext
import com.topjohnwu.magisk.core.utils.BiometricHelper
import io.noties.markwon.Markwon
import io.noties.markwon.utils.NoCopySpannableFactory
@@ -23,6 +24,7 @@ object ServiceLocator {
lateinit var context: Context
val deContext by lazy { context.deviceProtectedContext }
val timeoutPrefs by lazy { deContext.getSharedPreferences("su_timeout", 0) }
val biometrics by lazy { BiometricHelper(context) }
// Database
val policyDB = PolicyDao()
@@ -45,6 +47,7 @@ object ServiceLocator {
private fun createSuLogDatabase(context: Context) =
Room.databaseBuilder(context, SuLogDatabase::class.java, "sulogs.db")
.addMigrations(SuLogDatabase.MIGRATION_1_2)
.fallbackToDestructiveMigration()
.build()

View File

@@ -17,10 +17,10 @@ import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.core.intent
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.*
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.ktx.*
import com.topjohnwu.magisk.utils.APKInstall
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers

View File

@@ -7,8 +7,8 @@ import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseService
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.synchronized
import com.topjohnwu.magisk.core.utils.ProgressInputStream
import com.topjohnwu.magisk.ktx.synchronized
import com.topjohnwu.magisk.view.Notifications
import okhttp3.ResponseBody
import java.io.InputStream

View File

@@ -9,10 +9,10 @@ import android.os.Parcelable
import androidx.core.net.toUri
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.cachedFile
import com.topjohnwu.magisk.core.model.MagiskJson
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.ktx.cachedFile
import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.magisk.view.Notifications
import kotlinx.parcelize.IgnoredOnParcel

View File

@@ -1,4 +1,4 @@
package com.topjohnwu.magisk.ktx
package com.topjohnwu.magisk.core.ktx
import android.annotation.SuppressLint
import android.app.Activity
@@ -6,36 +6,26 @@ import android.content.*
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.LayerDrawable
import android.net.Uri
import android.os.Build
import android.os.Build.VERSION.SDK_INT
import android.os.Process
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.utils.APKInstall
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.internal.UiThreadHandler
import java.io.File
import kotlin.Array
import kotlin.String
import java.lang.reflect.Array as JArray
fun Context.rawResource(id: Int) = resources.openRawResource(id)
@@ -61,110 +51,6 @@ val Context.deviceProtectedContext: Context get() =
createDeviceProtectedStorageContext()
} else { this }
fun Intent.startActivityWithRoot() {
val args = mutableListOf("am", "start", "--user", Const.USER_ID.toString())
val cmd = toCommand(args).joinToString(" ")
Shell.cmd(cmd).submit()
}
fun Intent.toCommand(args: MutableList<String> = mutableListOf()): MutableList<String> {
action?.also {
args.add("-a")
args.add(it)
}
component?.also {
args.add("-n")
args.add(it.flattenToString())
}
data?.also {
args.add("-d")
args.add(it.toString())
}
categories?.also {
for (cat in it) {
args.add("-c")
args.add(cat)
}
}
type?.also {
args.add("-t")
args.add(it)
}
extras?.also {
loop@ for (key in it.keySet()) {
val v = it[key] ?: continue
var value: Any = v
val arg: String
when {
v is String -> arg = "--es"
v is Boolean -> arg = "--ez"
v is Int -> arg = "--ei"
v is Long -> arg = "--el"
v is Float -> arg = "--ef"
v is Uri -> arg = "--eu"
v is ComponentName -> {
arg = "--ecn"
value = v.flattenToString()
}
v is List<*> -> {
if (v.isEmpty())
continue@loop
arg = if (v[0] is Int)
"--eial"
else if (v[0] is Long)
"--elal"
else if (v[0] is Float)
"--efal"
else if (v[0] is String)
"--esal"
else
continue@loop /* Unsupported */
val sb = StringBuilder()
for (o in v) {
sb.append(o.toString().replace(",", "\\,"))
sb.append(',')
}
// Remove trailing comma
sb.deleteCharAt(sb.length - 1)
value = sb
}
v.javaClass.isArray -> {
arg = if (v is IntArray)
"--eia"
else if (v is LongArray)
"--ela"
else if (v is FloatArray)
"--efa"
else if (v is Array<*> && v.isArrayOf<String>())
"--esa"
else
continue@loop /* Unsupported */
val sb = StringBuilder()
val len = JArray.getLength(v)
for (i in 0 until len) {
sb.append(JArray.get(v, i)!!.toString().replace(",", "\\,"))
sb.append(',')
}
// Remove trailing comma
sb.deleteCharAt(sb.length - 1)
value = sb
}
else -> continue@loop
} /* Unsupported */
args.add(arg)
args.add(key)
args.add(value.toString())
}
}
args.add("-f")
args.add(flags.toString())
return args
}
fun Context.cachedFile(name: String) = File(cacheDir, name)
fun ApplicationInfo.getLabel(pm: PackageManager): String {
@@ -188,10 +74,6 @@ fun Context.unwrap(): Context {
return context
}
fun Context.hasPermissions(vararg permissions: String) = permissions.all {
ContextCompat.checkSelfPermission(this, it) == PERMISSION_GRANTED
}
fun Activity.hideKeyboard() {
val view = currentFocus ?: return
getSystemService<InputMethodManager>()
@@ -199,17 +81,6 @@ fun Activity.hideKeyboard() {
view.clearFocus()
}
fun ViewGroup.startAnimations() {
val transition = AutoTransition()
.setInterpolator(FastOutSlowInInterpolator())
.setDuration(400)
.excludeTarget(R.id.main_toolbar, true)
TransitionManager.beginDelayedTransition(
this,
transition
)
}
val View.activity: Activity get() {
var context = context
while(true) {
@@ -271,3 +142,11 @@ fun Context.selfLaunchIntent(): Intent {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
return intent
}
fun Context.toast(msg: CharSequence, duration: Int) {
UiThreadHandler.run { Toast.makeText(this, msg, duration).show() }
}
fun Context.toast(resId: Int, duration: Int) {
UiThreadHandler.run { Toast.makeText(this, resId, duration).show() }
}

View File

@@ -1,4 +1,4 @@
package com.topjohnwu.magisk.ktx
package com.topjohnwu.magisk.core.ktx
import androidx.collection.SparseArrayCompat
import com.topjohnwu.magisk.core.utils.currentLocale
@@ -11,7 +11,7 @@ import java.io.OutputStream
import java.lang.reflect.Field
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
import java.util.Collections
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream

View File

@@ -1,8 +1,6 @@
package com.topjohnwu.magisk.ktx
package com.topjohnwu.magisk.core.ktx
import android.content.Context
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -15,12 +13,4 @@ fun reboot(reason: String = if (Config.recovery) "recovery" else "") {
Shell.cmd("/system/bin/svc power reboot $reason || /system/bin/reboot $reason").submit()
}
fun relaunchApp(context: Context) {
val intent = context.packageManager.getLaunchIntentForPackage(context.packageName) ?: return
val args = mutableListOf("am", "start", "--user", Const.USER_ID.toString())
val cmd = intent.toCommand(args).joinToString(separator = " ")
Shell.cmd("run_delay 1 \"$cmd\"").exec()
Runtime.getRuntime().exit(0)
}
suspend fun Shell.Job.await() = withContext(Dispatchers.IO) { exec() }

View File

@@ -4,7 +4,7 @@ import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.topjohnwu.magisk.ktx.getLabel
import com.topjohnwu.magisk.core.ktx.getLabel
@Entity(tableName = "logs")
class SuLog(
@@ -14,7 +14,10 @@ class SuLog(
val packageName: String,
val appName: String,
val command: String,
val action: Boolean,
val action: Int,
val target: Int,
val context: String,
val gids: String,
val time: Long = System.currentTimeMillis()
) {
@PrimaryKey(autoGenerate = true) var id: Int = 0
@@ -25,7 +28,10 @@ fun PackageManager.createSuLog(
toUid: Int,
fromPid: Int,
command: String,
policy: Int
policy: Int,
target: Int,
context: String,
gids: String,
): SuLog {
val appInfo = info.applicationInfo
return SuLog(
@@ -35,7 +41,10 @@ fun PackageManager.createSuLog(
packageName = getNameForUid(appInfo.uid)!!,
appName = appInfo.getLabel(this),
command = command,
action = policy == SuPolicy.ALLOW
action = policy,
target = target,
context = context,
gids = gids,
)
}
@@ -44,7 +53,10 @@ fun createSuLog(
toUid: Int,
fromPid: Int,
command: String,
policy: Int
policy: Int,
target: Int,
context: String,
gids: String,
): SuLog {
return SuLog(
fromUid = fromUid,
@@ -53,6 +65,9 @@ fun createSuLog(
packageName = "[UID] $fromUid",
appName = "[UID] $fromUid",
command = command,
action = policy == SuPolicy.ALLOW
action = policy,
target = target,
context = context,
gids = gids,
)
}

View File

@@ -3,8 +3,8 @@ package com.topjohnwu.magisk.core.repository
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.data.SuLogDao
import com.topjohnwu.magisk.core.ktx.await
import com.topjohnwu.magisk.core.model.su.SuLog
import com.topjohnwu.magisk.ktx.await
import com.topjohnwu.superuser.Shell

View File

@@ -7,11 +7,11 @@ import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.getLabel
import com.topjohnwu.magisk.core.ktx.getPackageInfo
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.core.model.su.createSuLog
import com.topjohnwu.magisk.ktx.getLabel
import com.topjohnwu.magisk.ktx.getPackageInfo
import com.topjohnwu.magisk.utils.Utils
import kotlinx.coroutines.runBlocking
import timber.log.Timber
@@ -57,17 +57,20 @@ object SuCallbackHandler {
val toUid = data.getIntComp("to.uid", -1)
val pid = data.getIntComp("pid", -1)
val command = data.getString("command", "")
val target = data.getIntComp("target", -1)
val seContext = data.getString("context", "")
val gids = data.getString("gids", "")
val pm = context.packageManager
val log = runCatching {
pm.getPackageInfo(fromUid, pid)?.let {
pm.createSuLog(it, toUid, pid, command, policy)
pm.createSuLog(it, toUid, pid, command, policy, target, seContext, gids)
}
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy)
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids)
if (notify)
notify(context, log.action, log.appName)
notify(context, log.action == SuPolicy.ALLOW, log.appName)
runBlocking { ServiceLocator.logRepo.insert(log) }
}
@@ -93,7 +96,7 @@ object SuCallbackHandler {
else
R.string.su_deny_toast
Utils.toast(context.getString(resId, appName), Toast.LENGTH_SHORT)
context.toast(context.getString(resId, appName), Toast.LENGTH_SHORT)
}
}
}

View File

@@ -6,13 +6,14 @@ import android.content.pm.PackageManager
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.ktx.getPackageInfo
import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.ktx.getPackageInfo
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.DataOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.concurrent.TimeUnit
@@ -22,7 +23,7 @@ class SuRequestHandler(
private val policyDB: PolicyDao
) {
private lateinit var output: DataOutputStream
private lateinit var output: File
private lateinit var policy: SuPolicy
lateinit var pkgInfo: PackageInfo
private set
@@ -52,37 +53,27 @@ class SuRequestHandler(
return true
}
private fun close() {
if (::output.isInitialized)
runCatching { output.close() }
}
private suspend fun init(intent: Intent) = withContext(Dispatchers.IO) {
try {
val fifo = intent.getStringExtra("fifo") ?: throw IOException("fifo == null")
output = DataOutputStream(FileOutputStream(fifo))
val uid = intent.getIntExtra("uid", -1)
if (uid <= 0) {
throw IOException("uid == $uid")
}
policy = SuPolicy(uid)
val pid = intent.getIntExtra("pid", -1)
try {
pkgInfo = pm.getPackageInfo(uid, pid) ?: PackageInfo().apply {
val name = pm.getNameForUid(uid) ?: throw PackageManager.NameNotFoundException()
// We only fill in sharedUserId and leave other fields uninitialized
sharedUserId = name.split(":")[0]
}
return@withContext true
} catch (e: PackageManager.NameNotFoundException) {
respond(SuPolicy.DENY, -1)
return@withContext false
}
} catch (e: IOException) {
Timber.e(e)
close()
return@withContext false
private suspend fun init(intent: Intent): Boolean {
val uid = intent.getIntExtra("uid", -1)
val pid = intent.getIntExtra("pid", -1)
val fifo = intent.getStringExtra("fifo")
if (uid <= 0 || pid <= 0 || fifo == null) {
return false
}
output = File(fifo)
policy = SuPolicy(uid)
try {
pkgInfo = pm.getPackageInfo(uid, pid) ?: PackageInfo().apply {
val name = pm.getNameForUid(uid) ?: throw PackageManager.NameNotFoundException()
// We only fill in sharedUserId and leave other fields uninitialized
sharedUserId = name.split(":")[0]
}
} catch (e: PackageManager.NameNotFoundException) {
Timber.e(e)
respond(SuPolicy.DENY, -1)
return false
}
return output.canWrite()
}
suspend fun respond(action: Int, time: Int) {
@@ -97,14 +88,15 @@ class SuRequestHandler(
withContext(Dispatchers.IO) {
try {
output.writeInt(policy.policy)
output.flush()
DataOutputStream(FileOutputStream(output)).use {
it.writeInt(policy.policy)
it.flush()
}
} catch (e: IOException) {
Timber.e(e)
} finally {
close()
if (until >= 0)
policyDB.update(policy)
}
if (until >= 0) {
policyDB.update(policy)
}
}
}

View File

@@ -4,10 +4,10 @@ import android.net.Uri
import androidx.core.net.toFile
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
import com.topjohnwu.magisk.core.utils.unzip
import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

View File

@@ -11,14 +11,14 @@ import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Provider
import com.topjohnwu.magisk.core.ktx.await
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.utils.AXML
import com.topjohnwu.magisk.core.utils.Keygen
import com.topjohnwu.magisk.ktx.await
import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.magisk.signing.JarMap
import com.topjohnwu.magisk.signing.SignApk
import com.topjohnwu.magisk.utils.APKInstall
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Runnable
@@ -214,7 +214,7 @@ object HideAPK {
}
val onFailure = Runnable {
dialog.dismiss()
Utils.toast(R.string.failure, Toast.LENGTH_LONG)
activity.toast(R.string.failure, Toast.LENGTH_LONG)
}
val success = withContext(Dispatchers.IO) {
patchAndHide(activity, label, onFailure)
@@ -232,7 +232,7 @@ object HideAPK {
}
val onFailure = Runnable {
dialog.dismiss()
Utils.toast(R.string.failure, Toast.LENGTH_LONG)
activity.toast(R.string.failure, Toast.LENGTH_LONG)
}
val apk = StubApk.current(activity)
val session = APKInstall.startSession(activity, APPLICATION_ID, onFailure) {

View File

@@ -1,24 +1,30 @@
package com.topjohnwu.magisk.core.tasks
import android.net.Uri
import android.system.ErrnoException
import android.system.Os
import android.system.OsConstants
import android.system.OsConstants.O_WRONLY
import android.widget.Toast
import androidx.annotation.WorkerThread
import androidx.core.os.postDelayed
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.*
import com.topjohnwu.magisk.core.AppApkPath
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
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.copyAndClose
import com.topjohnwu.magisk.core.ktx.reboot
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.ktx.reboot
import com.topjohnwu.magisk.ktx.withStreams
import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.magisk.signing.SignBoot
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import com.topjohnwu.superuser.internal.NOPList
@@ -40,6 +46,7 @@ import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
abstract class MagiskInstallImpl protected constructor(
protected val console: MutableList<String> = NOPList.getInstance(),
@@ -111,7 +118,9 @@ abstract class MagiskInstallImpl protected constructor(
val name = n.substring(3, n.length - 3)
val dest = File(installDir, name)
zf.getInputStream(it).writeTo(dest)
dest.setExecutable(true)
}
zf.close()
} else {
val info = context.applicationInfo
var libs = File(info.nativeLibraryDir).listFiles { _, name ->
@@ -119,7 +128,8 @@ abstract class MagiskInstallImpl protected constructor(
} ?: emptyArray()
// Also symlink magisk32 on non 64-bit only 64-bit devices
val lib32 = info.javaClass.getDeclaredField("secondaryNativeLibraryDir").get(info) as String?
val lib32 = info.javaClass.getDeclaredField("secondaryNativeLibraryDir")
.get(info) as String?
if (lib32 != null) {
libs += File(lib32, "libmagisk32.so")
}
@@ -164,102 +174,215 @@ abstract class MagiskInstallImpl protected constructor(
return true
}
private fun InputStream.cleanPump(out: OutputStream) = withStreams(this, out) { src, _ ->
src.copyTo(out)
}
private fun InputStream.copyAndCloseOut(out: OutputStream) = out.use { copyTo(it) }
private fun newTarEntry(name: String, size: Long): TarEntry {
console.add("-- Writing: $name")
return TarEntry(TarHeader.createHeader(name, size, 0, false, 420 /* 0644 */))
}
private class LZ4InputStream(s: InputStream) : LZ4FrameInputStream(s) {
// Workaround bug in LZ4FrameInputStream
override fun available() = 0
}
private class NoBootException : IOException()
@Throws(IOException::class)
private fun processTar(input: InputStream, output: OutputStream): OutputStream {
private fun processTar(tarIn: TarInputStream, tarOut: TarOutputStream): ExtendedFile {
console.add("- Processing tar file")
val tarOut = TarOutputStream(output)
TarInputStream(input).use { tarIn ->
lateinit var entry: TarEntry
lateinit var entry: TarEntry
fun decompressedStream(): InputStream {
val src = if (entry.name.endsWith(".lz4")) LZ4FrameInputStream(tarIn) else tarIn
return object : FilterInputStream(src) {
override fun available() = 0 /* Workaround bug in LZ4FrameInputStream */
override fun close() { /* Never close src stream */ }
}
}
fun decompressedStream(): InputStream {
return if (entry.name.endsWith(".lz4")) LZ4InputStream(tarIn) else tarIn
}
while (tarIn.nextEntry?.let { entry = it } != null) {
if (entry.name.startsWith("boot.img") ||
entry.name.startsWith("init_boot.img") ||
(Config.recovery && entry.name.contains("recovery.img"))) {
val name = entry.name.replace(".lz4", "")
console.add("-- Extracting: $name")
while (tarIn.nextEntry?.let { entry = it } != null) {
if (entry.name.startsWith("boot.img") ||
entry.name.startsWith("init_boot.img") ||
(Config.recovery && entry.name.contains("recovery.img"))) {
val name = entry.name.replace(".lz4", "")
console.add("-- Extracting: $name")
val extract = installDir.getChildFile(name)
decompressedStream().cleanPump(extract.newOutputStream())
} else if (entry.name.contains("vbmeta.img")) {
val rawData = decompressedStream().readBytes()
// Valid vbmeta.img should be at least 256 bytes
if (rawData.size < 256)
continue
val extract = installDir.getChildFile(name)
decompressedStream().copyAndCloseOut(extract.newOutputStream())
} else if (entry.name.contains("vbmeta.img")) {
val rawData = decompressedStream().readBytes()
// Valid vbmeta.img should be at least 256 bytes
if (rawData.size < 256)
continue
// Patch flags to AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED |
// AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED
console.add("-- Patching: vbmeta.img")
ByteBuffer.wrap(rawData).putInt(120, 3)
tarOut.putNextEntry(newTarEntry("vbmeta.img", rawData.size.toLong()))
tarOut.write(rawData)
} else {
console.add("-- Copying: ${entry.name}")
tarOut.putNextEntry(entry)
tarIn.copyTo(tarOut, bufferSize = 1024 * 1024)
}
// Patch flags to AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED |
// AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED
console.add("-- Patching: vbmeta.img")
ByteBuffer.wrap(rawData).putInt(120, 3)
tarOut.putNextEntry(newTarEntry("vbmeta.img", rawData.size.toLong()))
tarOut.write(rawData)
// vbmeta partition exist, disable boot vbmeta patch
Info.patchBootVbmeta = false
} else if (entry.name.contains("userdata.img")) {
continue
} else {
console.add("-- Copying: ${entry.name}")
tarOut.putNextEntry(entry)
tarIn.copyTo(tarOut, bufferSize = 1024 * 1024)
}
}
val boot = installDir.getChildFile("boot.img")
val initBoot = installDir.getChildFile("init_boot.img")
val recovery = installDir.getChildFile("recovery.img")
if (Config.recovery && recovery.exists() && boot.exists()) {
// Install to recovery
srcBoot = recovery
// Repack boot image to prevent auto restore
arrayOf(
"cd $installDir",
"chmod -R 755 .",
"./magiskboot unpack boot.img",
"./magiskboot repack boot.img",
"cat new-boot.img > boot.img",
"./magiskboot cleanup",
"rm -f new-boot.img",
"cd /").sh()
boot.newInputStream().use {
tarOut.putNextEntry(newTarEntry("boot.img", boot.length()))
fun ExtendedFile.copyToTar() {
newInputStream().use {
tarOut.putNextEntry(newTarEntry(name, length()))
it.copyTo(tarOut)
}
boot.delete()
} else {
srcBoot = when {
initBoot.exists() -> initBoot
boot.exists() -> boot
else -> {
console.add("! No boot image found")
throw IOException()
delete()
}
// Patch priority: recovery > init_boot > boot
return when {
recovery.exists() -> {
if (boot.exists()) {
// Repack boot image to prevent auto restore
arrayOf(
"cd $installDir",
"chmod -R 755 .",
"./magiskboot unpack boot.img",
"./magiskboot repack boot.img",
"cat new-boot.img > boot.img",
"./magiskboot cleanup",
"rm -f new-boot.img",
"cd /").sh()
boot.copyToTar()
}
recovery
}
initBoot.exists() -> {
if (boot.exists())
boot.copyToTar()
initBoot
}
boot.exists() -> boot
else -> throw NoBootException()
}
}
@Throws(IOException::class)
private fun processZip(zipIn: ZipInputStream): ExtendedFile {
console.add("- Processing zip file")
val boot = installDir.getChildFile("boot.img")
val initBoot = installDir.getChildFile("init_boot.img")
lateinit var entry: ZipEntry
while (zipIn.nextEntry?.also { entry = it } != null) {
if (entry.isDirectory) continue
when (entry.name.substringAfterLast('/')) {
"payload.bin" -> {
try {
return processPayload(zipIn)
} catch (e: IOException) {
// No boot image in payload.bin, continue to find boot images
}
}
"init_boot.img" -> {
console.add("- Extracting init_boot.img")
zipIn.copyAndCloseOut(initBoot.newOutputStream())
return initBoot
}
"boot.img" -> {
console.add("- Extracting boot.img")
zipIn.copyAndCloseOut(boot.newOutputStream())
// Don't return here since there might be an init_boot.img
}
}
}
return tarOut
if (boot.exists()) {
return boot
} else {
throw NoBootException()
}
}
@Throws(IOException::class)
private fun processPayload(input: InputStream): ExtendedFile {
var fifo: File? = null
try {
console.add("- Processing payload.bin")
fifo = File.createTempFile("payload-fifo-", null, installDir)
fifo.delete()
Os.mkfifo(fifo.path, 420 /* 0644 */)
// Enqueue the shell command first, or the subsequent FIFO open will block
val future = arrayOf(
"cd $installDir",
"./magiskboot extract $fifo",
"cd /"
).eq()
val fd = Os.open(fifo.path, O_WRONLY, 0)
try {
val bufSize = 1024 * 1024
val buf = ByteBuffer.allocate(bufSize)
buf.position(input.read(buf.array()).coerceAtLeast(0)).flip()
while (buf.hasRemaining()) {
try {
Os.write(fd, buf)
} catch (e: ErrnoException) {
if (e.errno != OsConstants.EPIPE)
throw e
// If SIGPIPE, then the other side is closed, we're done
break
}
if (!buf.hasRemaining()) {
buf.limit(bufSize)
buf.position(input.read(buf.array()).coerceAtLeast(0)).flip()
}
}
} finally {
Os.close(fd)
}
val success = try { future.get().isSuccess } catch (e: Exception) { false }
if (!success) {
console.add("! Error while extracting payload.bin")
throw IOException()
}
val boot = installDir.getChildFile("boot.img")
val initBoot = installDir.getChildFile("init_boot.img")
return when {
initBoot.exists() -> {
console.add("-- Extract init_boot.img")
initBoot
}
boot.exists() -> {
console.add("-- Extract boot.img")
boot
}
else -> {
throw NoBootException()
}
}
} catch (e: ErrnoException) {
throw IOException(e)
} finally {
fifo?.delete()
}
}
private fun handleFile(uri: Uri): Boolean {
val outStream: OutputStream
var outFile: MediaStoreUtils.UriFile? = null
val outFile: MediaStoreUtils.UriFile
// Process input file
try {
uri.inputStream().buffered().use { src ->
src.mark(500)
val magic = ByteArray(5)
if (src.skip(257) != 257L || src.read(magic) != magic.size) {
val magic = ByteArray(4)
val tarMagic = ByteArray(5)
if (src.read(magic) != magic.size || src.skip(253) != 253L ||
src.read(tarMagic) != tarMagic.size
) {
console.add("! Invalid input file")
return false
}
@@ -275,29 +398,52 @@ abstract class MagiskInstallImpl protected constructor(
toString()
}
outStream = if (magic.contentEquals("ustar".toByteArray())) {
srcBoot = if (tarMagic.contentEquals("ustar".toByteArray())) {
// tar file
outFile = MediaStoreUtils.getFile("$filename.tar", true)
processTar(src, outFile!!.uri.outputStream())
outStream = TarOutputStream(outFile.uri.outputStream())
try {
processTar(TarInputStream(src), outStream)
} catch (e: IOException) {
outStream.close()
outFile.delete()
throw e
}
} else {
// raw image
srcBoot = installDir.getChildFile("boot.img")
console.add("- Copying image to cache")
src.cleanPump(srcBoot.newOutputStream())
outFile = MediaStoreUtils.getFile("$filename.img", true)
outFile!!.uri.outputStream()
outStream = outFile.uri.outputStream()
try {
if (magic.contentEquals("CrAU".toByteArray())) {
processPayload(src)
} else if (magic.contentEquals("PK\u0003\u0004".toByteArray())) {
processZip(ZipInputStream(src))
} else {
console.add("- Copying image to cache")
installDir.getChildFile("boot.img").also {
src.copyAndCloseOut(it.newOutputStream())
}
}
} catch (e: IOException) {
outStream.close()
outFile.delete()
throw e
}
}
}
} catch (e: IOException) {
if (e is NoBootException)
console.add("! No boot image found")
console.add("! Process error")
outFile?.delete()
Timber.e(e)
return false
}
// Patch file
if (!patchBoot()) {
outFile!!.delete()
outFile.delete()
return false
}
@@ -314,7 +460,7 @@ abstract class MagiskInstallImpl protected constructor(
}
outStream.putNextEntry(newTarEntry(name, newBoot.length()))
}
newBoot.newInputStream().cleanPump(outStream)
newBoot.newInputStream().copyAndClose(outStream)
newBoot.delete()
console.add("")
@@ -324,7 +470,7 @@ abstract class MagiskInstallImpl protected constructor(
console.add("****************************")
} catch (e: IOException) {
console.add("! Failed to output to $outFile")
outFile!!.delete()
outFile.delete()
Timber.e(e)
return false
}
@@ -337,22 +483,6 @@ abstract class MagiskInstallImpl protected constructor(
}
private fun patchBoot(): Boolean {
var isSigned = false
if (!srcBoot.isCharacter) {
try {
srcBoot.newInputStream().use {
if (SignBoot.verifySignature(it, null)) {
isSigned = true
console.add("- Boot image is signed with AVB 1.0")
}
}
} catch (e: IOException) {
console.add("! Unable to check signature")
Timber.e(e)
return false
}
}
val newBoot = installDir.getChildFile("new-boot.img")
if (!useRootDir) {
// Create output files before hand
@@ -364,34 +494,15 @@ abstract class MagiskInstallImpl protected constructor(
"cd $installDir",
"KEEPFORCEENCRYPT=${Config.keepEnc} " +
"KEEPVERITY=${Config.keepVerity} " +
"PATCHVBMETAFLAG=${Config.patchVbmeta} " +
"PATCHVBMETAFLAG=${Info.patchBootVbmeta} " +
"RECOVERYMODE=${Config.recovery} " +
"SYSTEM_ROOT=${Info.isSAR} " +
"LEGACYSAR=${Info.legacySAR} " +
"sh boot_patch.sh $srcBoot")
val isSuccess = cmds.sh().isSuccess
if (!cmds.sh().isSuccess)
return false
shell.newJob().add("./magiskboot cleanup", "cd /").exec()
val job = shell.newJob().add("./magiskboot cleanup", "cd /")
if (isSigned) {
console.add("- Signing boot image with verity keys")
val signed = File.createTempFile("signed", ".img", context.cacheDir)
try {
val src = newBoot.newInputStream().buffered()
val out = signed.outputStream().buffered()
withStreams(src, out) { _, _ ->
SignBoot.doSignature(null, null, src, out, "/boot")
}
} catch (e: IOException) {
console.add("! Unable to sign image")
Timber.e(e)
return false
}
job.add("cat $signed > $newBoot", "rm -f $signed")
}
job.exec()
return true
return isSuccess
}
private fun flashBoot() = "direct_install $installDir $srcBoot".sh().isSuccess
@@ -413,6 +524,7 @@ abstract class MagiskInstallImpl protected constructor(
return true
}
private fun Array<String>.eq() = shell.newJob().add(*this).to(console, logs).enqueue()
private fun String.sh() = shell.newJob().add(this).to(console, logs).exec()
private fun Array<String>.sh() = shell.newJob().add(*this).to(console, logs).exec()
private fun String.fsh() = ShellUtils.fastCmd(shell, this)
@@ -513,7 +625,7 @@ abstract class MagiskInstaller(
override suspend fun exec(): Boolean {
val success = super.exec()
callback()
Utils.toast(
context.toast(
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
Toast.LENGTH_LONG
)

View File

@@ -1,30 +1,24 @@
package com.topjohnwu.magisk.core.utils
import android.content.Context
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.di.AppContext
object BiometricHelper {
class BiometricHelper(context: Context) {
private val mgr by lazy { BiometricManager.from(AppContext) }
private val mgr = BiometricManager.from(context)
val isSupported get() = when (mgr.canAuthenticate()) {
val isSupported get() = when (mgr.canAuthenticate(Authenticators.BIOMETRIC_WEAK)) {
BiometricManager.BIOMETRIC_SUCCESS -> true
else -> false
}
val isEnabled: Boolean get() {
val enabled = Config.suBiometric
if (enabled && !isSupported) {
Config.suBiometric = false
return false
}
return enabled
}
val isEnabled get() = isSupported && Config.suBiometric
fun authenticate(
activity: FragmentActivity,
@@ -48,7 +42,7 @@ object BiometricHelper {
)
val info = BiometricPrompt.PromptInfo.Builder()
.setConfirmationRequired(true)
.setDeviceCredentialAllowed(false)
.setAllowedAuthenticators(Authenticators.BIOMETRIC_WEAK)
.setTitle(activity.getString(R.string.authenticate))
.setNegativeButtonText(activity.getString(android.R.string.cancel))
.build()

View File

@@ -1,6 +1,10 @@
package com.topjohnwu.magisk.core.utils
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import java.util.concurrent.AbstractExecutorService
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

View File

@@ -14,7 +14,9 @@ import java.security.KeyPairGenerator
import java.security.KeyStore
import java.security.PrivateKey
import java.security.cert.X509Certificate
import java.util.*
import java.util.Calendar
import java.util.Locale
import java.util.Random
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream

View File

@@ -102,6 +102,8 @@ object MediaStoreUtils {
fun Uri.outputStream() = cr.openOutputStream(this, "rwt") ?: throw FileNotFoundException()
fun Uri.fileDescriptor(mode: String) = cr.openFileDescriptor(this, mode) ?: throw FileNotFoundException()
val Uri.displayName: String get() {
if (scheme == "file") {
// Simple uri wrapper over file, directly get file name

View File

@@ -14,7 +14,7 @@ import androidx.core.content.getSystemService
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.topjohnwu.magisk.ktx.registerRuntimeReceiver
import com.topjohnwu.magisk.core.ktx.registerRuntimeReceiver
typealias ConnectionCallback = (Boolean) -> Unit

View File

@@ -0,0 +1,15 @@
package com.topjohnwu.magisk.core.utils;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleDispatcher;
import androidx.lifecycle.ProcessLifecycleOwner;
// Use Java to bypass Kotlin internal visibility modifier
public class ProcessLifecycle {
public static void init(@NonNull Context context) {
LifecycleDispatcher.init(context);
ProcessLifecycleOwner.init$lifecycle_process_release(context);
}
}

View File

@@ -7,10 +7,10 @@ import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.ktx.cachedFile
import com.topjohnwu.magisk.ktx.deviceProtectedContext
import com.topjohnwu.magisk.ktx.rawResource
import com.topjohnwu.magisk.ktx.writeTo
import com.topjohnwu.magisk.core.ktx.cachedFile
import com.topjohnwu.magisk.core.ktx.deviceProtectedContext
import com.topjohnwu.magisk.core.ktx.rawResource
import com.topjohnwu.magisk.core.ktx.writeTo
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import java.io.File
@@ -73,17 +73,17 @@ class ShellInit : Shell.Initializer() {
fun getVar(name: String) = fastCmd("echo \$$name")
fun getBool(name: String) = getVar(name).toBoolean()
Info.isSAR = getBool("SYSTEM_ROOT")
Info.isSAR = getBool("SYSTEM_AS_ROOT")
Info.ramdisk = getBool("RAMDISKEXIST")
Info.vbmeta = getBool("VBMETAEXIST")
Info.isAB = getBool("ISAB")
Info.crypto = getVar("CRYPTOTYPE")
Info.patchBootVbmeta = getBool("PATCHVBMETAFLAG")
Info.legacySAR = getBool("LEGACYSAR")
// Default presets
Config.recovery = getBool("RECOVERYMODE")
Config.keepVerity = getBool("KEEPVERITY")
Config.keepEnc = getBool("KEEPFORCEENCRYPT")
Config.patchVbmeta = getBool("PATCHVBMETAFLAG")
return true
}

View File

@@ -6,22 +6,47 @@ import androidx.databinding.ListChangeRegistry
import androidx.databinding.ObservableList
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListUpdateCallback
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.AbstractList
open class DiffObservableList<T : DiffItem<*>>
: AbstractList<T>(), ObservableList<T>, ListUpdateCallback {
// Only expose the immutable List types
interface DiffList<T : DiffItem<*>> : List<T> {
fun calculateDiff(newItems: List<T>): DiffUtil.DiffResult
@MainThread
fun update(newItems: List<T>, diffResult: DiffUtil.DiffResult)
@WorkerThread
suspend fun update(newItems: List<T>)
}
interface FilterList<T : DiffItem<*>> : List<T> {
fun filter(filter: (T) -> Boolean)
@MainThread
fun set(newItems: List<T>)
}
fun <T : DiffItem<*>> diffList(): DiffList<T> = DiffObservableList()
fun <T : DiffItem<*>> filterList(scope: CoroutineScope): FilterList<T> =
FilterableDiffObservableList(scope)
private open class DiffObservableList<T : DiffItem<*>>
: AbstractList<T>(), ObservableList<T>, DiffList<T>, ListUpdateCallback {
protected var list: List<T> = emptyList()
private set
private val listeners = ListChangeRegistry()
override val size: Int get() = list.size
override fun get(index: Int) = list[index]
fun calculateDiff(newItems: List<T>): DiffUtil.DiffResult {
override fun calculateDiff(newItems: List<T>): DiffUtil.DiffResult {
return doCalculateDiff(list, newItems)
}
@@ -48,13 +73,13 @@ open class DiffObservableList<T : DiffItem<*>>
}
@MainThread
fun update(newItems: List<T>, diffResult: DiffUtil.DiffResult) {
override fun update(newItems: List<T>, diffResult: DiffUtil.DiffResult) {
list = ArrayList(newItems)
diffResult.dispatchUpdatesTo(this)
}
@WorkerThread
suspend fun update(newItems: List<T>) {
override suspend fun update(newItems: List<T>) {
val diffResult = calculateDiff(newItems)
withContext(Dispatchers.Main) {
update(newItems, diffResult)
@@ -87,3 +112,45 @@ open class DiffObservableList<T : DiffItem<*>>
listeners.notifyRemoved(this, position, count)
}
}
private class FilterableDiffObservableList<T : DiffItem<*>>(
private val scope: CoroutineScope
) : DiffObservableList<T>(), FilterList<T> {
private var sublist: List<T> = emptyList()
private var job: Job? = null
private var lastFilter: ((T) -> Boolean)? = null
// ---
override fun filter(filter: (T) -> Boolean) {
lastFilter = filter
job?.cancel()
job = scope.launch(Dispatchers.Default) {
val oldList = sublist
val newList = list.filter(filter)
val diff = doCalculateDiff(oldList, newList)
withContext(Dispatchers.Main) {
sublist = newList
diff.dispatchUpdatesTo(this@FilterableDiffObservableList)
}
}
}
// ---
override fun get(index: Int): T {
return sublist[index]
}
override val size: Int
get() = sublist.size
@MainThread
override fun set(newItems: List<T>) {
onRemoved(0, sublist.size)
list = newItems
sublist = emptyList()
lastFilter?.let { filter(it) }
}
}

View File

@@ -1,39 +0,0 @@
package com.topjohnwu.magisk.databinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
open class FilterableDiffObservableList<T : DiffItem<*>>(
private val scope: CoroutineScope
) : DiffObservableList<T>() {
private var sublist: List<T> = emptyList()
private var job: Job? = null
// ---
fun filter(filter: (T) -> Boolean) {
job?.cancel()
job = scope.launch(Dispatchers.Default) {
val oldList = sublist
val newList = list.filter(filter)
val diff = doCalculateDiff(oldList, newList)
withContext(Dispatchers.Main) {
sublist = newList
diff.dispatchUpdatesTo(this@FilterableDiffObservableList)
}
}
}
// ---
override fun get(index: Int): T {
return sublist[index]
}
override val size: Int
get() = sublist.size
}

View File

@@ -46,11 +46,11 @@ class MergeObservableList<T> : AbstractList<T>(), ObservableList<T> {
return this
}
fun insertList(list: ObservableList<out T>): MergeObservableList<T> {
fun insertList(list: List<T>): MergeObservableList<T> {
val idx = size
lists.add(list)
++modCount
(list as ObservableList<T>).addOnListChangedCallback(callback)
(list as? ObservableList<T>)?.addOnListChangedCallback(callback)
if (list.isNotEmpty())
listeners.notifyInserted(this, idx, list.size)
return this
@@ -72,11 +72,11 @@ class MergeObservableList<T> : AbstractList<T>(), ObservableList<T> {
return false
}
fun removeList(listToRemove: ObservableList<out T>): Boolean {
fun removeList(listToRemove: List<T>): Boolean {
var idx = 0
for ((i, list) in lists.withIndex()) {
if (listToRemove === list) {
(list as ObservableList<T>).removeOnListChangedCallback(callback)
(list as? ObservableList<T>)?.removeOnListChangedCallback(callback)
lists.removeAt(i)
++modCount
listeners.notifyRemoved(this, idx, list.size)
@@ -90,8 +90,8 @@ class MergeObservableList<T> : AbstractList<T>(), ObservableList<T> {
override fun clear() {
val sz = size
for (list in lists) {
if (list is ObservableList<*>) {
(list as ObservableList<T>).removeOnListChangedCallback(callback)
if (list is ObservableList) {
list.removeOnListChangedCallback(callback)
}
}
++modCount

View File

@@ -4,19 +4,19 @@ import android.net.Uri
import com.topjohnwu.magisk.MainDirections
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName
import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.ui.module.ModuleViewModel
import com.topjohnwu.magisk.view.MagiskDialog
class LocalModuleInstallDialog(
private val viewModel: ModuleViewModel,
private val uri: Uri
private val uri: Uri,
private val displayName: String
) : DialogBuilder {
override fun build(dialog: MagiskDialog) {
dialog.apply {
setTitle(R.string.confirm_install_title)
setMessage(context.getString(R.string.confirm_install, uri.displayName))
setMessage(context.getString(R.string.confirm_install, displayName))
setButton(MagiskDialog.ButtonType.POSITIVE) {
text = android.R.string.ok
onClick {

View File

@@ -5,9 +5,9 @@ import android.content.Context
import android.widget.Toast
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.NavigationActivity
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.superuser.Shell
@@ -38,9 +38,9 @@ class UninstallDialog : DialogBuilder {
Shell.cmd("restore_imgs").submit { result ->
dialog.dismiss()
if (result.isSuccess) {
Utils.toast(R.string.restore_done, Toast.LENGTH_SHORT)
context.toast(R.string.restore_done, Toast.LENGTH_SHORT)
} else {
Utils.toast(R.string.restore_fail, Toast.LENGTH_LONG)
context.toast(R.string.restore_fail, Toast.LENGTH_LONG)
}
}
}

View File

@@ -3,7 +3,7 @@ package com.topjohnwu.magisk.events
import com.topjohnwu.magisk.arch.ActivityExecutor
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.di.ServiceLocator
class BiometricEvent(
builder: Builder.() -> Unit
@@ -17,7 +17,7 @@ class BiometricEvent(
}
override fun invoke(activity: UIActivity<*>) {
BiometricHelper.authenticate(
ServiceLocator.biometrics.authenticate(
activity,
onError = listenerOnFailure,
onSuccess = listenerOnSuccess

View File

@@ -1,115 +0,0 @@
package com.topjohnwu.magisk.signing;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class CryptoUtils {
static final Map<String, String> ID_TO_ALG;
static final Map<String, String> ALG_TO_ID;
static {
ID_TO_ALG = new HashMap<>();
ALG_TO_ID = new HashMap<>();
ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA256.getId(), "SHA256withECDSA");
ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA384.getId(), "SHA384withECDSA");
ID_TO_ALG.put(X9ObjectIdentifiers.ecdsa_with_SHA512.getId(), "SHA512withECDSA");
ID_TO_ALG.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1withRSA");
ID_TO_ALG.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256withRSA");
ID_TO_ALG.put(PKCSObjectIdentifiers.sha512WithRSAEncryption.getId(), "SHA512withRSA");
ALG_TO_ID.put("SHA256withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256.getId());
ALG_TO_ID.put("SHA384withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384.getId());
ALG_TO_ID.put("SHA512withECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512.getId());
ALG_TO_ID.put("SHA1withRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption.getId());
ALG_TO_ID.put("SHA256withRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption.getId());
ALG_TO_ID.put("SHA512withRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption.getId());
}
static String getSignatureAlgorithm(Key key) throws Exception {
if ("EC".equals(key.getAlgorithm())) {
int curveSize;
KeyFactory factory = KeyFactory.getInstance("EC");
if (key instanceof PublicKey) {
ECPublicKeySpec spec = factory.getKeySpec(key, ECPublicKeySpec.class);
curveSize = spec.getParams().getCurve().getField().getFieldSize();
} else if (key instanceof PrivateKey) {
ECPrivateKeySpec spec = factory.getKeySpec(key, ECPrivateKeySpec.class);
curveSize = spec.getParams().getCurve().getField().getFieldSize();
} else {
throw new InvalidKeySpecException();
}
if (curveSize <= 256) {
return "SHA256withECDSA";
} else if (curveSize <= 384) {
return "SHA384withECDSA";
} else {
return "SHA512withECDSA";
}
} else if ("RSA".equals(key.getAlgorithm())) {
return "SHA256withRSA";
} else {
throw new IllegalArgumentException("Unsupported key type " + key.getAlgorithm());
}
}
static AlgorithmIdentifier getSignatureAlgorithmIdentifier(Key key) throws Exception {
String id = ALG_TO_ID.get(getSignatureAlgorithm(key));
if (id == null) {
throw new IllegalArgumentException("Unsupported key type " + key.getAlgorithm());
}
return new AlgorithmIdentifier(new ASN1ObjectIdentifier(id));
}
public static X509Certificate readCertificate(InputStream input)
throws IOException, GeneralSecurityException {
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return (X509Certificate) cf.generateCertificate(input);
} finally {
input.close();
}
}
/** Read a PKCS#8 format private key. */
public static PrivateKey readPrivateKey(InputStream input)
throws IOException, GeneralSecurityException {
try {
ByteArrayStream buf = new ByteArrayStream();
buf.readFrom(input);
byte[] bytes = buf.toByteArray();
/* Check to see if this is in an EncryptedPrivateKeyInfo structure. */
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
/*
* Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm
* OID and use that to construct a KeyFactory.
*/
ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(spec.getEncoded()));
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
return KeyFactory.getInstance(algOid).generatePrivate(spec);
} finally {
input.close();
}
}
}

View File

@@ -1,382 +0,0 @@
package com.topjohnwu.magisk.signing;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
public class SignBoot {
private static final int BOOT_IMAGE_HEADER_V1_RECOVERY_DTBO_SIZE_OFFSET = 1632;
private static final int BOOT_IMAGE_HEADER_V2_DTB_SIZE_OFFSET = 1648;
// Arbitrary maximum header version value; when greater assume the field is dt/extra size
private static final int BOOT_IMAGE_HEADER_VERSION_MAXIMUM = 8;
// Maximum header size byte value to read (currently the bootimg minimum page size)
private static final int BOOT_IMAGE_HEADER_SIZE_MAXIMUM = 2048;
private static class PushBackRWStream extends FilterInputStream {
private OutputStream out;
private int pos = 0;
private byte[] backBuf;
PushBackRWStream(InputStream in, OutputStream o) {
super(in);
out = o;
}
@Override
public int read() throws IOException {
int b;
if (backBuf != null && backBuf.length > pos) {
b = backBuf[pos++];
} else {
b = super.read();
out.write(b);
}
return b;
}
@Override
public int read(byte[] bytes, int off, int len) throws IOException {
int read = 0;
if (backBuf != null && backBuf.length > pos) {
read = Math.min(len, backBuf.length - pos);
System.arraycopy(backBuf, pos, bytes, off, read);
pos += read;
off += read;
len -= read;
}
if (len > 0) {
int ar = super.read(bytes, off, len);
read += ar;
out.write(bytes, off, ar);
}
return read;
}
void unread(byte[] buf) {
backBuf = buf;
}
}
private static int fullRead(InputStream in, byte[] b) throws IOException {
return fullRead(in, b, 0, b.length);
}
private static int fullRead(InputStream in, byte[] b, int off, int len) throws IOException {
int n = 0;
while (n < len) {
int count = in.read(b, off + n, len - n);
if (count <= 0)
break;
n += count;
}
return n;
}
public static boolean doSignature(
@Nullable X509Certificate cert, @Nullable PrivateKey key,
@NonNull InputStream imgIn, @NonNull OutputStream imgOut, @NonNull String target
) {
try {
PushBackRWStream in = new PushBackRWStream(imgIn, imgOut);
byte[] hdr = new byte[BOOT_IMAGE_HEADER_SIZE_MAXIMUM];
// First read the header
fullRead(in, hdr);
int signableSize = getSignableImageSize(hdr);
// Unread header
in.unread(hdr);
BootSignature bootsig = new BootSignature(target, signableSize);
if (cert == null) {
cert = CryptoUtils.readCertificate(
new ByteArrayInputStream(KeyData.verityCert()));
}
bootsig.setCertificate(cert);
if (key == null) {
key = CryptoUtils.readPrivateKey(
new ByteArrayInputStream(KeyData.verityKey()));
}
byte[] sig = bootsig.sign(key, in, signableSize);
bootsig.setSignature(sig, CryptoUtils.getSignatureAlgorithmIdentifier(key));
byte[] encoded_bootsig = bootsig.getEncoded();
imgOut.write(encoded_bootsig);
imgOut.flush();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static boolean verifySignature(InputStream imgIn, X509Certificate cert) {
try {
// Read the header for size
byte[] hdr = new byte[BOOT_IMAGE_HEADER_SIZE_MAXIMUM];
if (fullRead(imgIn, hdr) != hdr.length) {
System.err.println("Unable to read image header");
return false;
}
int signableSize = getSignableImageSize(hdr);
// Read the rest of the image
byte[] rawImg = Arrays.copyOf(hdr, signableSize);
int remain = signableSize - hdr.length;
if (fullRead(imgIn, rawImg, hdr.length, remain) != remain) {
System.err.println("Unable to read image");
return false;
}
// Read footer, which contains the signature
byte[] signature = new byte[4096];
if (imgIn.read(signature) == -1 || Arrays.equals(signature, new byte [signature.length])) {
System.err.println("Invalid image: not signed");
return false;
}
BootSignature bootsig = new BootSignature(signature);
if (cert != null) {
bootsig.setCertificate(cert);
}
if (bootsig.verify(rawImg, signableSize)) {
System.err.println("Signature is VALID");
return true;
} else {
System.err.println("Signature is INVALID");
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return false;
}
public static int getSignableImageSize(byte[] data) throws Exception {
if (!Arrays.equals(Arrays.copyOfRange(data, 0, 8),
"ANDROID!".getBytes("US-ASCII"))) {
throw new IllegalArgumentException("Invalid image header: missing magic");
}
ByteBuffer image = ByteBuffer.wrap(data);
image.order(ByteOrder.LITTLE_ENDIAN);
image.getLong(); // magic
int kernelSize = image.getInt();
image.getInt(); // kernel_addr
int ramdskSize = image.getInt();
image.getInt(); // ramdisk_addr
int secondSize = image.getInt();
image.getLong(); // second_addr + tags_addr
int pageSize = image.getInt();
if (pageSize >= 0x02000000) {
throw new IllegalArgumentException("Invalid image header: PXA header detected");
}
int length = pageSize // include the page aligned image header
+ ((kernelSize + pageSize - 1) / pageSize) * pageSize
+ ((ramdskSize + pageSize - 1) / pageSize) * pageSize
+ ((secondSize + pageSize - 1) / pageSize) * pageSize;
int headerVersion = image.getInt(); // boot image header version or dt/extra size
if (headerVersion > 0 && headerVersion < BOOT_IMAGE_HEADER_VERSION_MAXIMUM) {
image.position(BOOT_IMAGE_HEADER_V1_RECOVERY_DTBO_SIZE_OFFSET);
int recoveryDtboLength = image.getInt();
length += ((recoveryDtboLength + pageSize - 1) / pageSize) * pageSize;
image.getLong(); // recovery_dtbo address
int headerSize = image.getInt();
if (headerVersion == 2) {
image.position(BOOT_IMAGE_HEADER_V2_DTB_SIZE_OFFSET);
int dtbLength = image.getInt();
length += ((dtbLength + pageSize - 1) / pageSize) * pageSize;
image.getLong(); // dtb address
}
if (image.position() != headerSize) {
throw new IllegalArgumentException("Invalid image header: invalid header length");
}
} else {
// headerVersion is 0 or actually dt/extra size in this case
length += ((headerVersion + pageSize - 1) / pageSize) * pageSize;
}
length = ((length + pageSize - 1) / pageSize) * pageSize;
if (length <= 0) {
throw new IllegalArgumentException("Invalid image header: invalid length");
}
return length;
}
static class BootSignature extends ASN1Object {
private ASN1Integer formatVersion;
private ASN1Encodable certificate;
private AlgorithmIdentifier algId;
private DERPrintableString target;
private ASN1Integer length;
private DEROctetString signature;
private PublicKey publicKey;
private static final int FORMAT_VERSION = 1;
/**
* Initializes the object for signing an image file
* @param target Target name, included in the signed data
* @param length Length of the image, included in the signed data
*/
public BootSignature(String target, int length) {
this.formatVersion = new ASN1Integer(FORMAT_VERSION);
this.target = new DERPrintableString(target);
this.length = new ASN1Integer(length);
}
/**
* Initializes the object for verifying a signed image file
* @param signature Signature footer
*/
public BootSignature(byte[] signature) throws Exception {
ASN1InputStream stream = new ASN1InputStream(signature);
ASN1Sequence sequence = (ASN1Sequence) stream.readObject();
formatVersion = (ASN1Integer) sequence.getObjectAt(0);
if (formatVersion.getValue().intValue() != FORMAT_VERSION) {
throw new IllegalArgumentException("Unsupported format version");
}
certificate = sequence.getObjectAt(1);
byte[] encoded = ((ASN1Object) certificate).getEncoded();
ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate c = (X509Certificate) cf.generateCertificate(bis);
publicKey = c.getPublicKey();
ASN1Sequence algId = (ASN1Sequence) sequence.getObjectAt(2);
this.algId = new AlgorithmIdentifier((ASN1ObjectIdentifier) algId.getObjectAt(0));
ASN1Sequence attrs = (ASN1Sequence) sequence.getObjectAt(3);
target = (DERPrintableString) attrs.getObjectAt(0);
length = (ASN1Integer) attrs.getObjectAt(1);
this.signature = (DEROctetString) sequence.getObjectAt(4);
}
public ASN1Object getAuthenticatedAttributes() {
ASN1EncodableVector attrs = new ASN1EncodableVector();
attrs.add(target);
attrs.add(length);
return new DERSequence(attrs);
}
public byte[] getEncodedAuthenticatedAttributes() throws IOException {
return getAuthenticatedAttributes().getEncoded();
}
public void setSignature(byte[] sig, AlgorithmIdentifier algId) {
this.algId = algId;
signature = new DEROctetString(sig);
}
public void setCertificate(X509Certificate cert)
throws CertificateEncodingException, IOException {
ASN1InputStream s = new ASN1InputStream(cert.getEncoded());
certificate = s.readObject();
publicKey = cert.getPublicKey();
}
public byte[] sign(PrivateKey key, InputStream is, int len) throws Exception {
Signature signer = Signature.getInstance(CryptoUtils.getSignatureAlgorithm(key));
signer.initSign(key);
int read;
byte buffer[] = new byte[4096];
while ((read = is.read(buffer, 0, Math.min(len, buffer.length))) > 0) {
signer.update(buffer, 0, read);
len -= read;
}
signer.update(getEncodedAuthenticatedAttributes());
return signer.sign();
}
public boolean verify(byte[] image, int length) throws Exception {
if (this.length.getValue().intValue() != length) {
throw new IllegalArgumentException("Invalid image length");
}
String algName = CryptoUtils.ID_TO_ALG.get(algId.getAlgorithm().getId());
if (algName == null) {
throw new IllegalArgumentException("Unsupported algorithm " + algId.getAlgorithm());
}
Signature verifier = Signature.getInstance(algName);
verifier.initVerify(publicKey);
verifier.update(image, 0, length);
verifier.update(getEncodedAuthenticatedAttributes());
return verifier.verify(signature.getOctets());
}
@Override
public ASN1Primitive toASN1Primitive() {
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(formatVersion);
v.add(certificate);
v.add(algId);
v.add(getAuthenticatedAttributes());
v.add(signature);
return new DERSequence(v);
}
}
public static void main(String[] args) throws Exception {
if (args.length > 0 && "-verify".equals(args[0])) {
X509Certificate cert = null;
if (args.length >= 2) {
// args[1] is the path to a public key certificate
cert = CryptoUtils.readCertificate(new FileInputStream(args[1]));
}
boolean signed = SignBoot.verifySignature(System.in, cert);
System.exit(signed ? 0 : 1);
} else if (args.length > 0 && "-sign".equals(args[0])) {
X509Certificate cert = null;
PrivateKey key = null;
String name = "/boot";
if (args.length >= 3) {
cert = CryptoUtils.readCertificate(new FileInputStream(args[1]));
key = CryptoUtils.readPrivateKey(new FileInputStream(args[2]));
}
if (args.length == 2) {
name = args[1];
} else if (args.length >= 4) {
name = args[3];
}
boolean result = SignBoot.doSignature(cert, key, System.in, System.out, name);
System.exit(result ? 0 : 1);
} else {
System.err.println(
"BootSigner <actions> [args]\n" +
"Input from stdin, output to stdout\n" +
"\n" +
"Actions:\n" +
" -verify [x509.pem]\n" +
" verify image. cert is optional.\n" +
" -sign [x509.pem] [pk8] [name]\n" +
" sign image. name and the cert/key pair are optional.\n" +
" name should be either /boot (default) or /recovery.\n"
);
}
}
}

View File

@@ -17,6 +17,7 @@ import androidx.navigation.NavDirections
import com.topjohnwu.magisk.MainDirections
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.arch.startAnimations
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
@@ -25,9 +26,7 @@ import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
import com.topjohnwu.magisk.ktx.startAnimations
import com.topjohnwu.magisk.ui.home.HomeFragmentDirections
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Shortcuts
import kotlinx.coroutines.Dispatchers
@@ -103,7 +102,7 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
// https://issuetracker.google.com/issues/124538620
}
binding.mainNavigation.menu.apply {
findItem(R.id.superuserFragment)?.isEnabled = Utils.showSuperUser()
findItem(R.id.superuserFragment)?.isEnabled = Info.showSuperUser
findItem(R.id.modulesFragment)?.isEnabled = Info.env.isActive && LocalModule.loaded()
}

View File

@@ -17,10 +17,10 @@ import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.JobService
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.ui.theme.Theme
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Shortcuts
import com.topjohnwu.superuser.Shell
@@ -80,7 +80,7 @@ abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Bi
onClick {
withPermission(REQUEST_INSTALL_PACKAGES) {
if (!it) {
Utils.toast(R.string.install_unknown_denied, Toast.LENGTH_SHORT)
toast(R.string.install_unknown_denied, Toast.LENGTH_SHORT)
showInvalidStateMessage()
} else {
lifecycleScope.launch {

View File

@@ -10,8 +10,8 @@ import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Build.VERSION.SDK_INT
import androidx.core.os.ProcessCompat
import com.topjohnwu.magisk.core.ktx.getLabel
import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.ktx.getLabel
import java.util.*
class CmdlineListItem(line: String) {

View File

@@ -11,8 +11,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.core.ktx.hideKeyboard
import com.topjohnwu.magisk.databinding.FragmentDenyMd2Binding
import com.topjohnwu.magisk.ktx.hideKeyboard
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect

View File

@@ -5,11 +5,11 @@ import android.view.ViewGroup
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.startAnimations
import com.topjohnwu.magisk.databinding.DiffItem
import com.topjohnwu.magisk.databinding.ObservableRvItem
import com.topjohnwu.magisk.databinding.addOnPropertyChangedCallback
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.ktx.startAnimations
import com.topjohnwu.superuser.Shell
import kotlin.math.roundToInt

View File

@@ -7,10 +7,10 @@ import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.databinding.FilterableDiffObservableList
import com.topjohnwu.magisk.core.ktx.concurrentMap
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.databinding.filterList
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.ktx.concurrentMap
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.asFlow
@@ -23,22 +23,22 @@ class DenyListViewModel : AsyncLoadViewModel() {
var isShowSystem = false
set(value) {
field = value
query()
doQuery(query)
}
var isShowOS = false
set(value) {
field = value
query()
doQuery(query)
}
var query = ""
set(value) {
field = value
query()
doQuery(value)
}
val items = FilterableDiffObservableList<DenyListRvItem>(viewModelScope)
val items = filterList<DenyListRvItem>(viewModelScope)
val extraBindings = bindExtra {
it.put(BR.viewModel, this)
}
@@ -50,7 +50,7 @@ class DenyListViewModel : AsyncLoadViewModel() {
@SuppressLint("InlinedApi")
override suspend fun doLoadWork() {
loading = true
withContext(Dispatchers.Default) {
val apps = withContext(Dispatchers.Default) {
val pm = AppContext.packageManager
val denyList = Shell.cmd("magisk --denylist ls").exec().out
.map { CmdlineListItem(it) }
@@ -63,21 +63,22 @@ class DenyListViewModel : AsyncLoadViewModel() {
.toCollection(ArrayList(size))
}
apps.sort()
items.update(apps)
apps
}
query()
items.set(apps)
doQuery(query)
}
private fun query() {
private fun doQuery(s: String) {
items.filter {
fun filterSystem() = isShowSystem || !it.info.isSystemApp()
fun filterOS() = (isShowSystem && isShowOS) || it.info.isApp()
fun filterQuery(): Boolean {
fun inName() = it.info.label.contains(query, true)
fun inPackage() = it.info.packageName.contains(query, true)
fun inProcesses() = it.processes.any { p -> p.process.name.contains(query, true) }
fun inName() = it.info.label.contains(s, true)
fun inPackage() = it.info.packageName.contains(s, true)
fun inProcesses() = it.processes.any { p -> p.process.name.contains(s, true) }
return inName() || inPackage() || inProcesses()
}

View File

@@ -5,23 +5,23 @@ import androidx.databinding.Bindable
import androidx.databinding.ObservableArrayList
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.map
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.ktx.reboot
import com.topjohnwu.magisk.core.ktx.synchronized
import com.topjohnwu.magisk.core.ktx.timeFormatStandard
import com.topjohnwu.magisk.core.ktx.toTime
import com.topjohnwu.magisk.core.tasks.FlashZip
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ktx.reboot
import com.topjohnwu.magisk.ktx.synchronized
import com.topjohnwu.magisk.ktx.timeFormatStandard
import com.topjohnwu.magisk.ktx.toTime
import com.topjohnwu.superuser.CallbackList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -34,7 +34,7 @@ class FlashViewModel : BaseViewModel() {
private val _state = MutableLiveData(State.FLASHING)
val state: LiveData<State> get() = _state
val flashing = Transformations.map(state) { it == State.FLASHING }
val flashing = state.map { it == State.FLASHING }
@get:Bindable
var showReboot = Info.isRooted

View File

@@ -24,6 +24,10 @@ private interface RikkaImpl : Dev {
override val name get() = "RikkaW"
}
private interface CanyieImpl : Dev {
override val name get() = "canyie"
}
sealed class DeveloperItem : Dev {
abstract val items: List<IconLink>
@@ -61,6 +65,14 @@ sealed class DeveloperItem : Dev {
object : IconLink.Github.User(), RikkaImpl {}
)
}
object Canyie : DeveloperItem(), CanyieImpl {
override val items =
listOf<IconLink>(
object : IconLink.Twitter() { override val name = "canyie2977" },
object : IconLink.Github.User(), CanyieImpl {}
)
}
}
sealed class IconLink : RvItem() {

View File

@@ -1,6 +1,9 @@
package com.topjohnwu.magisk.ui.home
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.widget.Toast
import androidx.core.net.toUri
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
@@ -15,6 +18,8 @@ import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.core.download.Subject.App
import com.topjohnwu.magisk.core.ktx.await
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.repository.NetworkService
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.databinding.set
@@ -22,8 +27,6 @@ import com.topjohnwu.magisk.dialog.EnvFixDialog
import com.topjohnwu.magisk.dialog.ManagerInstallDialog
import com.topjohnwu.magisk.dialog.UninstallDialog
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ktx.await
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.superuser.Shell
import kotlin.math.roundToInt
@@ -112,7 +115,15 @@ class HomeViewModel(
}
fun onLinkPressed(link: String) = object : ViewEvent(), ContextExecutor {
override fun invoke(context: Context) = Utils.openLink(context, link.toUri())
override fun invoke(context: Context) {
val intent = Intent(Intent.ACTION_VIEW, link.toUri())
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
try {
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
context.toast(R.string.open_link_failed_toast, Toast.LENGTH_SHORT)
}
}
}.publish()
fun onDeletePressed() = UninstallDialog().show()

View File

@@ -8,7 +8,7 @@ import android.widget.PopupMenu
import androidx.core.content.getSystemService
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.ktx.reboot as systemReboot
import com.topjohnwu.magisk.core.ktx.reboot as systemReboot
object RebootMenu {

View File

@@ -3,8 +3,8 @@ package com.topjohnwu.magisk.ui.install
import android.net.Uri
import android.os.Bundle
import android.os.Parcelable
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.SpannedString
import android.widget.Toast
import androidx.databinding.Bindable
import androidx.lifecycle.LiveData
@@ -19,27 +19,25 @@ import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.ContentResultCallback
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.repository.NetworkService
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.dialog.SecondSlotWarningDialog
import com.topjohnwu.magisk.events.GetContentEvent
import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.magisk.utils.Utils
import io.noties.markwon.Markwon
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
import timber.log.Timber
import java.io.File
import java.io.IOException
class InstallViewModel(
svc: NetworkService
) : BaseViewModel() {
class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel() {
val isRooted get() = Info.isRooted
val hideVbmeta = Info.vbmeta || Info.isSamsung || Info.isAB
val skipOptions = Info.isEmulator || (Info.isSAR && !Info.isFDE && hideVbmeta && Info.ramdisk)
val skipOptions = Info.isEmulator || (Info.isSAR && !Info.isFDE && Info.ramdisk)
val noSecondSlot = !isRooted || !Info.isAB || Info.isEmulator
@get:Bindable
@@ -65,7 +63,7 @@ class InstallViewModel(
val data: LiveData<Uri?> get() = uri
@get:Bindable
var notes: Spanned = SpannableStringBuilder()
var notes: Spanned = SpannedString("")
set(value) = set(value, field, { field = it }, BR.notes)
init {
@@ -81,7 +79,10 @@ class InstallViewModel(
str
}
}
notes = ServiceLocator.markwon.toMarkdown(text)
val spanned = markwon.toMarkdown(text)
withContext(Dispatchers.Main) {
notes = spanned
}
} catch (e: IOException) {
Timber.e(e)
}
@@ -103,7 +104,6 @@ class InstallViewModel(
step,
Config.keepVerity,
Config.keepEnc,
Config.patchVbmeta,
Config.recovery
))
}
@@ -114,7 +114,6 @@ class InstallViewModel(
step = it.step
Config.keepVerity = it.keepVerity
Config.keepEnc = it.keepEnc
Config.patchVbmeta = it.patchVbmeta
Config.recovery = it.recovery
}
}
@@ -122,7 +121,7 @@ class InstallViewModel(
@Parcelize
class UriCallback : ContentResultCallback {
override fun onActivityLaunch() {
Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG)
AppContext.toast(R.string.patch_file_msg, Toast.LENGTH_LONG)
}
override fun onActivityResult(result: Uri) {
uri.value = result
@@ -135,7 +134,6 @@ class InstallViewModel(
val step: Int,
val keepVerity: Boolean,
val keepEnc: Boolean,
val patchVbmeta: Boolean,
val recovery: Boolean,
) : Parcelable

View File

@@ -8,15 +8,15 @@ import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.ktx.timeFormatStandard
import com.topjohnwu.magisk.core.ktx.toTime
import com.topjohnwu.magisk.core.repository.LogRepository
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.databinding.DiffObservableList
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.databinding.diffList
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ktx.timeFormatStandard
import com.topjohnwu.magisk.ktx.toTime
import com.topjohnwu.magisk.view.TextItem
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -37,13 +37,13 @@ class LogViewModel(
// --- su log
val items = DiffObservableList<SuLogRvItem>()
val items = diffList<SuLogRvItem>()
val extraBindings = bindExtra {
it.put(BR.viewModel, this)
}
// --- magisk log
val logs = DiffObservableList<LogRvItem>()
val logs = diffList<LogRvItem>()
var magiskLogRaw = " "
override suspend fun doLoadWork() {

View File

@@ -3,18 +3,19 @@ package com.topjohnwu.magisk.ui.log
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.timeDateFormat
import com.topjohnwu.magisk.core.ktx.toTime
import com.topjohnwu.magisk.core.model.su.SuLog
import com.topjohnwu.magisk.databinding.DiffItem
import com.topjohnwu.magisk.databinding.ObservableRvItem
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.ktx.timeDateFormat
import com.topjohnwu.magisk.ktx.toTime
class SuLogRvItem(val log: SuLog) : ObservableRvItem(), DiffItem<SuLogRvItem> {
override val layoutRes = R.layout.item_log_access_md2
val date = log.time.toTime(timeDateFormat)
val info = genInfo()
@get:Bindable
var isTop = false
@@ -25,4 +26,28 @@ class SuLogRvItem(val log: SuLog) : ObservableRvItem(), DiffItem<SuLogRvItem> {
set(value) = set(value, field, { field = it }, BR.bottom)
override fun itemSameAs(other: SuLogRvItem) = log.appName == other.log.appName
private fun genInfo(): String {
val res = AppContext.resources
val sb = StringBuilder()
val date = log.time.toTime(timeDateFormat)
val toUid = res.getString(R.string.target_uid, log.toUid)
val fromPid = res.getString(R.string.pid, log.fromPid)
sb.append("$date\n$toUid $fromPid")
if (log.target != -1) {
val pid = if (log.target == 0) "magiskd" else log.target.toString()
val target = res.getString(R.string.target_pid, pid)
sb.append(" $target")
}
if (log.context.isNotEmpty()) {
val context = res.getString(R.string.selinux_context, log.context)
sb.append("\n$context")
}
if (log.gids.isNotEmpty()) {
val gids = res.getString(R.string.supp_group, log.gids)
sb.append("\n$gids")
}
sb.append("\n${log.command}")
return sb.toString()
}
}

View File

@@ -5,6 +5,7 @@ import android.view.View
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addInvalidateItemDecorationsObserver
@@ -21,7 +22,8 @@ class ModuleFragment : BaseFragment<FragmentModuleMd2Binding>() {
activity?.title = resources.getString(R.string.modules)
viewModel.data.observe(this) {
it ?: return@observe
viewModel.requestInstallLocalModule(it)
val displayName = runCatching { it.displayName }.getOrNull() ?: return@observe
viewModel.requestInstallLocalModule(it, displayName)
viewModel.data.value = null
}
}

View File

@@ -10,10 +10,10 @@ import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.ContentResultCallback
import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.databinding.DiffObservableList
import com.topjohnwu.magisk.databinding.MergeObservableList
import com.topjohnwu.magisk.databinding.RvItem
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.databinding.diffList
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.dialog.LocalModuleInstallDialog
import com.topjohnwu.magisk.dialog.OnlineModuleInstallDialog
@@ -27,7 +27,7 @@ class ModuleViewModel : AsyncLoadViewModel() {
val bottomBarBarrierIds = intArrayOf(R.id.module_update, R.id.module_remove)
private val itemsInstalled = DiffObservableList<LocalModuleRvItem>()
private val itemsInstalled = diffList<LocalModuleRvItem>()
val items = MergeObservableList<RvItem>()
val extraBindings = bindExtra {
@@ -84,8 +84,8 @@ class ModuleViewModel : AsyncLoadViewModel() {
GetContentEvent("application/zip", UriCallback()).publish()
}
fun requestInstallLocalModule(uri: Uri) {
LocalModuleInstallDialog(this, uri).show()
fun requestInstallLocalModule(uri: Uri, displayName: String) {
LocalModuleInstallDialog(this, uri, displayName).show()
}
@Parcelize

View File

@@ -6,9 +6,9 @@ import android.view.View
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.ktx.activity
import com.topjohnwu.magisk.databinding.ObservableRvItem
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.ktx.activity
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.view.MagiskDialog

View File

@@ -12,8 +12,9 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.activity
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.availableLocales
import com.topjohnwu.magisk.core.utils.currentLocale
@@ -21,8 +22,6 @@ import com.topjohnwu.magisk.databinding.DialogSettingsAppNameBinding
import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding
import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.ktx.activity
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.superuser.Shell
@@ -287,14 +286,16 @@ object Tapjack : BaseSettingsItem.Toggle() {
object Biometrics : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_biometric_title.asText()
override var description = R.string.settings_su_biometric_summary.asText()
override var value by Config::suBiometric
override var value
get() = ServiceLocator.biometrics.isEnabled
set(value) {
Config.suBiometric = value
}
override fun refresh() {
isEnabled = BiometricHelper.isSupported
isEnabled = ServiceLocator.biometrics.isSupported
if (!isEnabled) {
value = false
description = R.string.no_biometric.asText()
notifyPropertyChanged(BR.checked)
}
}
}
@@ -357,6 +358,6 @@ object Reauthenticate : BaseSettingsItem.Toggle() {
override var value by Config::suReAuth
override fun refresh() {
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Utils.showSuperUser()
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Info.showSuperUser
}
}

View File

@@ -13,13 +13,13 @@ import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.activity
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.BiometricEvent
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ktx.activity
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
@@ -69,7 +69,7 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
}
// Superuser
if (Utils.showSuperUser()) {
if (Info.showSuperUser) {
list.addAll(listOf(
Superuser,
Tapjack, Biometrics, AccessMode, MultiuserMode, MountNamespaceMode,
@@ -128,7 +128,7 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
private fun createHosts() {
Shell.cmd("add_hosts_module").submit {
Utils.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
}
}
}

View File

@@ -73,6 +73,8 @@ class PolicyRvItem(
viewModel.deletePressed(this)
}
override fun itemSameAs(other: PolicyRvItem) = item.uid == other.item.uid
override fun itemSameAs(other: PolicyRvItem) = packageName == other.packageName
override fun contentSameAs(other: PolicyRvItem) = item.policy == other.item.policy
}

View File

@@ -10,17 +10,17 @@ import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.getLabel
import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.databinding.*
import com.topjohnwu.magisk.dialog.SuperuserRevokeDialog
import com.topjohnwu.magisk.events.BiometricEvent
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ktx.getLabel
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.view.TextItem
import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ class SuperuserViewModel(
private val itemNoData = TextItem(R.string.superuser_policy_none)
private val itemsHelpers = ObservableArrayList<TextItem>()
private val itemsPolicies = DiffObservableList<PolicyRvItem>()
private val itemsPolicies = diffList<PolicyRvItem>()
val items = MergeObservableList<RvItem>()
.insertList(itemsHelpers)
@@ -49,7 +49,7 @@ class SuperuserViewModel(
@SuppressLint("InlinedApi")
override suspend fun doLoadWork() {
if (!Utils.showSuperUser()) {
if (!Info.showSuperUser) {
loading = false
return
}
@@ -105,13 +105,15 @@ class SuperuserViewModel(
fun deletePressed(item: PolicyRvItem) {
fun updateState() = viewModelScope.launch {
db.delete(item.item.uid)
itemsPolicies.removeAll { it.itemSameAs(item) }
if (itemsPolicies.isEmpty() && itemsHelpers.isEmpty()) {
val list = ArrayList(itemsPolicies)
list.removeAll { it.item.uid == item.item.uid }
itemsPolicies.update(list)
if (list.isEmpty() && itemsHelpers.isEmpty()) {
itemsHelpers.add(itemNoData)
}
}
if (BiometricHelper.isEnabled) {
if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent {
onSuccess { updateState() }
}.publish()
@@ -153,21 +155,20 @@ class SuperuserViewModel(
}
fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
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
db.update(item.item)
itemsPolicies.forEach {
if (it.item.uid == item.item.uid) {
it.notifyPropertyChanged(BR.enabled)
}
items.forEach {
it.notifyPropertyChanged(BR.enabled)
}
SnackbarEvent(res.asText(item.appName)).publish()
}
}
if (BiometricHelper.isEnabled) {
if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent {
onSuccess { updateState() }
}.publish()

View File

@@ -22,17 +22,18 @@ import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.getLabel
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY
import com.topjohnwu.magisk.core.su.SuRequestHandler
import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.events.BiometricEvent
import com.topjohnwu.magisk.events.DieEvent
import com.topjohnwu.magisk.events.ShowUIEvent
import com.topjohnwu.magisk.ktx.getLabel
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.Utils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.concurrent.TimeUnit.SECONDS
@@ -62,7 +63,7 @@ class SuRequestViewModel(
if (event.flags and MotionEvent.FLAG_WINDOW_IS_OBSCURED != 0
|| event.flags and MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED != 0) {
if (event.action == MotionEvent.ACTION_UP) {
Utils.toast(R.string.touch_filtered_warning, Toast.LENGTH_SHORT)
AppContext.toast(R.string.touch_filtered_warning, Toast.LENGTH_SHORT)
}
return@OnTouchListener Config.suTapjack
}
@@ -70,12 +71,13 @@ class SuRequestViewModel(
}
private val handler = SuRequestHandler(AppContext.packageManager, policyDB)
private lateinit var timer: CountDownTimer
private val millis = SECONDS.toMillis(Config.suDefaultTimeout.toLong())
private var timer = SuTimer(millis, 1000)
private var initialized = false
fun grantPressed() {
cancelTimer()
if (BiometricHelper.isEnabled) {
if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent {
onSuccess {
respond(ALLOW)
@@ -96,7 +98,7 @@ class SuRequestViewModel(
}
fun handleRequest(intent: Intent) {
viewModelScope.launch {
viewModelScope.launch(Dispatchers.Default) {
if (handler.start(intent))
showDialog()
else
@@ -125,8 +127,7 @@ class SuRequestViewModel(
selectedItemPosition = timeoutPrefs.getInt(packageName, 0)
// Set timer
val millis = SECONDS.toMillis(Config.suDefaultTimeout.toLong())
timer = SuTimer(millis, 1000).apply { start() }
timer.start()
// Actually show the UI
ShowUIEvent(if (Config.suTapjack) EmptyAccessibilityDelegate else null).publish()

View File

@@ -1,39 +0,0 @@
package com.topjohnwu.magisk.utils
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.superuser.internal.UiThreadHandler
object Utils {
fun toast(msg: CharSequence, duration: Int) {
UiThreadHandler.run { Toast.makeText(AppContext, msg, duration).show() }
}
fun toast(resId: Int, duration: Int) {
UiThreadHandler.run { Toast.makeText(AppContext, resId, duration).show() }
}
fun showSuperUser(): Boolean {
return Info.env.isActive && (Const.USER_ID == 0
|| Config.suMultiuserMode == Config.Value.MULTIUSER_MODE_USER)
}
fun openLink(context: Context, link: Uri) {
val intent = Intent(Intent.ACTION_VIEW, link)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
try {
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
toast(R.string.open_link_failed_toast, Toast.LENGTH_SHORT)
}
}
}

View File

@@ -13,8 +13,8 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.ktx.getBitmap
import com.topjohnwu.magisk.ktx.selfLaunchIntent
import com.topjohnwu.magisk.core.ktx.getBitmap
import com.topjohnwu.magisk.core.ktx.selfLaunchIntent
import java.util.concurrent.atomic.AtomicInteger
@Suppress("DEPRECATION")

View File

@@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.graphics.drawable.Icon
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.content.getSystemService
@@ -13,8 +14,8 @@ import androidx.core.graphics.drawable.IconCompat
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.ktx.getBitmap
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.getBitmap
object Shortcuts {
@@ -35,14 +36,28 @@ object Shortcuts {
ShortcutManagerCompat.requestPinShortcut(context, info, null)
}
private fun Context.getIconCompat(id: Int): IconCompat {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
IconCompat.createWithAdaptiveBitmap(getBitmap(id))
else
IconCompat.createWithBitmap(getBitmap(id))
private fun Context.getIcon(id: Int): Icon {
return if (isRunningAsStub) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
Icon.createWithAdaptiveBitmap(getBitmap(id))
else
Icon.createWithBitmap(getBitmap(id))
} else {
Icon.createWithResource(this, id)
}
}
private fun Context.getIcon(id: Int) = getIconCompat(id).toIcon(this)
private fun Context.getIconCompat(id: Int): IconCompat {
return if (isRunningAsStub) {
val bitmap = getBitmap(id)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
IconCompat.createWithAdaptiveBitmap(bitmap)
else
IconCompat.createWithBitmap(bitmap)
} else {
IconCompat.createWithResource(this, id)
}
}
@RequiresApi(api = 25)
private fun getShortCuts(context: Context): List<ShortcutInfo> {
@@ -51,7 +66,7 @@ object Shortcuts {
val shortCuts = mutableListOf<ShortcutInfo>()
if (Utils.showSuperUser()) {
if (Info.showSuperUser) {
shortCuts.add(
ShortcutInfo.Builder(context, Const.Nav.SUPERUSER)
.setShortLabel(context.getString(R.string.superuser))

View File

@@ -2,4 +2,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_magisk_padded" />
</adaptive-icon>
<monochrome android:drawable="@drawable/ic_magisk_padded" />
</adaptive-icon>

View File

@@ -6,4 +6,9 @@
android:drawable="@drawable/ic_extension"
android:inset="30%" />
</foreground>
</adaptive-icon>
<monochrome>
<inset
android:drawable="@drawable/ic_extension"
android:inset="30%" />
</monochrome>
</adaptive-icon>

View File

@@ -6,4 +6,9 @@
android:drawable="@drawable/ic_superuser"
android:inset="30%" />
</foreground>
</adaptive-icon>
<monochrome>
<inset
android:drawable="@drawable/ic_superuser"
android:inset="30%" />
</monochrome>
</adaptive-icon>

View File

@@ -242,6 +242,14 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/l_50" />
<include
item="@{DeveloperItem.Canyie.INSTANCE}"
layout="@layout/item_developer"
viewModel="@{viewModel}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/l_50" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@@ -108,15 +108,6 @@
android:text="@string/keep_force_encryption"
app:tint="?colorPrimary" />
<CheckBox
style="@style/WidgetFoundation.Checkbox"
gone="@{viewModel.hideVbmeta}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="@={Config.patchVbmeta}"
android:text="@string/patch_vbmeta"
app:tint="?colorPrimary" />
<CheckBox
style="@style/WidgetFoundation.Checkbox"
gone="@{Info.ramdisk}"

View File

@@ -29,8 +29,13 @@
tools:listitem="@layout/item_log_access_md2"
tools:paddingTop="24dp" />
<ProgressBar
style="@style/WidgetFoundation.ProgressBar.Indeterminate"
goneUnless="@{viewModel.loading}"
android:layout_marginTop="@dimen/l1" />
<FrameLayout
gone="@{!viewModel.items.empty}"
gone="@{viewModel.loading || !viewModel.items.empty}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">

View File

@@ -25,9 +25,9 @@
<include
android:id="@+id/log_track_container"
bullet="@{item.log.action ? 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}"
isSelected="@{item.log.action != 2}"
isTop="@{item.isTop}"
layout="@layout/item_log_track_md2"
android:layout_width="wrap_content"
@@ -54,48 +54,22 @@
android:text="@{item.log.appName}"
android:textAppearance="@style/AppearanceFoundation.Body"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/log_date"
app:layout_constraintBottom_toTopOf="@+id/log_info"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/magisk" />
<TextView
android:id="@+id/log_date"
android:id="@+id/log_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{item.date}"
android:text="@{item.info}"
android:textAppearance="@style/AppearanceFoundation.Caption.Variant"
app:layout_constraintBottom_toTopOf="@+id/log_app_details"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/log_app_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="06:00 PM, 10 Oct 2019" />
<TextView
android:id="@+id/log_app_details"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@{String.format(`%s %s`, @string/pid(item.log.fromPid), @string/target_uid(item.log.toUid))}"
android:textAppearance="@style/AppearanceFoundation.Caption.Variant"
app:layout_constraintBottom_toTopOf="@id/log_command"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/log_date"
tools:text="PID: 7196 Target UID: 0" />
<TextView
android:id="@+id/log_command"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:text="@{item.log.command}"
android:textAppearance="@style/AppearanceFoundation.Caption.Variant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/log_app_details"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="/system/bin/sh" />
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -24,11 +24,15 @@
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:id="@+id/module"
style="@style/WidgetFoundation.Card"
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"
@@ -95,6 +99,7 @@
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/l_50"
android:checked="@={item.enabled}"
android:nextFocusLeft="@id/module"
app:layout_constraintBottom_toBottomOf="@+id/module_version_author"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"

View File

@@ -17,10 +17,13 @@
android:layout_gravity="center">
<com.google.android.material.card.MaterialCardView
android:id="@+id/policy"
style="@style/WidgetFoundation.Card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="@{item.enabled ? 1f : .5f}"
android:focusable="true"
android:nextFocusRight="@id/policy_indicator"
android:onClick="@{() -> item.toggleExpand()}">
<LinearLayout
@@ -35,10 +38,10 @@
<ImageView
android:id="@+id/policy_app_icon"
style="@style/WidgetFoundation.Image"
srcCompat="@{item.icon}"
android:layout_marginStart="@dimen/l1"
android:layout_marginTop="@dimen/l1"
android:layout_marginBottom="@dimen/l1"
srcCompat="@{item.icon}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
@@ -86,8 +89,9 @@
android:id="@+id/policy_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={item.enabled}"
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" />
@@ -96,20 +100,20 @@
<LinearLayout
android:id="@+id/policy_expand_container"
android:orientation="horizontal"
gone="@{!item.isExpanded}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurfaceVariant"
android:orientation="horizontal"
tools:visibility="visible">
<Button
android:id="@+id/policy_notify"
style="@style/WidgetFoundation.Button.Text"
isSelected="@{item.shouldNotify}"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="24dp"
android:onClick="@{() -> item.toggleNotify()}"
android:text="@string/superuser_toggle_notification"
@@ -131,9 +135,9 @@
android:id="@+id/policy_log"
style="@style/WidgetFoundation.Button.Text"
isSelected="@{item.shouldLog}"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="24dp"
android:onClick="@{() -> item.toggleLog()}"
android:text="@string/logs"
@@ -154,9 +158,9 @@
<Button
android:id="@+id/policy_delete"
style="@style/WidgetFoundation.Button.Text"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="24dp"
android:onClick="@{() -> item.revoke()}"
android:text="@string/superuser_toggle_revoke"

View File

@@ -44,7 +44,6 @@ fix_env() {
rm -rf $MAGISKBIN/*
mkdir -p $MAGISKBIN 2>/dev/null
chmod 700 $NVBASE
rm $1/stub.apk 2>/dev/null
cp_readlink $1 $MAGISKBIN
rm -rf $1
chown -R 0:0 $MAGISKBIN
@@ -155,7 +154,7 @@ check_boot_ramdisk() {
$ISAB && return 0
# If we are using legacy SAR, but not A/B, assume we do not have ramdisk
if grep ' / ' /proc/mounts | grep -q '/dev/root'; then
if $LEGACYSAR; then
# Override recovery mode to true
RECOVERYMODE=true
return 1
@@ -194,25 +193,32 @@ check_encryption() {
mount_partitions() {
[ "$(getprop ro.build.ab_update)" = "true" ] && SLOT=$(getprop ro.boot.slot_suffix)
# Check whether non rootfs root dir exists
SYSTEM_ROOT=false
grep ' / ' /proc/mounts | grep -qv 'rootfs' && SYSTEM_ROOT=true
SYSTEM_AS_ROOT=false
grep ' / ' /proc/mounts | grep -qv 'rootfs' && SYSTEM_AS_ROOT=true
}
get_flags() {
KEEPVERITY=$SYSTEM_ROOT
KEEPVERITY=$SYSTEM_AS_ROOT
ISENCRYPTED=false
[ "$(getprop ro.crypto.state)" = "encrypted" ] && ISENCRYPTED=true
KEEPFORCEENCRYPT=$ISENCRYPTED
# Although this most certainly won't work without root, keep it just in case
if [ -e /dev/block/by-name/vbmeta_a ] || [ -e /dev/block/by-name/vbmeta ]; then
VBMETAEXIST=true
if [ -n "$(getprop ro.boot.vbmeta.device)" -o -n "$(getprop ro.boot.vbmeta.size)" ]; then
PATCHVBMETAFLAG=false
elif getprop ro.product.ab_ota_partitions | grep -wq vbmeta; then
PATCHVBMETAFLAG=false
else
VBMETAEXIST=false
PATCHVBMETAFLAG=true
fi
# Preset PATCHVBMETAFLAG to false in the non-root case
PATCHVBMETAFLAG=false
# Make sure RECOVERYMODE has value
[ -z $RECOVERYMODE ] && RECOVERYMODE=false
if $SYSTEM_AS_ROOT; then
if grep ' / ' /proc/mounts | grep -q '/dev/root'; then
LEGACYSAR=true
else
LEGACYSAR=false
fi
else
LEGACYSAR=false
fi
}
run_migrations() { return; }
@@ -225,11 +231,11 @@ grep_prop() { return; }
app_init() {
mount_partitions
get_flags
RAMDISKEXIST=false
check_boot_ramdisk && RAMDISKEXIST=true
get_flags
run_migrations
SHA1=$(grep_prop SHA1 $MAGISKTMP/config)
SHA1=$(grep_prop SHA1 $MAGISKTMP/.magisk/config)
check_encryption
}

View File

@@ -1,85 +1,156 @@
<resources>
<!--Welcome Activity-->
<!--Sections-->
<string name="modules">Əlavələr</string>
<string name="superuser">Superuser</string>
<string name="logs">Log</string>
<string name="settings">Tənzimləmələr</string>
<string name="logs">Girişlər</string>
<string name="settings">Ayarlar</string>
<string name="install">Quraşdır</string>
<string name="unsupport_magisk_title">Dəstəklənməyən Magisk Versiyası</string>
<string name="section_home">Ev</string>
<string name="section_theme">Mövzular</string>
<string name="denylist">İstisnalar</string>
<!--Status Fragment-->
<string name="invalid_update_channel">Etibarsız Yeniləmə Kanalı</string>
<string name="keep_force_encryption">Şifrələməyə məcbur etməni qoru</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity\'i qoru</string>
<string name="uninstall_magisk_title">Magisk\'i Sil</string>
<string name="uninstall_magisk_msg">Bütün əlavələr ləğv olunacaq/silinəcək. Root silinəcək, və əgər hal-hazırda deyilsə, bütün məlumatlarınız potensiyal olaraq şifrələnəcək.</string>
<!--Home-->
<string name="no_connection">Bağlantı yoxdur</string>
<string name="app_changelog">Dəyişənlər</string>
<string name="loading">Yüklənir…</string>
<string name="update">Yenilə</string>
<string name="not_available">Yoxdur</string>
<string name="hide">Gizlə</string>
<string name="home_package">Paket</string>
<string name="home_app_title">Tətbiq</string>
<!--Module Fragment-->
<string name="no_info_provided">(Məlumat təmin edilməyib)</string>
<string name="reboot_recovery">Bərpa rejimində yenidən başlat</string>
<string name="reboot_bootloader">Bootloader\'ə yenidən başlat</string>
<string name="reboot_download">Yükləmə rejimində yenidən başlat</string>
<string name="reboot_edl">EDL\'ə yenidən başlat</string>
<string name="home_notice_content">Magiski YALNIZ rəsmi GitHub səhifəsindən endirin. Bilinməyən mənbələrdəki fayllar zərərli ola bilər!</string>
<string name="home_support_title">Dəstək ol</string>
<string name="home_follow_title">İzlə</string>
<string name="home_item_source">Mənbə</string>
<string name="home_support_content">Magisk pulsuzdur və həmişə belə qalacaq. Amma istəsən bizə dəstək ola bilərsən.</string>
<string name="home_installed_version">Qurulan</string>
<string name="home_latest_version">Yeni</string>
<string name="invalid_update_channel">Keçərsiz yeniləmə kanalı</string>
<string name="uninstall_magisk_title">Magisk\'i sil</string>
<string name="uninstall_magisk_msg">Bütün əlavələr ləğv olunacaq/silinəcək. Root silinəcək, və əgər hal-hazırda deyilsə, bütün məlumatlarınız potensiyal olaraq şifrələnəcək.</string>
<!--Repo Fragment-->
<string name="update_available">Yeniləmə Var</string>
<string name="home_installed_version">Yüklənib</string>
<!--Install-->
<string name="keep_force_encryption">Zorla şifrələməni qoru</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity qoru</string>
<string name="patch_vbmeta">vbmeta\'nı boot\'da yamaqla</string>
<string name="recovery_mode">Bərpa Rejimi</string>
<string name="install_options_title">Ayarlar</string>
<string name="install_method_title">Yol</string>
<string name="install_next">Sonrakı</string>
<string name="install_start">Getdik</string>
<string name="manager_download_install">Endirib quraşdırmaq üçün bas</string>
<string name="direct_install">Birbaşa Quraşdır (Tövsiyyə olunur)</string>
<string name="install_inactive_slot">Fəal olmayan Slot\'a quraşdır (OTA\'dan sonra)</string>
<string name="install_inactive_slot_msg">Cihazınız yenidən başladıqdan sonra fəal olmayan slotda başlamağa MƏCBUR ediləcək!\nBu seçimi ancaq OTA bitdikdən sonra tətbiq edin.\nDavam edilsin?</string>
<string name="setup_title">Əlavə Sazlamalar</string>
<string name="select_patch_file">Fayl seç və yamaqla</string>
<string name="patch_file_msg">(*.img) yaxud ODIN (*.tar) seç</string>
<string name="reboot_delay_toast">5 saniyəyə yenidən başlayacaq…</string>
<string name="flash_screen_title">Quraşdırılma</string>
<!--Log Fragment-->
<string name="menuSaveLog">Log\'u saxla</string>
<string name="menuClearLog">Log\'u indi təmizlə</string>
<string name="logs_cleared">Log uğurla təmizləndi.</string>
<!--Superuser-->
<string name="su_request_title">Superuser İstəyi</string>
<string name="touch_filtered_warning">Hansısa tətbiq Superuser istəyini pozduğuna görə, Magisk göstərişinizi yerinə yetirə bilmir</string>
<string name="deny">İmtina et</string>
<string name="prompt">İstək</string>
<string name="grant">İcazə ver</string>
<string name="su_warning">Bu tətbiqə tam səlahiyyət verəcək.\nƏmin deyilsənsə imtina et!</string>
<string name="forever">Həmişə</string>
<string name="once">1 dəfəlik</string>
<string name="tenmin">10 dəqiqəlik</string>
<string name="twentymin">20 dəqiqəlik</string>
<string name="thirtymin">30 dəqiqəlik</string>
<string name="sixtymin">60 dəqiqəlik</string>
<string name="su_allow_toast">%1$s Superuser icazəsi aldı</string>
<string name="su_deny_toast">%1$s Superuser icazəsi ala bilmədi</string>
<string name="su_snack_grant">%1$s üçün Superuser haqları verilib</string>
<string name="su_snack_deny">%1$s üçün Superuser haqları verilməyib</string>
<string name="su_snack_notif_on">%1$s üçün bildirişlər açıqdır</string>
<string name="su_snack_notif_off">%1$s üçün bildirişlər qapalıdır</string>
<string name="su_snack_log_on">%1$s qeydləri açıqdır</string>
<string name="su_snack_log_off">%1$s qeydləri qapalıdır</string>
<string name="su_revoke_title">Sil</string>
<string name="su_revoke_msg">%1$s üçün Superuser haqlarının silinməsini təsdiqlə</string>
<string name="toast">Tost</string>
<string name="none">Heçnə</string>
<!--About Activity-->
<string name="app_changelog">Yeniliklər</string>
<string name="superuser_toggle_notification">bildirişlər</string>
<string name="superuser_toggle_revoke">Sil</string>
<string name="superuser_policy_none">Hələ heçbir tətbiq Superusr icazəsi istəməyib.</string>
<!-- System Components, Notifications -->
<string name="update_channel">Magisk Yeniləmələri</string>
<string name="progress_channel">Nəticə Bildirişləri</string>
<string name="download_complete">Yükləmə bitdi</string>
<string name="download_file_error">Faylı yükləmək alınmadı</string>
<string name="magisk_update_title">Magisk Yeniləməsi Var!</string>
<!--Logs-->
<string name="log_data_none">Qeyd yoxdur, root icazəli tətbiqlərdən daha çox istifadə edə bilərsən</string>
<string name="log_data_magisk_none">Qəribədir, Magisk qeydləri boşdur</string>
<string name="menuSaveLog">Qeydləri saxla</string>
<string name="menuClearLog">Qeydləri sil</string>
<string name="logs_cleared">Qeydlər silindi</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Hədəf UID: %1$d</string>
<!--Toasts, Dialogs-->
<string name="download">Yüklə</string>
<string name="reboot">Yenidən Başlat</string>
<string name="release_notes">Yeniliklər</string>
<string name="manager_download_install">Yükləyib quraşdırmaq üçün toxun.</string>
<string name="flashing">Qurulur</string>
<string name="open_link_failed_toast">Keçid açmağa heçbir tətbiq tapılmadı.</string>
<string name="direct_install">Birdəfəlik Yüklə (Tövsiyə olunur)</string>
<string name="select_patch_file">Fayl Seç və Yamaqla</string>
<string name="install_inactive_slot">Fəal olmayan slota quraşdır (OTA\'dan sonra)</string>
<string name="install_inactive_slot_msg">Cihazınız yenidən başladıldıqdan sonra fəal olmayan slota başlamağa MƏCBUR ediləcək!\nBu seçimi yalnız OTA bitdikdən sonra istifadə edin.\nDavam edirsiniz?</string>
<string name="complete_uninstall">Silməni Bitir</string>
<string name="restore_img">Nüsxələri Qaytar</string>
<string name="restore_img_msg">Geri qaytarılır…</string>
<string name="restore_done">Geri qaytarma bitdi!</string>
<string name="restore_fail">Stock nüsxə mövcud deyil!</string>
<string name="setup_fail">Quraşdırma alınmadı.</string>
<string name="env_fix_title">Əlavə Quraşdırma Lazımdır</string>
<string name="setup_title">Əlavə quraşdırma</string>
<string name="setup_msg">Quraşdırma yerinə yetirilir…</string>
<!--SafetyNet-->
<!--Settings Activity -->
<!--MagiskHide-->
<string name="show_system_app">Sistem tətbiqlərini göstər</string>
<string name="show_os_app">ƏS tətbiqlərini göstər</string>
<string name="hide_filter_hint">Adla sırala</string>
<string name="hide_search">Axtar</string>
<!--Module-->
<string name="no_info_provided">(Məlumat verilməyib)</string>
<string name="reboot_userspace">Yumuşaq başlatma</string>
<string name="reboot_recovery">Bərpaya başlat</string>
<string name="reboot_bootloader">Bootloader\'ə başlat</string>
<string name="reboot_download">Yükləməyə başlat</string>
<string name="reboot_edl">EDL\'ə başlat</string>
<string name="module_version_author">%2$s tərəfindən %1$s buraxılışı</string>
<string name="module_state_remove">Sil</string>
<string name="module_state_restore">Bərpa et</string>
<string name="module_action_install_external">Yaddaşdan yüklə</string>
<string name="update_available">Yeniləmə var</string>
<string name="suspend_text_riru">%1$s açıq olduğundan Magisk əlavəsi dayandırıldı</string>
<string name="suspend_text_zygisk">%1$s qapalı olduğu üçün Magisk əlavəsi dayandırıldı</string>
<string name="zygisk_module_unloaded">Zygisk əlavəsi uyğunsuzluq səbəbindən açılmadı</string>
<string name="module_empty">Heçbir əlavə qurulmayıb</string>
<!--Settings-->
<string name="settings_dark_mode_title">Mövzu Modu</string>
<string name="settings_dark_mode_message">Zövqünə uyğun modu seç!</string>
<string name="settings_dark_mode_light">Həmişə Açıq</string>
<string name="settings_dark_mode_system">Sistemə Uyğun</string>
<string name="settings_dark_mode_dark">Həmişə Qaranlıq</string>
<string name="settings_download_path_title">Endirmə yolu</string>
<string name="settings_download_path_message">Fayllar %1$s\'a yerləşdiriləcək</string>
<string name="settings_hide_app_title">Magisk tətbiqini gizlət</string>
<string name="settings_hide_app_summary">Təsadüfi paket ID\'si ilə proxy yüklə və özəl tətbiq adı yaz</string>
<string name="settings_restore_app_title">Magisk tətbiqini bərpa et</string>
<string name="settings_restore_app_summary">Tətbiqi üzə çıxar və orijinal APKnı bərpa et</string>
<string name="language">Dil</string>
<string name="system_default">(Sistem Dili)</string>
<string name="settings_check_update_title">Yeniləmələri Yoxla</string>
<string name="settings_check_update_summary">Axraplanda vaxtaşırı yeniləmələri yoxla.</string>
<string name="settings_update_channel_title">Kanalı Yenilə</string>
<string name="settings_update_stable">Stabil</string>
<string name="settings_check_update_title">Yeniləməni Yoxla</string>
<string name="settings_check_update_summary">Vaxtaşırı arxaplanda yeniləmələri yoxla</string>
<string name="settings_update_channel_title">Yeniləmə Kanalı</string>
<string name="settings_update_stable">Sabit</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Özəl</string>
<string name="settings_update_custom_msg">Özəl URL daxil edin</string>
<string name="settings_hosts_title">Sistemsiz host\'lar</string>
<string name="settings_hosts_summary">Adblock tətbiqləri üçün Sistemsiz host dəstəyi.</string>
<string name="settings_hosts_toast">Sistemsiz host əlavəsi quraşdırıldı</string>
<string name="settings_update_custom_msg">Özəl kanal URL\'si daxil et</string>
<string name="settings_zygisk_summary">Magiskin bəzi hissələrini zygote daemonda aç</string>
<string name="settings_denylist_title">İstisnaları Məcbur İşlət</string>
<string name="settings_denylist_summary">İstisnalar siyahısındakı proseslər Magisk əlavələrini tərsinə çevirəcək</string>
<string name="settings_denylist_error">Bu özəlliyin işləməsi üçün %1$s açıq olmalıdır</string>
<string name="settings_denylist_config_title">İstisnaları Ayarla</string>
<string name="settings_denylist_config_summary">İstisnalara yerləşdiriləcək prosesi seçin</string>
<string name="settings_hosts_title">Sistemsiz hostlar</string>
<string name="settings_hosts_summary">Reklam əngəlləyici tətbiqlər üçün host faylları</string>
<string name="settings_hosts_toast">Sistemsiz hostların əlavəsi quruldu</string>
<string name="settings_app_name_hint">Yeni Ad</string>
<string name="settings_app_name_helper">Tətbiq bu adla yenidən paketlənəcək</string>
<string name="settings_app_name_error">Keçərsiz Format</string>
<string name="settings_su_app_adb">Tətbiqlər və ADB</string>
<string name="settings_su_app">Yalnız Tətbiqlər</string>
<string name="settings_su_app">Yalmız Tətbiqlər</string>
<string name="settings_su_adb">Yalnız ADB</string>
<string name="settings_su_disable">Qapalı</string>
<string name="settings_su_disable">Heç Biri</string>
<string name="settings_su_request_10">10 saniyə</string>
<string name="settings_su_request_15">15 saniyə</string>
<string name="settings_su_request_20">20 saniyə</string>
@@ -88,55 +159,83 @@
<string name="settings_su_request_60">60 saniyə</string>
<string name="superuser_access">Superuser İcazəsi</string>
<string name="auto_response">Avtomatik Cavab</string>
<string name="request_timeout">İcazə Vaxtaşımı</string>
<string name="superuser_notification">Superuser Bildirişləri</string>
<string name="settings_su_reauth_title">Yüksəltdən sonra Yenidən İdentifikasiya et</string>
<string name="settings_su_reauth_summary">Tətbiq yeniləmələridən sonra superuser icazələrini yenidən identifikasiya et</string>
<string name="multiuser_mode">Çox-istifadəçi modu</string>
<string name="settings_owner_only">Yalnız cihaz sahibi</string>
<string name="settings_owner_manage">Cihaz sahibinin idarəçiliyində</string>
<string name="settings_user_independent">İstifadəçidən asılı olmayaraq</string>
<string name="owner_only_summary">Yalnız cihaz sahibinin root icazəsi var.</string>
<string name="owner_manage_summary">Yalnız cihaz sahibi root icazələrini redaktə edə və icazə istəkləri qəbul edə bilər.</string>
<string name="user_independent_summary">Hər istifadəçinin ayrı root qaydaları var.</string>
<string name="mount_namespace_mode">Adlarfəzası Modunu Qoş</string>
<string name="settings_ns_global">Qlobal Adlarfəzası</string>
<string name="settings_ns_requester">Keçmə Adlarfəzası</string>
<string name="settings_ns_isolate">Ayrılmış Adlarfəzası</string>
<string name="global_summary">Bütün root sessyaları qlobal qoşma adlarfəzasından istifadə edir.</string>
<string name="requester_summary">Root sessyaları soruşulan adlarfəzasından birindən digərinə keçirəcək.</string>
<string name="isolate_summary">Hər bir root sessyasının ayrılmış adlarfəzası olacaq.</string>
<string name="request_timeout">İstək Vaxtaşımı</string>
<string name="superuser_notification">Superuser Bildirişi</string>
<string name="settings_su_reauth_title">Yüksəltdikdən sonra yenidən səlahiyətləndir</string>
<string name="settings_su_reauth_summary">Tətbiqləri yüksəltdikdən sonra Superuser icazəsi istə</string>
<string name="settings_su_tapjack_title">Tapjack Qoruması</string>
<string name="settings_su_tapjack_summary">Superuser icazə pəncərəsi digər pəncərələr tərəfindən əngəlləndikdə heçbir girişə cavab verməyəcək</string>
<string name="settings_su_biometric_title">Biometrik İcazə</string>
<string name="settings_su_biometric_summary">Superuser istəkləri üçün biometrik icazədən istifadə et</string>
<string name="no_biometric">Cihaz ya dəstəklənmir ya da biometrik ayarlar yoxdur</string>
<string name="settings_customization">Özəlləşdirmə</string>
<string name="setting_add_shortcut_summary">Tətbiqi gizlətdikdən sonra tapmaq çətin olmasın deyə ana ekrana qısayol əlavə et</string>
<string name="settings_doh_title">HTTPS əvəzinə DNS</string>
<string name="settings_doh_description">Bəzi ölkələrdə DNS problemlərini həll edir</string>
<!--Superuser-->
<string name="su_request_title">Superuser Tələbi</string>
<string name="deny">Ləğv et</string>
<string name="prompt">Yönləndir</string>
<string name="grant">Təmin et</string>
<string name="su_warning">Cihazın tam icazəsi ilə təmin edin.\nƏmin deyilsinizsə ləğv edin!</string>
<string name="forever">Sonsuz</string>
<string name="once">Bir dəfəlik</string>
<string name="tenmin">10 dəq</string>
<string name="twentymin">20 dəq</string>
<string name="thirtymin">30 dəq</string>
<string name="sixtymin">60 dəq</string>
<string name="su_allow_toast">%1$s SuperUser icazəsi ilə təmin edildi</string>
<string name="su_deny_toast">%1$s SuperUser icazəsi ilə təmin edilmədi</string>
<string name="su_snack_grant">%1$s üçün Superuser icazəsi verilib</string>
<string name="su_snack_deny">%1$s üçün Superuser icazəsi verilməyib</string>
<string name="su_snack_notif_on">%1$s üçün bildirişlər açıqdır</string>
<string name="su_snack_notif_off">%1$s üçün bildirişlər bağlıdır</string>
<string name="su_snack_log_on">%1$s üçün giriş açıqdır</string>
<string name="su_snack_log_off">%1$s üçün giriş bağlıdır</string>
<string name="su_revoke_title">Ləğv olunsun?</string>
<string name="su_revoke_msg">%1$s üçün haqları ləğv etməyi təsdiq edirsiniz?</string>
<string name="toast">Tost</string>
<string name="none">Heçnə</string>
<string name="multiuser_mode">Çox-istifadəçi Modu</string>
<string name="settings_owner_only">Yalnız Cihazın Yiyəsi</string>
<string name="settings_owner_manage">Cihaz Yiyəsinin İdarəsində</string>
<string name="settings_user_independent">İstifadəçidən-Asılı</string>
<string name="owner_only_summary">Yalnız cihaz yiyəsində root icazəsi var</string>
<string name="owner_manage_summary">Yalnız cihaz yiyəsi root icazəsi verə yaxud istəyə bilər</string>
<string name="user_independent_summary">Hər istifadəçinin öz root icazəsi var</string>
<!--Superuser logs-->
<string name="pid">PID: %1$d</string>
<string name="target_uid">Hədəf UID: %1$d</string>
<string name="mount_namespace_mode">Adlarfəzası modunu qoş</string>
<string name="settings_ns_global">Beynəlxalq Adlarfəzası</string>
<string name="settings_ns_requester">Adlarfəzası Daxil et</string>
<string name="settings_ns_isolate">Təklənmiş Adlarfəzası</string>
<string name="global_summary">Bütün kök girişləri beynəlxaq adlarfəzası işlədəcək</string>
<string name="requester_summary">Bütün kök girişləri öz adlarfəzalarından icazə alacaq</string>
<string name="isolate_summary">Hər kök giriş üçün ayrıca kök adlarfəzası olacaq</string>
<!-- MagiskHide -->
<string name="show_system_app">Sistem tətbiqlərini göstər</string>
<!--Notifications-->
<string name="update_channel">Magisk Yeniləmələri</string>
<string name="progress_channel">İrəliləmə Bildirişləri</string>
<string name="updated_channel">Yeniləmə Bitdi</string>
<string name="download_complete">Endirmə Bitdi</string>
<string name="download_file_error">Faylı endirmək olmadı</string>
<string name="magisk_update_title">Magisk Yeniləməsi Var!</string>
<string name="updated_title">Magisk Yeniləndi</string>
<string name="updated_text">Tətbiqi açmaq üçün toxun</string>
<!--Toasts, Dialogs-->
<string name="yes">Bəli</string>
<string name="no">Xeyr</string>
<string name="repo_install_title">Quraşdır %1$s %2$s(%3$d)</string>
<string name="download">Endir</string>
<string name="reboot">Yenidən başlat</string>
<string name="release_notes">Yeniliklər</string>
<string name="flashing">Qurulur…</string>
<string name="done">Bitdi!</string>
<string name="failure">Alınmadı!</string>
<string name="hide_app_title">Magisk tətbiqi gizlədilir…</string>
<string name="open_link_failed_toast">Keçidi açası tətbiq yoxdur</string>
<string name="complete_uninstall">Tamamilə sil</string>
<string name="restore_img">Nüsxələri Qaytar</string>
<string name="restore_img_msg">Qaytarılır…</string>
<string name="restore_done">Qaytarıldı!</string>
<string name="restore_fail">Hazır nüsxələr mövcud deyil!</string>
<string name="setup_fail">Qurma alınmadı</string>
<string name="env_fix_title">Əlavə qurmaya ethiyac var</string>
<string name="env_fix_msg">Cihazınız Magiskin düzgün işləməsi üçün əlavə qurmaya ehtiyac duyur. Yenidən başlatmaq istəyirsiniz?</string>
<string name="setup_msg">Qurulur…</string>
<string name="authenticate">Səlahiyətləndirilir</string>
<string name="unsupport_magisk_title">Bu Magisk versiyası dəstəklənmir</string>
<string name="unsupport_magisk_msg">Tətbiqin bu versiyası Magiskin %1$s versiyasından aşağıları dəstəkləmir.\n\nTətbiq sanki Magisk heç yoxmuş kimi davranacaq, lütfən Magiski yüksəldin.</string>
<string name="unsupport_general_title">Anormal Hal</string>
<string name="unsupport_system_app_msg">Bu tətbiqi sistem tətbiqi kimi açmaq olmur. Onu yenidən istifadəçi tətbiqi etməlisiniz.</string>
<string name="unsupport_other_su_msg">Magiskdən olmayan \"su\" tapıldı. Lütfən digər kök icazələrini silin yaxud Magiski yenidən quraşdırın.</string>
<string name="unsupport_external_storage_msg">Magisk xarici yaddaşa qurulub. Lütfən tətbiqi daxili yaddaşa keçirin.</string>
<string name="unsupport_nonroot_stub_msg">Gizli Magisk tətbiqi kök itirildiyinə görə işləməyəcək. Orijinal APKnı geri qaytarın.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Bu funksiyanı işə salmaq üçün yaddaş icazəsi verin</string>
<string name="post_notifications_denied">Bu funksiyanı işə salmaq üçün bildiriş icazəsi verin</string>
<string name="install_unknown_denied">"bilinməyən tətbiqləri quraşdır"\ı açsanız bu funksiya işə düşəcək</string>
<string name="add_shortcut_title">Ana ekranda qısayol yarat</string>
<string name="add_shortcut_msg">Tətbiqi gizlətdikdən sonra tapmaq çətin olmasın deyə ana ekranda qısayol yaradılsın?</string>
<string name="app_not_found">Bu işi görəsi heçbir tətbiq yoxdur</string>
<string name="reboot_apply_change">Dəyişikliklər təkrar başladıqdan sonra olacaq</string>
<string name="restore_app_confirmation">Gizli tətbiq əvvəlki halına qayıdacaq. Davam edilsin?</string>
</resources>

View File

@@ -1,79 +1,154 @@
<resources>
<!--Welcome Activity-->
<!--Sections-->
<string name="modules">Модули</string>
<string name="superuser">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>
<!--Status Fragment-->
<string name="invalid_update_channel">Невалиден канал за актуализации</string>
<!--Install Fragment-->
<string name="keep_force_encryption">Запазване на наложеното криптиране</string>
<string name="keep_dm_verity">Запазване на AVB 2.0/dm-verity</string>
<string name="uninstall_magisk_title">Деинсталиране на Magisk</string>
<string name="uninstall_magisk_msg">Всички модули ще бъдат изключени/премахнати. Руут достъпът ще бъде премахнат и е възможно криптиране на данните Ви.</string>
<string name="update">Актуализация</string>
<!--Module Fragment-->
<string name="no_info_provided">(Не е представена информация)</string>
<string name="reboot_recovery">Рестартиране в режима за възстановяване</string>
<string name="reboot_bootloader">Рестартиране в буутлоудъра</string>
<string name="reboot_download">Рестартиране в даунлоуд режима</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-->
<!--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="hide">Скриване</string>
<string name="home_package">Пакет</string>
<string name="home_app_title">Приложение</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">Достъпно е издание на Magisk.</string>
<string name="release_notes">Бележки</string>
<string name="manager_download_install">Докоснете за изтегляне и инсталиране.</string>
<string name="update_channel">Актуализации на Magisk</string>
<string name="flashing">Инсталиране</string>
<string name="open_link_failed_toast">Не е намерено приложение за отваряне на препратката.</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="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_title">Допълнително надстройване</string>
<string name="setup_msg">Надстройването на средата е в ход…</string>
<string name="download_file_error">Грешка при изтегляне на файла.</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 е, и винаги ще бъде, безплатен и с отворен изходен код. Въпреки това можете да покажете подкрапата си чрез дарение.</string>
<string name="home_installed_version">Инсталиранo</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Ако вътрешното хранилище е разшифровано с Magisk, то ще бъде шифровано отново!</string>
<!--Settings Activity -->
<!--Install-->
<string name="keep_force_encryption">Запазване на наложеното шифроване</string>
<string name="keep_dm_verity">Запазване на AVB 2.0/dm-verity</string>
<string name="patch_vbmeta">Закърпване на vbmeta в образ на boot</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)</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="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>
<!--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>
<!--SafetyNet-->
<!--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="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>
<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">Инсталира междинно приложение с произволен идестификатор и име</string>
<string name="settings_restore_app_title">Възстановяване на приложението на Magisk</string>
<string name="settings_restore_app_summary">Показва и възстановява оригиналното приложение</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="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">Въведете потребителски адрес</string>
<string name="settings_hosts_title">Несистемни хостове</string>
<string name="settings_hosts_summary">Поддръжка на несистемни хостове за използване на приложения, блокиращи реклами.</string>
<string name="settings_hosts_toast">Добавен е модул с несистемни хостове.</string>
<string name="settings_update_custom_msg">Адрес на потребителски канал</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_error">Изизква %1$s да бъде включено</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>
@@ -84,55 +159,86 @@
<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">Superuser достъп</string>
<string name="superuser_access">Достъп до суперпотребителя</string>
<string name="auto_response">Автоматичен отговор</string>
<string name="request_timeout">Време за запитване</string>
<string name="superuser_notification">Superuser известие</string>
<string name="settings_su_reauth_title">Повторно запитване след актуализация</string>
<string name="settings_su_reauth_summary">Повторно запитване за Superuser достъп след актуализация на приложенията.</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_biometric_title">Биометрично удостоверяване</string>
<string name="settings_su_biometric_summary">За получаване на достъп до суперпотребителя е необходимо биометрично удостоверяване</string>
<string name="no_biometric">Устройството не се поддръжа или липсват биометрични настройки</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="multiuser_mode">Потребителски достъп</string>
<string name="settings_owner_only">Само собственик</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_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="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">Всички сесии с достъп до суперпотребителя използват общото пространство от имена</string>
<string name="requester_summary">Всички сесии с достъп до суперпотребителя наследяват пространството от имена на запитващото приложение</string>
<string name="isolate_summary">Всички сесии с достъп до суперпотребителя получават изолирани пространства от имена</string>
<!--Superuser-->
<string name="su_request_title">Запитване за Superuser достъп</string>
<string name="deny">Отказ</string>
<string name="prompt">Запитване</string>
<string name="grant">Разрешаване</string>
<string name="su_warning">Дава пълен достъп до устройството.\Откажете, ако не сте сигурни.</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 е разрешен Superuser достъп.</string>
<string name="su_deny_toast">На %1$s е отказан Superuser достъп.</string>
<string name="su_snack_grant">На %1$s е предоставен Superuser достъп.</string>
<string name="su_snack_deny">На %1$s е отказан Superuser достъп.</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">Toast</string>
<string name="none">Без</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>
<!--Superuser logs-->
<string name="target_uid">Целеви UID: %1$d</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="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_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="authenticate">Удостоверяване</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 не може да продължи да работи, защото достъпът до правата на суперпотребителя е загубен. Възстановете оригиналното приложение.</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

@@ -7,7 +7,8 @@
<string name="settings">Nastavení</string>
<string name="install">Instalovat</string>
<string name="section_home">Domů</string>
<string name="section_theme">Téma</string>
<string name="section_theme">Témata</string>
<string name="denylist">DenyList</string>
<!--Home-->
<string name="no_connection">Žádné připojení</string>
@@ -19,10 +20,12 @@
<string name="home_package">Balíček</string>
<string name="home_app_title">Aplikace</string>
<string name="home_notice_content">Stahujte Magisk POUZE z oficiální stránky GitHub. Soubory z neznámých zdrojů mohou být škodlivé!</string>
<string name="home_support_title">Podpořte nás</string>
<string name="home_follow_title">Sledujte nás</string>
<string name="home_item_source">Zdroj</string>
<string name="home_support_content">Magisk je a vždy bude svobodný s otevřeným kódem. Můžete nám však zaslat malý dar jako poděkování.</string>
<string name="home_installed_version">Nainstalovano</string>
<string name="home_installed_version">Nainstalováno</string>
<string name="home_latest_version">Poslední</string>
<string name="invalid_update_channel">Neplatný kanál aktualizace</string>
<string name="uninstall_magisk_title">Odinstalovat Magisk</string>
@@ -31,6 +34,7 @@
<!--Install-->
<string name="keep_force_encryption">Ponechat Force Encryption</string>
<string name="keep_dm_verity">Ponechat AVB 2.0/DM-Verity</string>
<string name="patch_vbmeta">Patchnout vbmeta do boot obrazu</string>
<string name="recovery_mode">Režim Recovery</string>
<string name="install_options_title">Možnosti</string>
<string name="install_method_title">Způsob</string>
@@ -48,7 +52,7 @@
<!--Superuser-->
<string name="su_request_title">Požadavek SuperUser</string>
<string name="touch_filtered_warning">Protože aplikace zavírá požadavek SuperUser, Magisk nemůže ověřit Vaši odpověď</string>
<string name="touch_filtered_warning">Magisk nemůže ověřit Vaši odpověď, protože aplikace zavírá požadavek SuperUser</string>
<string name="deny">Zakázat</string>
<string name="prompt">Zeptat se</string>
<string name="grant">Povolit</string>
@@ -68,7 +72,7 @@
<string name="su_snack_log_on">Protokolování %1$s je povoleno</string>
<string name="su_snack_log_off">Protokolování %1$s je zakázáno</string>
<string name="su_revoke_title">Smazat?</string>
<string name="su_revoke_msg">Chcete smazat protokol k oprávnění pro %1$s?</string>
<string name="su_revoke_msg">Potvrzením odeberete %1$s oprávnění SuperUser</string>
<string name="toast">Text</string>
<string name="none">Žádné</string>
@@ -77,13 +81,16 @@
<string name="superuser_policy_none">Žádná aplikace nepožádala o oprávnění SuperUser.</string>
<!--Logs-->
<string name="log_data_none">Žádné protokoly. Vyzkoušejte nějakou aplikaci vyžadující oprávnění SuperUser.</string>
<string name="log_data_magisk_none">Protokoly Magisk jsou prázdné. To je zvláštní!</string>
<string name="log_data_none">Nemáte žádné protokoly. Vyzkoušejte nějakou aplikaci vyžadující oprávnění SuperUser</string>
<string name="log_data_magisk_none">Protokoly Magisk jsou prázdné. To je zvláštní</string>
<string name="menuSaveLog">Uložit protokol</string>
<string name="menuClearLog">Smazat protokol</string>
<string name="logs_cleared">Protokol byl smazán</string>
<string name="pid">PID:%1$d</string>
<string name="target_uid">Cílové UID: %1$d</string>
<string name="target_pid">Připojit PID cílového ns: %s</string>
<string name="selinux_context">SELinux kontext: %s</string>
<string name="supp_group">Sekundární skupina: %s</string>
<!--SafetyNet-->
@@ -105,6 +112,12 @@
<string name="module_state_restore">Obnovit</string>
<string name="module_action_install_external">Instalace z úložiště</string>
<string name="update_available">Dostupná aktualizace</string>
<string name="suspend_text_riru">Modul byl pozastaven, protože je povolen %1$s</string>
<string name="suspend_text_zygisk">Modul byl pozastaven, protože %1$s není povoleno</string>
<string name="zygisk_module_unloaded">Modul Zygisk nebyl načten z důvodu nekompatibility</string>
<string name="module_empty">Není nainstalován žádný modul</string>
<string name="confirm_install">Instalovat modul %1$s?</string>
<string name="confirm_install_title">Potvrzení instalace</string>
<!--Settings-->
<string name="settings_dark_mode_title">Režim motivu</string>
@@ -115,23 +128,29 @@
<string name="settings_download_path_title">Složka pro stahování</string>
<string name="settings_download_path_message">Soubory budou uloženy do %1$s.</string>
<string name="settings_hide_app_title">Skrýt aplikaci Magisk</string>
<string name="settings_hide_app_summary">Skryjete aplikaci náhodným ID balíčku a vlastním názvem aplikace.</string>
<string name="settings_hide_app_summary">Skryje aplikaci náhodným ID balíčku a vlastním názvem aplikace</string>
<string name="settings_restore_app_title">Obnovit aplikaci Magisk</string>
<string name="settings_restore_app_summary">Obnovíte aplikaci zpět do původního APK.</string>
<string name="settings_restore_app_summary">Obnoví aplikaci zpět do původního APK</string>
<string name="language">Jazyk</string>
<string name="system_default">(výchozí podle systému)</string>
<string name="settings_check_update_title">Zkontrolovat aktualizace</string>
<string name="settings_check_update_summary">Povolíte pravidelnou kontrolu aktualizace na pozadí.</string>
<string name="settings_check_update_summary">Povolí pravidelnou kontrolu aktualizace na pozadí</string>
<string name="settings_update_channel_title">Kanál aktualizace</string>
<string name="settings_update_stable">Stabilní</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Vlastní</string>
<string name="settings_update_custom_msg">Vložte vlastní URL</string>
<string name="settings_hosts_title">Nesystémový hostitel</string>
<string name="settings_hosts_summary">Přidáte modul pro podporu nesystémových hostitelů v aplikaci AdBlock.</string>
<string name="settings_hosts_toast">Přidán systémový modul hostitelů</string>
<string name="settings_zygisk_summary">Spustí části Magisku v démonu Zygote</string>
<string name="settings_denylist_title">Vynutit DenyList</string>
<string name="settings_denylist_summary">Na procesy v Denylistu nebudou aplikovány žádné změny, nebo modifikace způsobené Magiskem</string>
<string name="settings_denylist_error">Tato funkce vyžaduje povolení %1$s</string>
<string name="settings_denylist_config_title">Nastavit DenyList</string>
<string name="settings_denylist_config_summary">Vyberte procesy, které mají být zahrnuty v DenyListu</string>
<string name="settings_hosts_title">Nesystémoví hostitelé</string>
<string name="settings_hosts_summary">Přidá modul pro podporu nesystémových hostitelů v aplikaci AdBlock</string>
<string name="settings_hosts_toast">Modul nesystémových hostitelů přidán</string>
<string name="settings_app_name_hint">Nový název</string>
<string name="settings_app_name_helper">Název aplikace bude nahrazen tímto názvem.</string>
<string name="settings_app_name_helper">Název aplikace bude nahrazen tímto názvem</string>
<string name="settings_app_name_error">Neplatný formát</string>
<string name="settings_su_app_adb">Aplikace a ADB</string>
<string name="settings_su_app">Pouze aplikace</string>
@@ -150,22 +169,22 @@
<string name="settings_su_reauth_title">Opětovné ověření po aktualizaci</string>
<string name="settings_su_reauth_summary">Opětovné ověření oprávnění SuperUser po aktualizaci aplikace.</string>
<string name="settings_su_tapjack_title">Povolit ochranu před TapJack</string>
<string name="settings_su_tapjack_summary">Okno dialogu SuperUser nebude reagovat na kliknutí v případě, že je zavřené nebo překryté jiným oknem.</string>
<string name="settings_su_tapjack_summary">Okno dialogu SuperUser nebude reagovat na kliknutí v případě, že je zavřené nebo překryté jiným oknem</string>
<string name="settings_su_biometric_title">Povolit biometrické ověření</string>
<string name="settings_su_biometric_summary">Použijte biometrické ověření pro povolení požadavků SuperUser.</string>
<string name="no_biometric">Nepodporované zařízení nebo není biometrické ověření povolené</string>
<string name="settings_su_biometric_summary">Použije biometrické ověření pro povolení požadavků SuperUser</string>
<string name="no_biometric">Nepodporované zařízení, nebo není povolené biometrické ověření</string>
<string name="settings_customization">Přizpůsobit</string>
<string name="setting_add_shortcut_summary">Přidejte odkaz na domovskou obrazovku v případě, že se po skrytí aplikace její název a ikona těžko rozpoznávají.</string>
<string name="settings_doh_title">DNS nebo HTTPS</string>
<string name="settings_doh_description">Řešení pro opravy DNS v některých zemích.</string>
<string name="setting_add_shortcut_summary">Přidá odkaz na domovskou obrazovku v případě, že se po skrytí aplikace její název a ikona těžko rozpoznávají.</string>
<string name="settings_doh_title">DNS přes HTTPS</string>
<string name="settings_doh_description">Obejde DNS v některých zemích</string>
<string name="multiuser_mode">Režim více uživatelů</string>
<string name="settings_owner_only">Vlastník zařízení</string>
<string name="settings_owner_manage">Správce zařízení</string>
<string name="settings_user_independent">Všichni uživatelé</string>
<string name="owner_only_summary">Pouze vlastník má přístup ROOT.</string>
<string name="owner_manage_summary">Přístup ROOT má správce zařízení, který přijímá požadavky k přístupu.</string>
<string name="user_independent_summary">Každý uživatel má svá vlastní pravidla přístupu ROOT.</string>
<string name="owner_only_summary">Pouze vlastník má přístup ROOT</string>
<string name="owner_manage_summary">Přístup ROOT má správce zařízení, který přijímá požadavky k přístupu</string>
<string name="user_independent_summary">Každý uživatel má svá vlastní pravidla přístupu ROOT</string>
<string name="mount_namespace_mode">Režim připojení jmenného prostoru</string>
<string name="settings_ns_global">Globální jmenný prostor</string>
@@ -178,33 +197,51 @@
<!--Notifications-->
<string name="update_channel">Aktualizace Magisk</string>
<string name="progress_channel">Oznámení o průběhu</string>
<string name="updated_channel">Aktualizace dokončena</string>
<string name="download_complete">Stahování dokončeno</string>
<string name="download_file_error">Chyba při stahování souboru</string>
<string name="magisk_update_title">Aktualizace Magisk je dostupná!</string>
<string name="updated_title">Magisk aktualizován</string>
<string name="updated_text">Klepnutím otevřete aplikaci</string>
<!--Toasts, Dialogs-->
<string name="yes">ANO</string>
<string name="no">NE</string>
<!--Toasts, Dialogs-->
<string name="yes">Ano</string>
<string name="no">Ne</string>
<string name="repo_install_title">Instalovat %1$s %2$s(%3$d)</string>
<string name="download">Stáhnout</string>
<string name="reboot">Restartovat</string>
<string name="release_notes">Poznámky k vydání</string>
<string name="flashing">Instalování</string>
<string name="release_notes">Seznam změn</string>
<string name="flashing">Flashuji</string>
<string name="done">Hotovo!</string>
<string name="failure">Selhalo!</string>
<string name="open_link_failed_toast">Nebyla nalezena žádná aplikace pro otevření odkazu.</string>
<string name="complete_uninstall">Odinstalovat</string>
<string name="failure">Nepodařilo se!</string>
<string name="hide_app_title">Skrývám aplikaci Magisk…</string>
<string name="open_link_failed_toast">Nebyla nalezena žádná aplikace pro otevření odkazu</string>
<string name="complete_uninstall">Kompletní odinstalace</string>
<string name="restore_img">Obnovit obrazy</string>
<string name="restore_img_msg">Obnovování…</string>
<string name="restore_done">Obnovení bylo provedeno!</string>
<string name="restore_fail">Výchozí záloha neexistuje!</string>
<string name="restore_done">Proces obnovování dokončen!</string>
<string name="restore_fail">Původní záloha neexistuje!</string>
<string name="setup_fail">Nastavení selhalo</string>
<string name="env_fix_title">Vyžaduje se další nastavení</string>
<string name="setup_msg">Nastavení je spuštěno…</string>
<string name="env_fix_title">Vyžadováno dodatečné nastavení</string>
<string name="env_fix_msg">Aby mohl Magisk správně fungovat, je třeba zařízení dodatečně nastavit. Chcete pokračovat a restartovat zařízení?</string>
<string name="env_full_fix_msg">Aby vaše zařízení správně fungovalo, potřebuje se Magisk znovu flashnout. Nainstalujte znovu Magisk v aplikaci, režim Recovery nemůže získat správné informace o zařízení.</string>
<string name="setup_msg">Probíhá nastavení prostředí…</string>
<string name="authenticate">Ověřit</string>
<string name="unsupport_magisk_title">Nepodporovaná verze Magisk</string>
<string name="external_rw_permission_denied">Udělte oprávnění pro povolení této funkce.</string>
<string name="add_shortcut_title">Přidat odkaz na domovskou obrazovku</string>
<string name="app_not_found">Nelze nalézt žádnou aplikaci, která dokáže provést tuto akci.</string>
<string name="unsupport_magisk_msg">Tato verze aplikace nepodporuje Magisk ve verzi nižší než %1$s.\n\nAplikace se bude chovat, jako by žádný Magisk nebyl nainstalován. Aktualizujte prosím Magisk co nejdříve.</string>
<string name="unsupport_general_title">Abnormální stav</string>
<string name="unsupport_system_app_msg">Spuštění této aplikace jako systémové, není podporováno. Změňte prosím aplikaci zpět na uživatelskou.</string>
<string name="unsupport_other_su_msg">Byl detekován binární soubor \"su\", který nepochází z Magisk. Odeberte jakékoli konkurenční ROOT řešení a/nebo přeinstalujte Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk je nainstalován na externím úložišti. Přesuňte prosím aplikaci do interního úložiště.</string>
<string name="unsupport_nonroot_stub_msg">Skrytá aplikace Magisk nemůže dále fungovat, protože byl ztracen ROOT. Obnovte prosím původní soubor APK.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Pro povolení této funkce, povolte oprávnění pro přístup k úložišti</string>
<string name="post_notifications_denied">Pro povolení této funkce, povolte oznámení</string>
<string name="install_unknown_denied">Pro povolení této funkce, povolte "instalovat aplikace z neznámých zdrojů"</string>
<string name="add_shortcut_title">Přidat zástupce na domovskou obrazovku</string>
<string name="add_shortcut_msg">Po skrytí této aplikace může být obtížné rozpoznat její název a ikonu. Chcete přidat na domovskou obrazovku hezkého zástupce?</string>
<string name="app_not_found">Nebyla nalezena žádná aplikace, která by tuto akci provedla</string>
<string name="reboot_apply_change">Pro použití změn restartujte zařízení</string>
<string name="restore_app_confirmation">Tímto skrytou aplikaci obnovíte zpět na původní aplikaci. Opravdu to chcete udělat?</string>
</resources>

View File

@@ -13,7 +13,7 @@
<!--Home-->
<string name="no_connection">Keine Verbindung verfügbar</string>
<string name="app_changelog">Änderungen</string>
<string name="loading">Laden…</string>
<string name="loading">Laden </string>
<string name="update">Aktualisieren</string>
<string name="not_available">N/A</string>
<string name="hide">Verstecken</string>
@@ -46,8 +46,8 @@
<string name="install_inactive_slot_msg">Dein Gerät wird gezwungen, nach einem Neustart in den inaktiven Slot zu booten! Diese Option nur verwenden, wenn OTA abgeschlossen ist.\nWeiter?</string>
<string name="setup_title">Zusätzliche Einstellungen</string>
<string name="select_patch_file">Eine Datei auswählen und patchen</string>
<string name="patch_file_msg">Raw Image (*.img) oder ein ODIN tarfile (*.tar) auswählen</string>
<string name="reboot_delay_toast">Neustart in 5 Sekunden…</string>
<string name="patch_file_msg">Ein Raw Image (*.img), eine ODIN Tar-Datei (*.tar) oder eine Payload.bin (*.bin) auswählen</string>
<string name="reboot_delay_toast">Neustart in 5 Sekunden </string>
<string name="flash_screen_title">Installieren</string>
<!--Superuser-->
@@ -113,7 +113,9 @@
<string name="suspend_text_zygisk">Modul ausgesetzt, weil %1$s nicht aktiviert ist</string>
<string name="zygisk_module_unloaded">Zygisk-Modul aufgrund von Inkompatibilität nicht geladen</string>
<string name="module_empty">Kein Modul installiert</string>
<string name="confirm_install">Modul %1$s installieren?</string>
<string name="confirm_install_title">Installation bestätigen</string>
<!--Settings-->
<string name="settings_dark_mode_title">Themen-Modus</string>
<string name="settings_dark_mode_message">Modus auswählen, der am besten zu deinem Stil passt!</string>
@@ -206,20 +208,21 @@
<string name="download">Herunterladen</string>
<string name="reboot">Neustart</string>
<string name="release_notes">Anmerkungen zur Veröffentlichung</string>
<string name="flashing">Flashen…</string>
<string name="flashing">Flashen </string>
<string name="done">Fertig!</string>
<string name="failure">Fehlgeschlagen</string>
<string name="hide_app_title">Magisk-App verstecken…</string>
<string name="hide_app_title">Magisk-App verstecken </string>
<string name="open_link_failed_toast">Keine App zum öffnen des Links gefunden</string>
<string name="complete_uninstall">Vollständig deinstallieren</string>
<string name="restore_img">Image wiederherstellen</string>
<string name="restore_img_msg">Wiederherstellen…</string>
<string name="restore_img_msg">Wiederherstellen </string>
<string name="restore_done">Wiederherstellen fertig!</string>
<string name="restore_fail">Stock-Sicherung existiert nicht!</string>
<string name="setup_fail">Setup fehlgeschlagen</string>
<string name="env_fix_title">Zusätzliche Einrichtung erforderlich</string>
<string name="env_fix_msg">Magisk braucht ein zusätzliches Setup, um auf deinem Gerät zu funktionieren. Willst du fortfahren und dein Gerät neustarten?</string>
<string name="setup_msg">Laufzeitumgebung einrichten…</string>
<string name="env_full_fix_msg">Dein Gerät benötigt einen Reflash von Magisk, um richtig zu funktionieren. Bitte Magisk innerhalb der App neu installieren, der Wiederherstellungsmodus kann keine korrekten Geräteinformationen abrufen.</string>
<string name="setup_msg">Laufzeitumgebung einrichten …</string>
<string name="authenticate">Authentifizieren</string>
<string name="unsupport_magisk_title">Nicht unterstützte Magisk-Version</string>
<string name="unsupport_magisk_msg">Diese App-Version unterstützt keine Magisk-Version kleiner als %1$s.\n\nDie App verhält sich so, als ob kein Magisk installiert wäre. Bitte Magisk so bald wie möglich aktualisieren.</string>
@@ -231,7 +234,7 @@
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Speichererlaubnis erteilen, um diese Funktion zu aktivieren</string>
<string name="install_unknown_denied">Unbekannte Apps installieren erlauben, um diese Funktion zu aktivieren</string>
<string name="post_notifications_denied">Benachrichtigungen die Berechtigung erteilen, diese Funktion zu aktivieren</string>
<string name="add_shortcut_title">Verknüpfung zum Startbildschirm hinzufügen</string>
<string name="add_shortcut_msg">Nachdem du diese App versteckst, wird der Name und das Symbol eventuell schwer zu erkennen sein. Möchtest du zum Startbildschirm eine schöne Verknüpfung hinzufügen?</string>
<string name="app_not_found">Keine App gefunden, die diese Aktion verarbeitet</string>

View File

@@ -1,6 +1,6 @@
<resources>
<!--Sections-->
<!--Secciones-->
<string name="modules">Módulos</string>
<string name="superuser">Superusuario</string>
<string name="logs">Registros</string>
@@ -8,148 +8,150 @@
<string name="install">Instalar</string>
<string name="section_home">Inicio</string>
<string name="section_theme">Temas</string>
<string name="denylist">Lista de Denegacion</string>
<string name="denylist">Lista de denegación</string>
<!--Home-->
<string name="no_connection">Conexión no disponible</string>
<!--Inicio/Pantalla principal-->
<string name="no_connection">Sin conexión disponible</string>
<string name="app_changelog">Registro de cambios</string>
<string name="loading">Cargando…</string>
<string name="update">Actualizar</string>
<string name="not_available">No disponible</string>
<string name="hide">Ocultar</string>
<string name="home_package">Paquete</string>
<string name="home_package">Nombre de paquete:</string>
<string name="home_app_title">App</string>
<string name="home_notice_content">Descarga Magisk SÓLO de la página de GitHub oficial. Archivos de fuentes desconocidas pueden resultar maliciosos!</string>
<string name="home_support_title">Apóyenos</string>
<string name="home_follow_title">Síganos</string>
<string name="home_notice_content">Descarga Magisk únicamente desde la página oficial de GitHub. ¡Las descargas desde fuentes desconocidas pueden ser maliciosas!</string>
<string name="home_support_title">Apóyanos</string>
<string name="home_follow_title">Síguenos</string>
<string name="home_item_source">Código fuente</string>
<string name="home_support_content">Magisk es, y siempre será gratuito y de código abierto. Sin embargo, puede apoyarnos enviando una pequeña donación.</string>
<string name="home_installed_version">Instalado</string>
<string name="home_latest_version">Última</string>
<string name="home_support_content">Magisk es y siempre será gratis y de código abierto. Sin embargo, puedes mostrarnos tu apoyo mediante una donación.</string>
<string name="home_installed_version">Versión instalada:</string>
<string name="home_latest_version">Última versión disponible:</string>
<string name="invalid_update_channel">Canal de actualización inválido</string>
<string name="uninstall_magisk_title">Desinstalar Magisk</string>
<string name="uninstall_magisk_msg">¡Todos los módulos serán desactivados/eliminados!\nSe eliminará la raíz!\n¡Sus datos serán potencialmente encriptados si no lo están ya!</string>
<string name="uninstall_magisk_msg">Antes de desinstalar Magisk, ten en cuenta lo siguiente:\n• Todos los módulos serán desinstalados\n• Perderás el acceso root\n• Tu almacenamiento interno será reencriptado en caso de que no lo esté</string>
<!--Install-->
<string name="keep_force_encryption">Mantener cifrado forzado</string>
<!--Instalación-->
<string name="keep_force_encryption">Mantener FDE (Full-Disk Encryption)</string>
<string name="keep_dm_verity">Mantener AVB 2.0/dm-verity</string>
<string name="patch_vbmeta">Parche vbmeta en la imagen de arranque</string>
<string name="patch_vbmeta">Parchar vbmeta en el archivo boot.img</string>
<string name="recovery_mode">Modo recovery</string>
<string name="install_options_title">Opciones</string>
<string name="install_method_title">Método</string>
<string name="install_options_title">Opciones de instalación:</string>
<string name="install_method_title">Método de instalación:</string>
<string name="install_next">Siguiente</string>
<string name="install_start">Comencemos</string>
<string name="manager_download_install">Pulse para descargar e instalar</string>
<string name="install_start">Instalar</string>
<string name="manager_download_install">Pulsa para descargar e instalar</string>
<string name="direct_install">Instalación directa (recomendado)</string>
<string name="install_inactive_slot">Instalar en ranura inactiva (después de OTA)</string>
<string name="install_inactive_slot_msg">¡Su dispositivo será forzado a arrancar en la ranura inactiva actual después de un reinicio!\nSólo use esta opción después de que OTA haya terminado.\n¿Continuar?</string>
<string name="install_inactive_slot">Instalar en el slot inactivo (tras una OTA)</string>
<string name="install_inactive_slot_msg">Tu dispositivo será forzado a bootear en el slot inactivo actual después de un reinicio\nUsa esta opción solo después de que la actualización OTA se complete.\n¿Quieres continuar?</string>
<string name="setup_title">Configuración adicional</string>
<string name="select_patch_file">Seleccionar y parchar un archivo</string>
<string name="patch_file_msg">Seleccione una imagen raw (*.img) o un archivo tar de ODIN (*.tar)</string>
<string name="patch_file_msg">Selecciona una imagen raw (.img) o un archivo comprimido que la contenga (.tar), en caso de que quieras usar Odin (Samsung)</string>
<string name="reboot_delay_toast">Reiniciando en 5 segundos…</string>
<string name="flash_screen_title">Instalación</string>
<!--Superuser-->
<string name="su_request_title">Petición de superusuario</string>
<string name="touch_filtered_warning">Como otra app está escondiendo la solicitud de superusuario, Magisk no puede verificar tu respuesta</string>
<!--Superusuario-->
<string name="su_request_title">Solicitud de superusuario</string>
<string name="touch_filtered_warning">Hay una app superponiéndose a la solicitud de superusuario, por lo que Magisk no puede verificar tu respuesta.</string>
<string name="deny">Denegar</string>
<string name="prompt">Preguntar</string>
<string name="grant">Permitir</string>
<string name="su_warning">Permite acceso total a tu dispositivo.\n¡Denegar si no está seguro!</string>
<string name="grant">Conceder</string>
<string name="su_warning">Le concedes a esta app acceso completo a tu dispositivo.\n¡Rechaza la solicitud si desconfías de ella!</string>
<string name="forever">Siempre</string>
<string name="once">Una vez</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">Permitidos derechos de superusuario para %1$s</string>
<string name="su_deny_toast">Denegados derechos de superusuario para %1$s</string>
<string name="su_snack_grant">Derechos de superusuario para %1$s permitidos</string>
<string name="su_snack_deny">Derechos de superusuario para %1$s denegados</string>
<string name="tenmin">10 minutos</string>
<string name="twentymin">20 minutos</string>
<string name="thirtymin">30 minutos</string>
<string name="sixtymin">1 hora</string>
<string name="su_allow_toast">Le concediste privilegios de superusuario a %1$s</string>
<string name="su_deny_toast">Le denegaste privilegios de superusuario a %1$s</string>
<string name="su_snack_grant">Privilegios de superusuario para %1$s concedidos</string>
<string name="su_snack_deny">Privilegios de superusuario para %1$s denegados</string>
<string name="su_snack_notif_on">Notificaciones de %1$s habilitadas</string>
<string name="su_snack_notif_off">Notificaciones de %1$s deshabilitadas</string>
<string name="su_snack_log_on">Registros de %1$s habilitados</string>
<string name="su_snack_log_off">Registros de %1$s deshabilitados</string>
<string name="su_revoke_title">¿Revocar?</string>
<string name="su_revoke_msg">¿Confirmar para revocar derechos de %1$s?</string>
<string name="toast">Aviso</string>
<string name="none">Nada</string>
<string name="su_revoke_title">Revocar privilegios</string>
<string name="su_revoke_msg">Confirma para revocarle los privilegios de superusuario a %1$s</string>
<string name="toast">Mensaje emergente</string>
<string name="none">Ninguno</string>
<string name="superuser_toggle_notification">Notificaciones</string>
<string name="superuser_toggle_revoke">Revocar</string>
<string name="superuser_policy_none">Ninguna aplicación ha pedido permiso de superusuario todavía.</string>
<string name="superuser_policy_none">Ninguna app ha solicitado privilegios de superusuario aún.</string>
<!--Logs-->
<string name="log_data_none">No se tiene registro, intente usar más sus aplicaciones habilitadas para SU.</string>
<string name="log_data_magisk_none">Los registros de Magisk están vacíos, esto es muy raro.</string>
<!--Registros-->
<string name="log_data_none">No hay registros de apps disponibles</string>
<string name="log_data_magisk_none">No hay registros de Magisk disponibles</string>
<string name="menuSaveLog">Guardar registro</string>
<string name="menuClearLog">Limpiar registro ahora</string>
<string name="logs_cleared">Registro limpiado correctamente</string>
<string name="menuClearLog">Limpiar registro</string>
<string name="logs_cleared">Registros limpiados correctamente</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">UID de objetivo: %1$d</string>
<string name="target_uid">Target UID: %1$d</string>
<!--SafetyNet-->
<!--SafetyNet/PlayIntegrity-->
<!-- MagiskHide -->
<!--Denylist-->
<string name="show_system_app">Mostrar apps del sistema</string>
<string name="show_os_app">Mostrar apps del OS</string>
<string name="hide_filter_hint">Filtrar por nombre</string>
<string name="show_os_app">Mostrar apps del sistema operativo</string>
<string name="hide_filter_hint">Nombre de la app o del paquete</string>
<string name="hide_search">Buscar</string>
<!--Module -->
<string name="no_info_provided">(No hay información)</string>
<!--Módulos-->
<string name="no_info_provided">El creador del módulo no proporcionó ninguna descripción.</string>
<string name="reboot_userspace">Reinicio suave</string>
<string name="reboot_recovery">Reiniciar en modo recovery</string>
<string name="reboot_bootloader">Reiniciar en modo bootloader</string>
<string name="reboot_download">Reiniciar en modo download</string>
<string name="reboot_edl">Reiniciar en modo EDL</string>
<string name="module_version_author">%1$s por %2$s</string>
<string name="module_state_remove">Eliminar</string>
<string name="module_state_restore">Restaurar</string>
<string name="reboot_recovery">Modo Recovery</string>
<string name="reboot_bootloader">Modo Bootloader</string>
<string name="reboot_download">Modo Download</string>
<string name="reboot_edl">Modo EDL</string>
<string name="module_version_author">Versión %1$s, por %2$s</string>
<string name="module_state_remove">Desinstalar</string>
<string name="module_state_restore">Reinstalar</string>
<string name="module_action_install_external">Instalar desde almacenamiento</string>
<string name="update_available">Actualización disponible</string>
<string name="suspend_text_riru">Módulo suspendido porque %1$s está habilitado</string>
<string name="suspend_text_zygisk">Módulo suspendido porque %1$s no está habilitado</string>
<string name="zygisk_module_unloaded">Módulo Zygisk no cargado debido a incompatibilidad</string>
<string name="module_empty">Ningún módulo instalado</string>
<string name="suspend_text_riru">Módulo suspendido porque %1$s está activado</string>
<string name="suspend_text_zygisk">Módulo suspendido porque %1$s está desactivado</string>
<string name="zygisk_module_unloaded">El módulo Zygisk no se cargó por problemas de compatibilidad</string>
<string name="module_empty">No hay módulos instalados</string>
<string name="confirm_install">¿Quieres instalar el módulo %1$s?</string>
<string name="confirm_install_title">Confirmar instalación</string>
<!--Settings -->
<string name="settings_dark_mode_title">Elegir modo</string>
<string name="settings_dark_mode_message">¡Seleccione el modo que mejor se adapte a su estilo!</string>
<!--Ajustes-->
<string name="settings_dark_mode_title">Modo del tema</string>
<string name="settings_dark_mode_message">¡Elige el modo que más se adapte a tu estilo!</string>
<string name="settings_dark_mode_light">Claro</string>
<string name="settings_dark_mode_system">Seguir al sistema</string>
<string name="settings_dark_mode_dark">Oscuro</string>
<string name="settings_download_path_title">Ruta de Descarga</string>
<string name="settings_download_path_message">Los archivos se guardarán en %1$s</string>
<string name="settings_hide_app_title">Esconder la app de Magisk</string>
<string name="settings_hide_app_summary">Instalar una nueva app proxy con una ID de paquete aleatoria y una etiqueta personalizada</string>
<string name="settings_restore_app_title">Restaurar la app de Magisk</string>
<string name="settings_restore_app_summary">Descubrir la app y restaurarla al APK original</string>
<string name="settings_dark_mode_system">Predeterminado del sistema</string>
<string name="settings_download_path_title">Ruta de descarga</string>
<string name="settings_download_path_message">Los archivos serán guardados en la siguiente ruta:\n%1$s</string>
<string name="settings_hide_app_title">Ocultar la app de Magisk</string>
<string name="settings_hide_app_summary">Instalar una versión proxy de la app con un nombre de paquete aleatorio y una etiqueta personalizada</string>
<string name="settings_restore_app_title">Restaurar la app</string>
<string name="settings_restore_app_summary">Desoculta la app y la reemplaza por la original</string>
<string name="language">Idioma</string>
<string name="system_default">(Idioma del sistema)</string>
<string name="settings_check_update_title">Comprobar Actualizaciones</string>
<string name="settings_check_update_summary">Buscar periódicamente en segundo plano si existen actualizaciones</string>
<string name="system_default">Predeterminado del sistema</string>
<string name="settings_check_update_title">Buscar actualizaciones</string>
<string name="settings_check_update_summary">Busca actualizaciones periódicamente en segundo plano</string>
<string name="settings_update_channel_title">Canal de actualización</string>
<string name="settings_update_stable">Estable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Personalizado</string>
<string name="settings_update_custom_msg">Insertar una URL personalizada</string>
<string name="settings_zygisk_summary">Corre partes de magisk en zygote</string>
<string name="settings_denylist_title">Aplicar lista de denegacion</string>
<string name="settings_denylist_summary">Los procesos en la lista de denegacion tandran todas las modificaciones de magisk revertidas</string>
<string name="settings_denylist_error">Esta requere de %1$s para ser activada</string>
<string name="settings_denylist_config_title">Configurar lista de denegacion</string>
<string name="settings_denylist_config_summary">Seleccione los procesos para ser incluidos en la lista de denegacion</string>
<string name="settings_hosts_title">Systemless Hosts</string>
<string name="settings_hosts_summary">Soporte para bloqueadores de publicidad fuera de la partición system</string>
<string name="settings_hosts_toast">Módulo systemless hosts agregado</string>
<string name="settings_app_name_hint">Nuevo Nombre</string>
<string name="settings_app_name_helper">La app se reempaquetará</string>
<string name="settings_app_name_error">Formato inválido</string>
<string name="settings_su_app_adb">Aplicaciones y ADB</string>
<string name="settings_su_app">Sólo aplicaciones</string>
<string name="settings_su_adb">Sólo ADB</string>
<string name="settings_update_custom_msg">Ingresa la URL del canal personalizado</string>
<string name="settings_zygisk_summary">Ejecuta Magisk en el proceso Zygote de Android</string>
<string name="settings_denylist_title">Aplicar lista de denegación</string>
<string name="settings_denylist_summary">Las apps en la lista de denegación no serán modificadas por Magisk</string>
<string name="settings_denylist_error">Necesitas activar %1$s para usar esta función</string>
<string name="settings_denylist_config_title">Configurar lista de denegación</string>
<string name="settings_denylist_config_summary">Selecciona los procesos de cada app que se incluirán en la lista</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Prepara al archivo hosts para que los bloqueadores de anuncios puedan modificarlo sin alterar el sistema</string>
<string name="settings_hosts_toast">El módulo se instaló correctamente, reinicia para aplicar los cambios.</string>
<string name="settings_app_name_hint">Nuevo nombre de la app</string>
<string name="settings_app_name_helper">La app de Magisk será reempaquetada con este nombre</string>
<string name="settings_app_name_error">El nombre es inválido</string>
<string name="settings_su_app_adb">Permitir tanto a las apps como a ADB</string>
<string name="settings_su_app">Permitir solo a las apps</string>
<string name="settings_su_adb">Permitir solo a ADB</string>
<string name="settings_su_disable">Deshabilitado</string>
<string name="settings_su_request_10">10 segundos</string>
<string name="settings_su_request_15">15 segundos</string>
@@ -158,48 +160,48 @@
<string name="settings_su_request_45">45 segundos</string>
<string name="settings_su_request_60">60 segundos</string>
<string name="superuser_access">Acceso de superusuario</string>
<string name="auto_response">Respuesta automática</string>
<string name="request_timeout">Tiempo de petición</string>
<string name="auto_response">Respuesta predeterminada</string>
<string name="request_timeout">Duración de la solicitud</string>
<string name="superuser_notification">Notificación de superusuario</string>
<string name="settings_su_reauth_title">Re-autenticación</string>
<string name="settings_su_reauth_summary">Pedir permisos de superusuario nuevamente si una aplicación es actualizada o reinstalada</string>
<string name="settings_su_tapjack_title">Habilitar Protección contra Tapjacking</string>
<string name="settings_su_tapjack_summary">El cuadro de solicitud de superusuario no responderá mientras esté oculto por cualquier otra ventana o superposición</string>
<string name="settings_su_biometric_title">Habilitar autenticación biométrica</string>
<string name="settings_su_biometric_summary">Usar autenticación biométrica para permitir solicitudes de superusuario</string>
<string name="no_biometric">Dispositivo no compatible o las configuraciones biométricas no están habilitadas</string>
<string name="settings_su_reauth_title">Reautenticar después de una actualización</string>
<string name="settings_su_reauth_summary">Las apps volverán a solicitar privilegios de superusuario tras actualizarse</string>
<string name="settings_su_tapjack_title">Protección contra tapjacking</string>
<string name="settings_su_tapjack_summary">No podrás interactuar con las solicitudes de superusuario mientras estén tapadas por cualquier otra ventana o superposición</string>
<string name="settings_su_biometric_title">Autenticación biométrica</string>
<string name="settings_su_biometric_summary">Usa tu rostro, iris o huella digital para conceder privilegios de superusuario</string>
<string name="no_biometric">El dispositivo no está soportado o no has configurado ningún dato biométrico</string>
<string name="settings_customization">Personalización</string>
<string name="setting_add_shortcut_summary">Añade un bonito atajo en la pantalla de inicio en caso de que el nombre y el icono sean difíciles de reconocer después de ocultar la aplicación</string>
<string name="setting_add_shortcut_summary">Añade un atajo a la app con el ícono de Magisk a la pantalla de inicio en caso de que te resulte difícil reconocerla tras haberle cambiado el nombre y el ícono</string>
<string name="settings_doh_title">DNS sobre HTTPS</string>
<string name="settings_doh_description">Evitar envenenamiento de DNS en algunos países</string>
<string name="settings_doh_description">Proporciona una solución alternativa (workaround) contra el envenenamiento de DNS en algunos países</string>
<string name="multiuser_mode">Modo multiusuario</string>
<string name="settings_owner_only">Sólo administrador del dispositivo</string>
<string name="settings_owner_manage">Administrador del dispositivo</string>
<string name="settings_user_independent">Usuario independiente</string>
<string name="owner_only_summary">Sólo el administrador tiene acceso root</string>
<string name="owner_manage_summary">Sólo el administrador puede supervisar el acceso root y recibir solicitudes de otros usuarios</string>
<string name="user_independent_summary">Cada usuario tiene separadas sus propias reglas de root </string>
<string name="settings_owner_only">Propietario del dispositivo</string>
<string name="settings_owner_manage">Administrado por el propietario del dispositivo</string>
<string name="settings_user_independent">Acceso independiente</string>
<string name="owner_only_summary">Solo el administrador tiene acceso root</string>
<string name="owner_manage_summary">Solo el administrador puede manipular y recibir solicitudes de superusuario</string>
<string name="user_independent_summary">Cada usuario tiene sus propias reglas y acceso al root</string>
<string name="mount_namespace_mode">Montar Namespace </string>
<string name="settings_ns_global">Global Namespace</string>
<string name="settings_ns_requester">Heredar Namespace</string>
<string name="settings_ns_isolate">Aislar Namespace</string>
<string name="global_summary">Todas las sesiones de root utilizan el soporte Global Namespace</string>
<string name="requester_summary">Las sesiones de root heredarán las peticiones Namespace</string>
<string name="isolate_summary">Cada sesión root tendrá su propia Namespace</string>
<string name="mount_namespace_mode">Modo del namespace de montaje</string>
<string name="settings_ns_global">Namespace global</string>
<string name="settings_ns_requester">Namespace heredado</string>
<string name="settings_ns_isolate">Namespace aislado</string>
<string name="global_summary">Todas las sesiones de superusuario usarán el namespace de montaje global</string>
<string name="requester_summary">Las sesiones de superusuario heredarán el namespace de montaje de quien las solicita</string>
<string name="isolate_summary">Cada sesión de superusuario tendrá su propio namespace de montaje aislado</string>
<!--Notifications-->
<string name="update_channel">Actualización de Magisk</string>
<!--Notificaciones-->
<string name="update_channel">Actualizaciones de Magisk</string>
<string name="progress_channel">Notificaciones de progreso</string>
<string name="updated_channel">Actualización completa</string>
<string name="download_complete">Descarga Completa</string>
<string name="download_file_error">Error descargando archivo</string>
<string name="updated_channel">Actualización finalizada</string>
<string name="download_complete">Descarga finalizada</string>
<string name="download_file_error">Ocurrió un error en la descarga</string>
<string name="magisk_update_title">¡Actualización de Magisk disponible!</string>
<string name="updated_title">Magisk Actualizado</string>
<string name="updated_text">Toca para abrir la aplicación</string>
<string name="updated_title">Se actualizó Magisk</string>
<string name="updated_text">Pulsa para abrir la app</string>
<!--Toasts, Dialogs-->
<!--Alertas y diálogos-->
<string name="yes"></string>
<string name="no">No</string>
<string name="repo_install_title">Instalar %1$s %2$s(%3$d)</string>
@@ -207,34 +209,36 @@
<string name="reboot">Reiniciar</string>
<string name="release_notes">Notas de lanzamiento</string>
<string name="flashing">Flasheando…</string>
<string name="done">¡Hecho!</string>
<string name="failure">Ha fallado</string>
<string name="hide_app_title">Escondiendo la app de Magisk…</string>
<string name="open_link_failed_toast">No se encontró ninguna aplicación para abrir el enlace</string>
<string name="done">¡Listo!</string>
<string name="failure">¡Ocurrió un error!</string>
<string name="hide_app_title">Ocultando la app de Magisk…</string>
<string name="open_link_failed_toast">No se encontró ninguna app que pueda abrir este enlace</string>
<string name="complete_uninstall">Desinstalación completa</string>
<string name="restore_img">Restaurar imágenes</string>
<string name="restore_img">Solo restaurar las imágenes</string>
<string name="restore_img_msg">Restaurando…</string>
<string name="restore_done">¡Restauración Terminada!</string>
<string name="restore_fail">¡El respaldo de la imagen boot Stock no existe!</string>
<string name="setup_fail">Instalación fallida</string>
<string name="env_fix_title">Se requiere una instalación adicional</string>
<string name="env_fix_msg">Tu dispositivo necesita configuración adicional para el correcto funcionamiento de Magisk. ¿Quieres proceder y reiniciar?</string>
<string name="restore_done">¡Restauración completa!</string>
<string name="restore_fail">Oops... no se encontró una copia de seguridad de las imágenes originales</string>
<string name="setup_fail">Ocurrió un error en la configuración</string>
<string name="env_fix_title">Configuración adicional</string>
<string name="env_fix_msg">Tu dispositivo necesita una configuración adicional para que Magisk funcione correctamente. ¿Quieres continuar y reiniciar?</string>
<string name="env_full_fix_msg">Tu dispositivo necesita reinstalar Magisk para que este funcione correctamente. Por favor, reinstala Magisk desde la app, el modo recovery no puede obtener la información correcta del dispositivo.</string>
<string name="setup_msg">Ejecutando configuración de entorno…</string>
<string name="authenticate">Autenticar</string>
<string name="unsupport_magisk_title">Versión de Magisk no soportada</string>
<string name="unsupport_magisk_msg">Esta versión de la app no soporta versiones de Magisk inferiores a la %1$s.\n\nLa aplicación se comportará como si no tuvieses Magisk instalado, por favor actualiza Magisk tan pronto como sea posible.</string>
<string name="unsupport_magisk_msg">La versión actual de la app no soporta versiones de Magisk inferiores a la %1$s.\n\nLa app se comportará como si Magisk no estuviese instalado, por favor, actualízalo tan pronto como puedas</string>
<string name="unsupport_general_title">Estado anormal</string>
<string name="unsupport_system_app_msg">No se admite la ejecución de esta aplicación como una aplicación del sistema. Revierta la aplicación a una aplicación de usuario.</string>
<string name="unsupport_other_su_msg">Se ha detectado un binario \"su\" que no es de Magisk. Elimine cualquier solución raíz de la competencia y/o reinstale Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk está instalado en el almacenamiento externo. Mueva la aplicación al almacenamiento interno.</string>
<string name="unsupport_nonroot_stub_msg">La aplicación Magisk oculta no puede seguir funcionando porque se perdió la raíz. Restaura el APK original.</string>
<string name="unsupport_system_app_msg">La ejecución de esta app como app del sistema no está soportada. Por favor, vuelve a instalarla como usuario</string>
<string name="unsupport_other_su_msg">Se detectó un binario \"su\" ajeno a Magisk. Por favor, desinstala cualquier solución root de la competencia y/o reinstala Magisk</string>
<string name="unsupport_external_storage_msg">La app de Magisk está instalada en un almacenamiento externo, por favor, muévela al almacenamiento interno.</string>
<string name="unsupport_nonroot_stub_msg">La app de Magisk oculta no puede seguir funcionando porque se perdió el acceso root. Por favor, restaura el APK original</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Conceder permiso de almacenamiento para habilitar esta funcionalidad</string>
<string name="install_unknown_denied">Permitir "instalar aplicaciones desconocidas" para habilitar esta funcionalidad</string>
<string name="external_rw_permission_denied">Permite el acceso al almacenamiento para activar esta funcionalidad</string>
<string name="post_notifications_denied">Permite mostrar notificaciones para activar esta funcionalidad</string>
<string name="install_unknown_denied">Permite la instalación de apps desconocidas para activar esta funcionalidad</string>
<string name="add_shortcut_title">Añadir un atajo a la pantalla de inicio</string>
<string name="add_shortcut_msg">Tras esconder la app, su nombre e icono pueden resultar difíciles de reconocer. ¿Quieres añadir un acceso directo más bonito a la pantalla principal?</string>
<string name="app_not_found">No se ha encontrado ninguna app para manejar esta acción</string>
<string name="reboot_apply_change">Reiniciar para aplicar cambios</string>
<string name="restore_app_confirmation">Esto restaurará la aplicación oculta a la aplicación original. ¿Realmente quieres hacer esto?</string>
<string name="add_shortcut_msg">Añade un atajo a la app con el ícono de Magisk a la pantalla de inicio en caso de que te resulte difícil reconocerla tras haberle cambiado el nombre y el ícono</string>
<string name="app_not_found">No se encontró ninguna app que pueda realizar esta acción</string>
<string name="reboot_apply_change">Reinicia para aplicar los cambios</string>
<string name="restore_app_confirmation">Se restaurará la app oculta de vuelta a la original. ¿Quieres continuar?</string>
</resources>

View File

@@ -112,9 +112,9 @@
<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">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Custom Channel</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_hosts_title">نصب بدون حذف یا تغییر در فایل ها</string>
<string name="settings_hosts_summary">نصب بدون حذف یا تغییر در فایل ها رای ساپورت از برنامه های Adblock</string>
@@ -153,16 +153,16 @@
<string name="user_independent_summary">هر کاربر قوانین روت جداگانه خود را دارد</string>
<string name="mount_namespace_mode">نصب کردن 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="settings_ns_global">سراسری Namespace</string>
<string name="settings_ns_requester">وراثتی Namespace</string>
<string name="settings_ns_isolate">منزوی Namespace</string>
<string name="global_summary">همه سشن های روت از global 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">Progress اعلان</string>
<string name="progress_channel">اعلان پیشرفت</string>
<string name="download_complete">دانلود کامل شد</string>
<string name="download_file_error">خطا در دانلود فایل</string>
<string name="magisk_update_title">بروزرسانی Magisk در دسترس است!</string>

View File

@@ -46,7 +46,7 @@
<string name="install_inactive_slot_msg">Votre appareil sera obligatoirement réamorcé à partir de lespace (slot) actuellement inactif après son redémarrage !\nNutilisez uniquement cette option quaprès que la mise à jour OTA a été effectuée.\nVoulezvous continuer ?</string>
<string name="setup_title">Configuration supplémentaire</string>
<string name="select_patch_file">Sélectionnez le fichier cible du correctif</string>
<string name="patch_file_msg">Sélectionnez une image brute (*.img) ou une archive TAR ODIN (*.tar)</string>
<string name="patch_file_msg">Sélectionnez une image brute (*.img) ou une archive TAR ODIN (*.tar) ou un fichier payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Redémarrage dans 5 secondes…</string>
<string name="flash_screen_title">Installation</string>
@@ -113,6 +113,8 @@
<string name="suspend_text_zygisk">Module suspendu car %1$s nest pas actif</string>
<string name="zygisk_module_unloaded">Module Zygisk non chargé en raison dune incompatibilité</string>
<string name="module_empty">Aucun module installé</string>
<string name="confirm_install">Installer le module %1$s?</string>
<string name="confirm_install_title">Confirmer linstallation</string>
<!--Settings -->
<string name="settings_dark_mode_title">Mode du thème</string>
@@ -217,6 +219,7 @@
<string name="restore_done">Restauration effectuée !</string>
<string name="restore_fail">La sauvegarde par défaut nexiste pas !</string>
<string name="setup_fail">Échec de linstallation</string>
<string name="env_full_fix_msg">Votre périphérique nécessite de réinstaller Magisk pour fonctionner correctement. Merci de réinstaller Magisk par lapplication, le mode de récupération ne pouvant pas récupérer les informations correctement.</string>
<string name="env_fix_title">Installation supplémentaire requise</string>
<string name="env_fix_msg">Votre appareil a besoin dune installation supplémentaire afin que Magisk fonctionne correctement. Voulezvous effectuer cette installation maintenant puis redémarrer ?</string>
<string name="setup_msg">Configuration de lenvironnement en cours…</string>

View File

@@ -20,7 +20,7 @@
<string name="home_package">Paket</string>
<string name="home_app_title">Aplikasi</string>
<string name="home_notice_content">Unduh Magisk HANYA dari halaman GitHub resmi kami. File dari sumber yang tidak dikenal bisa berbahaya!</string>
<string name="home_notice_content">Unduh Magisk HANYA dari halaman GitHub resmi kami. File dari sumber yang tidak dikenal dapat berbahaya!</string>
<string name="home_support_title">Dukung kami</string>
<string name="home_follow_title">Ikuti Kami</string>
<string name="home_item_source">Sumber</string>
@@ -113,6 +113,8 @@
<string name="suspend_text_zygisk">Modul ditangguhkan karena %1$s tidak diaktifkan</string>
<string name="zygisk_module_unloaded">Modul Zygisk tidak dimuat karena ketidakcocokan</string>
<string name="module_empty">Tidak ada modul terpasang</string>
<string name="confirm_install">Pasang modul %1$s?</string>
<string name="confirm_install_title">Konfirmasi Pasang</string>
<!--Settings-->
<string name="settings_dark_mode_title">Mode tema</string>
@@ -219,6 +221,7 @@
<string name="setup_fail">Penyiapan gagal</string>
<string name="env_fix_title">Perlu penyiapan tambahan</string>
<string name="env_fix_msg">Perangkat Anda membutuhkan pengaturan tambahan untuk Magisk agar berfungsi dengan benar. Apakah Anda ingin melanjutkan dan Menyalakan ulang?</string>
<string name="env_full_fix_msg">Perangkat Anda membutuhkan pemasangan ulang Magisk agar berfungsi dengan baik. Silakan pasang ulang Magisk dalam aplikasi, mode recovery tidak dapat memperoleh info perangkat yang benar.</string>
<string name="setup_msg">Memproses penyiapan lingkungan…</string>
<string name="authenticate">Autentikasi</string>
<string name="unsupport_magisk_title">Versi Magisk tidak didukung</string>

View File

@@ -16,7 +16,7 @@
<string name="loading">Caricamento…</string>
<string name="update">Aggiorna</string>
<string name="not_available">N/D</string>
<string name="hide">Hide</string>
<string name="hide">Nascondi</string>
<string name="home_package">Pacchetto</string>
<string name="home_app_title">App</string>
@@ -46,7 +46,7 @@
<string name="install_inactive_slot_msg">Questo dispositivo verrà FORZATO ad avviarsi usando lo slot inattivo!\nUsa questo metodo solo dopo che un aggiornamento OTA è stato installato.\nVuoi continuare?</string>
<string name="setup_title">Configurazione aggiuntiva</string>
<string name="select_patch_file">Seleziona e aggiorna un file</string>
<string name="patch_file_msg">Seleziona un\'immagine in formato .img o un file ODIN .tar</string>
<string name="patch_file_msg">Seleziona un\'immagine in formato .img, un file .tar di ODIN o un file payload.bin</string>
<string name="reboot_delay_toast">Riavvio fra 5 secondi…</string>
<string name="flash_screen_title">Installazione</string>
@@ -113,6 +113,8 @@
<string name="module_empty">Nessun modulo installato</string>
<!--Settings -->
<string name="confirm_install">Vuoi installare il modulo %1$s?</string>
<string name="confirm_install_title">Conferma installazione</string>
<string name="settings_dark_mode_title">Impostazioni tema</string>
<string name="settings_dark_mode_message">Seleziona il tema che si adatta meglio al tuo stile!</string>
<string name="settings_dark_mode_light">Chiaro</string>
@@ -217,6 +219,7 @@
<string name="setup_fail">Configurazione fallita</string>
<string name="env_fix_title">Configurazione aggiuntiva richiesta</string>
<string name="env_fix_msg">Il tuo dispositivo necessita di una configurazione aggiuntiva per far funzionare Magisk correttamente. Vuoi procedere e riavviare il dispositivo?</string>
<string name="env_full_fix_msg">È necessario eseguire di nuovo il flash di Magisk per farlo funzionare correttamente. Reinstalla Magisk utilizzando l\'app, in modalità recovery non è possibile ottenere informazioni corrette sul dispositivo.</string>
<string name="setup_msg">Configurazione dell\'ambiente in corso…</string>
<string name="authenticate">Autentica</string>
<string name="unsupport_magisk_title">Versione di Magisk non supportata</string>
@@ -228,6 +231,7 @@
<string name="unsupport_nonroot_stub_msg">Dal momento che i permessi di root sono stati persi, l\'app di Magisk nascosta non può più funzionare. Ripristina l\'APK originale.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Consenti l\'accesso alla memoria del dispositivo per abilitare questa opzione</string>
<string name="post_notifications_denied">Consenti l\'invio di notifiche per abilitare questa opzione</string>
<string name="install_unknown_denied">Consenti l\'installazione di app sconosciute per abilitare questa funzionalità</string>
<string name="add_shortcut_title">Aggiungi collegamento alla schermata iniziale</string>
<string name="add_shortcut_msg">Dopo aver nascosto quest\'app, il suo nome e la sua icona potrebbero diventare difficili da riconoscere. Vuoi aggiungere una scorciatoia alla schermata principale?</string>

View File

@@ -11,7 +11,7 @@
<string name="denylist">거부목록</string>
<!--Home-->
<string name="no_connection">사용 가능한 연결 없음</string>
<string name="no_connection">인터넷 연결 없음</string>
<string name="app_changelog">앱 변경 사항</string>
<string name="loading">로딩중…</string>
<string name="update">업데이트</string>
@@ -33,7 +33,7 @@
<!--Install-->
<string name="keep_force_encryption">강제 암호화 유지</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity 유지</string>
<string name="patch_vbmeta">부트 이미지 vbmeta 패치</string>
<string name="patch_vbmeta">부트 이미지 vbmeta 패치</string>
<string name="recovery_mode">리커버리 모드</string>
<string name="install_options_title">옵션</string>
<string name="install_method_title">설치 방법</string>
@@ -80,7 +80,7 @@
<string name="superuser_policy_none">슈퍼유저 권한을 요청한 앱이 없습니다.</string>
<!--Logs-->
<string name="log_data_none">로그가 없습니다. SU 권한을 필요로 하는 앱을 사용하십시오.</string>
<string name="log_data_none">로그가 없습니다. 슈퍼유저 권한을 필요로 하는 앱을 사용하십시오.</string>
<string name="log_data_magisk_none">Magisk 로그가 없습니다.</string>
<string name="menuSaveLog">로그 저장</string>
<string name="menuClearLog">지금 로그 삭제</string>
@@ -108,8 +108,8 @@
<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-->
@@ -121,8 +121,8 @@
<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_hide_app_summary">랜덤 패키지 ID와 커스텀 앱 이름으로 Magisk 프록시 앱을 설치합니다.</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>
@@ -135,10 +135,10 @@
<string name="settings_update_custom_msg">사용자 지정 URL 입력</string>
<string name="settings_zygisk_summary">zygote 데몬에서 Magisk 부분 실행</string>
<string name="settings_denylist_title">DenyList 적용</string>
<string name="settings_denylist_summary">DenyList 프로세스 Magisk의 모든 수정사항을 되돌니다</string>
<string name="settings_denylist_summary">DenyList에 있는 프로세스를 실행할때 Magisk의 모든 수정사항을 되돌리고 실행합니다.</string>
<string name="settings_denylist_error">이 기능을 사용하려면 %1$s 활성화가 필요합니다</string>
<string name="settings_denylist_config_title">DenyList 구성</string>
<string name="settings_denylist_config_summary">denylist에 포함할 프로세스를 선택합니다.</string>
<string name="settings_denylist_config_summary">Denylist에 포함할 프로세스를 선택합니다.</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">광고 차단 앱에서 사용하는 systemless hosts를 지원합니다.</string>
<string name="settings_hosts_toast">Systemless hosts 모듈 추가됨</string>
@@ -160,9 +160,9 @@
<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_summary">앱이 업데이트되면 권한 승인 요청을 다시 합니다.</string>
<string name="settings_su_tapjack_title">탭재킹 보호 활성화</string>
<string name="settings_su_tapjack_summary">슈퍼유저 프롬프트 대화 상자가 다른 창이나 오버레이로 가려지는 동안 입력에 응답하지 않습니다.</string>
<string name="settings_su_tapjack_summary">슈퍼유저 프롬프트가 다른 창이나 오버레이로 가려지는 동안 입력을 무시합니다.</string>
<string name="settings_su_biometric_title">생체 인증 활성화</string>
<string name="settings_su_biometric_summary">슈퍼유저 요청 허용에 생체 인증을 사용합니다.</string>
<string name="no_biometric">지원되지 않는 기기이거나 등록된 생체 정보가 없습니다.</string>
@@ -176,16 +176,16 @@
<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_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="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>
<!--Notifications-->
<string name="update_channel">Magisk 업데이트</string>
@@ -194,7 +194,7 @@
<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_title">Magisk가 업데이트 되었습니다!</string>
<string name="updated_text">터치하여 앱 열기</string>
<!--Toasts, Dialogs-->
@@ -203,8 +203,8 @@
<string name="repo_install_title">%1$s %2$s(%3$d) 설치</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="hide_app_title">Magisk 앱 숨기는 중…</string>
@@ -213,22 +213,22 @@
<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">기기가 제대로 작동하려면 추가 설정이 필요합니다. 다시 시작 하시겠습니까?</string>
<string name="env_fix_msg">Magisk가 제대로 작동하려면 추가 설정이 필요합니다. 다시 시작 하시겠습니까?</string>
<string name="setup_msg">환경 설정 진행 중…</string>
<string name="authenticate">인증</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_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

@@ -1,133 +1,244 @@
<resources>
<!--Welcome Activity-->
<string name="modules">Papildiniai</string>
<string name="superuser">Supervartotojas</string>
<string name="logs">Įvykių sąrašas</string>
<!--Sections-->
<string name="modules">Moduliai</string>
<string name="superuser">Supernaudotojas</string>
<string name="logs">Žurnalas</string>
<string name="settings">Nustatymai</string>
<string name="install">Instaliuoti</string>
<string name="install">Įdiegti</string>
<string name="section_home">Pagrindinis</string>
<string name="section_theme">Temos</string>
<string name="denylist">DenyList</string>
<!--Status Fragment-->
<string name="invalid_update_channel">Neteisingas atnaujinimų nustatymas</string>
<!--Home-->
<string name="no_connection">Nėra ryšio</string>
<string name="app_changelog">Keitimų sąrašas</string>
<string name="loading">Įkeliama…</string>
<string name="update">Naujinti</string>
<string name="not_available">Neįdiegta</string>
<string name="hide">Slėpti</string>
<string name="home_package">Paketas</string>
<string name="home_app_title">Programėlė</string>
<!--Install Fragment-->
<string name="keep_force_encryption">Palikti priverstinį šifravimą</string>
<string name="keep_dm_verity">Palikti dm-verity</string>
<string name="home_notice_content">Magisk siųskites TIK iš oficialiojo GitHub puslapio. Failai iš nežinomų šaltinių gali būti kenkėjiški!</string>
<string name="home_support_title">Palaikykite mus</string>
<string name="home_follow_title">Sekite mus</string>
<string name="home_item_source">Pirminis kodas</string>
<string name="home_support_content">Magisk yra ir visada bus nemokamas, atvirojo kodo. Tačiau galite paaukoti pinigų, jei norite parodyti, kad jums rūpi.</string>
<string name="home_installed_version">Įdiegta versija</string>
<string name="home_latest_version">Naujausia versija</string>
<string name="invalid_update_channel">Neteisingas naujinimų kanalas</string>
<string name="uninstall_magisk_title">Pašalinti Magisk</string>
<string name="uninstall_magisk_msg">Visi papildiniai bus išjungti/pašalinti. Root bus panaikintas. Yra galimybė, kad duomenys bus užšifruoti…</string>
<string name="update">Atnaujinti</string>
<string name="uninstall_magisk_msg">Visi moduliai bus išjungti/pašalinti!\nRoot prieiga bus pašalinta!\nVidinė atmintis, iššifruota su Magisk, bus iš naujo užšifruota!</string>
<!--Module Fragment-->
<!--Install-->
<string name="keep_force_encryption">Neišjungti priverstinio šifravimo</string>
<string name="keep_dm_verity">Neišjungti AVB 2.0/dm-verity</string>
<string name="patch_vbmeta">Taisyti vbmeta boot vaizdą</string>
<string name="recovery_mode">Atkūrimo režimas</string>
<string name="install_options_title">Parinktys</string>
<string name="install_method_title">Būdas</string>
<string name="install_next">Toliau</string>
<string name="install_start">Įdiegti</string>
<string name="manager_download_install">Spustelėkite, kad atsisiųstumėte ir įdiegtumėte</string>
<string name="direct_install">Tiesioginis įdiegimas (rekomenduojama)</string>
<string name="install_inactive_slot">Įdiegti į antrąją vietą (po OTA naujinimo)</string>
<string name="install_inactive_slot_msg">Jūsų įremginys bus PRIVERSTAS pasileisti į dabartinę neaktyvią vietą po paleidimo iš naujo!\nNaudokite šią parinktį, kai OTA naujinimas yra baigtas.\nTęsti?</string>
<string name="setup_title">Išplėstinė sąranka</string>
<string name="select_patch_file">Pasirinkite ir taisykite failą</string>
<string name="patch_file_msg">Pasirinkite vaizdo failą (*.img) arba ODIN archyvą (*.tar)</string>
<string name="reboot_delay_toast">Paleidžiama iš naujo po 5 sekundžių…</string>
<string name="flash_screen_title">Įdiegimas</string>
<!--Superuser-->
<string name="su_request_title">Supernaudotojo užklausa</string>
<string name="touch_filtered_warning">Programėlė užstoja supernaudotojo užklausą, todėl Magisk negali patvirtinti jūsų atsakymo</string>
<string name="deny">Atmesti</string>
<string name="prompt">Klausti</string>
<string name="grant">Leisti</string>
<string name="su_warning">Suteikia prieigą prie jūsų įrenginio.\nAtmeskite, jei nesate tikri!</string>
<string name="forever">Amžinai</string>
<string name="once">Kartą</string>
<string name="tenmin">10 minučių</string>
<string name="twentymin">20 minučių</string>
<string name="thirtymin">30 minučių</string>
<string name="sixtymin">60 minučių</string>
<string name="su_allow_toast">%1$s suteiktos supernaudotojo teisės</string>
<string name="su_deny_toast">%1$s atmestos supernaudotojo teisės</string>
<string name="su_snack_grant">%1$s supernaudotojo teisės yra suteiktos</string>
<string name="su_snack_deny">%1$s supernaudotojo teisės yra atmestos</string>
<string name="su_snack_notif_on">%1$s pranešimai yra įjungti</string>
<string name="su_snack_notif_off">%1$s pranešimai yra išjungti</string>
<string name="su_snack_log_on">%1$s registravimas yra įjungtas</string>
<string name="su_snack_log_off">%1$s registravimas yra išjungtas</string>
<string name="su_revoke_title">Atšaukti?</string>
<string name="su_revoke_msg">Patvirtinkite %1$s supernaudotojo teisių atšaukimą</string>
<string name="toast">Iššokantys pranešimai</string>
<string name="none">Nėra</string>
<string name="superuser_toggle_notification">Pranešimai</string>
<string name="superuser_toggle_revoke">Atšaukti</string>
<string name="superuser_policy_none">Kol kas jokia programėlė neprašė supernaudotojo teisių.</string>
<!--Logs-->
<string name="log_data_none">Žurnalas tuščias</string>
<string name="log_data_magisk_none">Magisk žurnalas yra tuščias, keistoka</string>
<string name="menuSaveLog">Išsaugoti žurnalą</string>
<string name="menuClearLog">Valyti žurnalą</string>
<string name="logs_cleared">Žurnalas išvalytas</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Tikslinis UID: %1$d</string>
<!--SafetyNet-->
<!--MagiskHide-->
<string name="show_system_app">Rodyti sistemos programėles</string>
<string name="show_os_app">Rodyti OS programėles</string>
<string name="hide_filter_hint">Filtruoti pagal pavadinimą</string>
<string name="hide_search">Ieškoti</string>
<!--Module-->
<string name="no_info_provided">(Nėra informacijos)</string>
<string name="reboot_recovery">Perkrauti į Recovery</string>
<string name="reboot_bootloader">Perkrauti į Bootloader</string>
<string name="reboot_download">Perkrauti į Download režimą</string>
<string name="reboot_userspace">Paleidimas neišjungus</string>
<string name="reboot_recovery">Paleidimas į Recovery</string>
<string name="reboot_bootloader">Paleidimas į Bootloader</string>
<string name="reboot_download">Paleidimas į Download</string>
<string name="reboot_edl">Paleidimas į EDL</string>
<string name="module_version_author">%1$s nuo %2$s</string>
<string name="module_state_remove">Šalinti</string>
<string name="module_state_restore">Atkurti</string>
<string name="module_action_install_external">Įdiegti iš saugyklos</string>
<string name="update_available">Prieinamas naujinimas</string>
<string name="suspend_text_riru">Modulis išjungtas, nes %1$s yra įjungtas</string>
<string name="suspend_text_zygisk">Modulis išjungtas, nes %1$s nėra įjungtas</string>
<string name="zygisk_module_unloaded">Zygisk moduis neįkeltas dėl nesuderinamumo</string>
<string name="module_empty">Modulių nėra</string>
<string name="confirm_install">Įdiegti modulį %1$s?</string>
<string name="confirm_install_title">Įdiegimo patvirtinimas</string>
<!--Repo Fragment-->
<string name="update_available">Galimas atnaujinimas</string>
<string name="home_installed_version">Instaliuota</string>
<!--Log Fragment-->
<string name="menuSaveLog">Išsaugoti įvykių sąrašą</string>
<string name="menuClearLog">Išvalyti įvykių sąrašą</string>
<string name="logs_cleared">Įvykių sąrašas pašalintas</string>
<!--About Activity-->
<string name="app_changelog">Pakeitimų sąrašas</string>
<!--Toasts, Dialogs-->
<string name="repo_install_title">Instaliuoti %1$s %2$s(%3$d)</string>
<string name="download">Atsisiųsti</string>
<string name="reboot">Perkrauti</string>
<string name="magisk_update_title">Atsirado nauja Magisk versija!</string>
<string name="release_notes">Pakeitimai</string>
<string name="manager_download_install">Paspauskite, kad atsisiųstumėte ir instaliuotumėte</string>
<string name="update_channel">Magisk Atnaujinimai</string>
<string name="flashing">Instaliuojama</string>
<string name="direct_install">Tiesioginis instaliavimas (Rekomenduojamas)</string>
<string name="complete_uninstall">Pilnas pašalinimas</string>
<string name="restore_img">Atstatyti boot failą</string>
<string name="restore_img_msg">Atstatome…</string>
<string name="restore_done">Atstatymas įvykdytas!</string>
<string name="restore_fail">Gamyklinis atstatymo failas neegzistuoja!</string>
<string name="setup_fail">Pasiruošimas nesėkmingas</string>
<string name="env_fix_title">Reikalingas papildomas pasiruošimas</string>
<string name="setup_title">Papildomas pasiruošimas</string>
<string name="setup_msg">Paruošiama aplinka…</string>
<string name="download_file_error">Atsisiunčiant failą įvyko klaida</string>
<!--Settings Activity -->
<!--Settings-->
<string name="settings_dark_mode_title">Temos režimas</string>
<string name="settings_dark_mode_message">Pasirinkite režimą, kuris geriausiai atitinka jūsų stilių!</string>
<string name="settings_dark_mode_light">Visada šviesi</string>
<string name="settings_dark_mode_system">Sistemos</string>
<string name="settings_dark_mode_dark">Visada tamsi</string>
<string name="settings_download_path_title">Atsisiuntimo kelias</string>
<string name="settings_download_path_message">Failai bus išsaugoti %1$s</string>
<string name="settings_hide_app_title">Slėpti Magisk programėlę</string>
<string name="settings_hide_app_summary">Įdiegti įgaliotąją programėlę su atsitiktiniu paketo ID ir kitu pavadinimu</string>
<string name="settings_restore_app_title">Atkurti Magisk programėlę</string>
<string name="settings_restore_app_summary">Atkurti programėlę ir originalų APK</string>
<string name="language">Kalba</string>
<string name="system_default">(Sistemos)</string>
<string name="settings_check_update_title">Automatiškas atnaujinimų ieškojimas</string>
<string name="settings_check_update_summary">Automatiškai ieškoti Magisk ir Magisk Manager atnaujinimų</string>
<string name="settings_update_channel_title">Atnaujinimų tipai</string>
<string name="settings_update_stable">Stabilūs</string>
<string name="system_default">(Sistemos numatytoji)</string>
<string name="settings_check_update_title">Naujinimų tikrinimas</string>
<string name="settings_check_update_summary">Periodiškai fone tikrinti, ar nėra naujinimų</string>
<string name="settings_update_channel_title">Naujinimų kanalas</string>
<string name="settings_update_stable">Stabilus</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Pasirinktiniai</string>
<string name="settings_update_custom_msg">Įvesti pasirinktinį URL</string>
<string name="settings_hosts_title">Sistemos padejėjai</string>
<string name="settings_hosts_summary">Įgalinti sistemos padejėjus Adblock programėlėms</string>
<string name="settings_su_app_adb">Programėlėms ir ADB</string>
<string name="settings_su_app">Tik programėlėms</string>
<string name="settings_update_custom">Tinkintas</string>
<string name="settings_update_custom_msg">Įdėkite tinkinto kanalo URL</string>
<string name="settings_zygisk_summary">Vykdyti Magisk dalis zygote tarnyboje</string>
<string name="settings_denylist_title">Aktyvinti DenyList</string>
<string name="settings_denylist_summary">Visos procesų, esančių denylist, Magisk modifikacijos bus atkurtos</string>
<string name="settings_denylist_error">Šiai funkcijai reikia, kad būtų įjungta %1$s</string>
<string name="settings_denylist_config_title">Konfigūruoti DenyList</string>
<string name="settings_denylist_config_summary">Pasirinkite procesus, kuriuos norite įtraukti į denylist</string>
<string name="settings_hosts_title">Basisteminis hosts</string>
<string name="settings_hosts_summary">Basisteminis hosts palaiko reklamų blokatorių programėlėms</string>
<string name="settings_hosts_toast">Pridėtas besisteminio hosts modulis</string>
<string name="settings_app_name_hint">Naujas pavadinimas</string>
<string name="settings_app_name_helper">Programėlė bus perpakuota su šiuo pavadinimu</string>
<string name="settings_app_name_error">Netinkamas formatas</string>
<string name="settings_su_app_adb">Programėlės ir ADB</string>
<string name="settings_su_app">Tik programėlės</string>
<string name="settings_su_adb">Tik ADB</string>
<string name="settings_su_disable">Išjungta</string>
<string name="settings_su_request_10">10 sekundžių</string>
<string name="settings_su_request_15">15 sekundžių</string>
<string name="settings_su_request_20">20 sekundžių</string>
<string name="settings_su_request_30">30 sekundžių</string>
<string name="settings_su_request_45">45 sekundžių</string>
<string name="settings_su_request_45">45 sekundės</string>
<string name="settings_su_request_60">60 sekundžių</string>
<string name="superuser_access">Supervartotojo prieiga</string>
<string name="superuser_access">Prieigos lygis</string>
<string name="auto_response">Automatinis atsakymas</string>
<string name="request_timeout">Prašymo laikas baigiasi po</string>
<string name="superuser_notification">Supervartotojo pranešimai</string>
<string name="settings_su_reauth_title">Pakartotinai patvirtinti po atnaujinimo</string>
<string name="settings_su_reauth_summary">Pakartotinai patvirtinti supervartotojo leidimus po programėlės atnaujinimo</string>
<string name="request_timeout">Atsakymo laukimas</string>
<string name="superuser_notification">Supernaudotojo pranešimas</string>
<string name="settings_su_reauth_title">Pakartotinis autentifikavimas</string>
<string name="settings_su_reauth_summary">Iš naujo prašyti supernaudotojo teisių po programėlnaujinimo</string>
<string name="settings_su_tapjack_title">Bakstelėjimų perėmimo apsauga</string>
<string name="settings_su_tapjack_summary">Supernaudotojo užklausos langas bus neaktyvus, kol jis yra užstotas kito lango</string>
<string name="settings_su_biometric_title">Biometrinis autentifikavimas</string>
<string name="settings_su_biometric_summary">Naudoti biometrinį autentifikavimą supernaudotojo užklausų patvirtinimui</string>
<string name="no_biometric">Nepalaikomas įrenginys arba biometriniai nustatymai neįjungti</string>
<string name="settings_customization">Tinkinimas</string>
<string name="setting_add_shortcut_summary">Pridėti nuorodą į pagrindinį ekraną, jei po programėlės paslėpimo yra sunku atpažinti jos pavadinimą ir piktogramą</string>
<string name="settings_doh_title">DNS virš HTTPS</string>
<string name="settings_doh_description">Aktyvinti DoH (naudokite, jei kyla problemų jungiantis prie tinklo</string>
<string name="multiuser_mode">Daugialypio vartotojo režimas</string>
<string name="multiuser_mode">Daugelio naudotojų režimas</string>
<string name="settings_owner_only">Tik įrenginio savininkas</string>
<string name="settings_owner_manage">Įrenginio savininko valdomas</string>
<string name="settings_user_independent">Visų</string>
<string name="owner_only_summary">Tik įrenginio savininkas turi root prieigą</string>
<string name="owner_manage_summary">Tik įrenginio savinkas gali tvarkyti root prieigą ir gauti lenteles prašančias root prieigos</string>
<string name="user_independent_summary">Kiekvienas vartotojas turi savo atskiras root taisykles</string>
<string name="settings_owner_manage">Valdoma įrenginio savininko</string>
<string name="settings_user_independent">Naudotojų taisyklės</string>
<string name="owner_only_summary">Tik savininkas turi root prieigą</string>
<string name="owner_manage_summary">Tik savininkas gali tvarkyti root prieigą ir gauti užklausas</string>
<string name="user_independent_summary">Kiekvienas naudotojas turi savo atskiras root taisykles</string>
<string name="mount_namespace_mode">Root sesijos vardų srities režimas</string>
<string name="settings_ns_global">Globali vardų sritis</string>
<string name="settings_ns_requester">Paveldima vardų sritis</string>
<string name="settings_ns_isolate">Izoliuota vardų sritis</string>
<string name="global_summary">Visos root sesijos naudoja globalią vardų sritį</string>
<string name="requester_summary">Root sesijos paveldi jos išprašytojo/s vardų sritį</string>
<string name="isolate_summary">Kiekviena root sesija turi savo izoliuotą vardų sritį</string>
<string name="mount_namespace_mode">Pavadinimų erdvės režimas</string>
<string name="settings_ns_global">Bendra pavadinimų erdvė</string>
<string name="settings_ns_requester">Paveldima pavadinimų erdvė</string>
<string name="settings_ns_isolate">Izoliuota pavadinimų erdvė</string>
<string name="global_summary">Visos root sesijos naudos bendrą pavainimų erdvę</string>
<string name="requester_summary">Root sesijos paveldės prašytojų pavadinimų erdvę</string>
<string name="isolate_summary">Kiekviena root sesija turės savo izoliuotą pavadinimų erdvę</string>
<!--Superuser-->
<string name="su_request_title">Supervartotojo prašymas</string>
<string name="deny">Atmesti</string>
<string name="prompt">Klausti</string>
<string name="grant">Suteikti(a)</string>
<string name="su_warning">Supervartotojo prieiga suteikia pilną prieigą prie jūsų įrenginio\nAtmeskite jei neesate tikri dėl programėlės patikimumo!</string>
<string name="forever">Visados</string>
<string name="once">Vieną kartą</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 gavo supervartotojo teises</string>
<string name="su_deny_toast">%1$s negavo supervartotojo teisių</string>
<string name="su_snack_grant">%1$s supervartotojo teisių prašymas buvo atsakytas teigiamai</string>
<string name="su_snack_deny">%1$s supervartotojo teisių prašymas buvo atmestas</string>
<string name="su_snack_notif_on">Buvo įjungta %1$s pranešimai</string>
<string name="su_snack_notif_off">Buvo išjungta %1$s pranešimai</string>
<string name="su_snack_log_on">%1$s įvykių surašymas yra įgalintas</string>
<string name="su_snack_log_off">%1$s įvykių surašymas yra išjungtas</string>
<string name="su_revoke_title">Neleisti?</string>
<string name="su_revoke_msg">Neleisti %1$s naudotis supervartotojo teisėmis?</string>
<string name="toast">Išmesti</string>
<string name="none">Nėra</string>
<!--Notifications-->
<string name="update_channel">Magisk naujinimai</string>
<string name="progress_channel">Progreso pranešimai</string>
<string name="updated_channel">Naujinimas baigtas</string>
<string name="download_complete">Atsisiuntimas baigtas</string>
<string name="download_file_error">Klaida atsisiunčiant failą</string>
<string name="magisk_update_title">Prieinamas Magisk naujinimas!</string>
<string name="updated_title">Magisk atnaujintas</string>
<string name="updated_text">Bakstelėkite, kad atidarytumėte programėlę</string>
<!--Superuser logs-->
<string name="target_uid">Target UID: %1$d</string>
<!--Toasts, Dialogs-->
<string name="yes">Taip</string>
<string name="no">Ne</string>
<string name="repo_install_title">Įdiegimas %1$s %2$s(%3$d)</string>
<string name="download">Atsisiųsti</string>
<string name="reboot">Paleisti iš naujo</string>
<string name="release_notes">Laidos informacija</string>
<string name="flashing">Diegiama…</string>
<string name="done">Baigta!</string>
<string name="failure">Nepavyko!</string>
<string name="hide_app_title">Slepiama Magisk programėlė…</string>
<string name="open_link_failed_toast">Nerasta programėlių nuorodos atidarymui</string>
<string name="complete_uninstall">Visiškas pašalinimas</string>
<string name="restore_img">Atkurti vaizdą</string>
<string name="restore_img_msg">Atkuriama…</string>
<string name="restore_done">Atkūrimas baigtas!</string>
<string name="restore_fail">Nėra atsarginės kopijos!</string>
<string name="setup_fail">Sąranka nepavyko</string>
<string name="env_fix_title">Reikalinga išplėstinė sąranka</string>
<string name="env_fix_msg">Jūsų įrenginiui reikalinga išplėstinė sąranka, kad Magisk veiktų tinkamai. Norite tęsti ir įrenginį paleisti iš naujo?</string>
<string name="env_full_fix_msg">Jūsų įrenginiui reikia iš naujo įdiegti Magisk, kad jis veiktų tinkamai. Iš naujo įdiekite Magisk su programėle, atkūrimo režimas negali gauti teisingos įrenginio informacijos.</string>
<string name="setup_msg">Vykdoma Running aplinkos sąranka…</string>
<string name="authenticate">Autentifikavimas</string>
<string name="unsupport_magisk_title">Nepalaikoma Magisk versija</string>
<string name="unsupport_magisk_msg">Ši programėlės versija nepalaiko Magisk versijų, žemesnių už %1$s.\n\nProgramėlė veiks taip, lyg Magisk yra neįdiegtas. Kuo greičiau atnaujinkite Magisk.</string>
<string name="unsupport_general_title">Nenormali būsena</string>
<string name="unsupport_system_app_msg">Šios programėlės vykdymas kaip sistemos programėlės yra nepalaikomas. Nustatykite ją atgal į naudotojo programėlę.</string>
<string name="unsupport_other_su_msg">Aptiktas dvejetainis failas \"su\" ne iš Magisk. Pašalinkite pašalinį root teisių tiekėją ir/arba iš naujo įdiekite Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk yra įdiegtas išorinėje saugykloje. Perkelkite programėlę į vidinę saugyklą.</string>
<string name="unsupport_nonroot_stub_msg">Paslėpta Magisk programėlė negali tęsti darbo, nes root teisės buvo prarastos. Atkurkite originalų APk.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Suteikti prieigą prie saugyklos</string>
<string name="post_notifications_denied">Suteikti prieigą prie pranešimų</string>
<string name="install_unknown_denied">Suteikti prieigą prie įdiegimo iš nežinomų šaltinių</string>
<string name="add_shortcut_title">Pridėti nuorodą į pagrindinį ekraną</string>
<string name="add_shortcut_msg">Po šios programėlės paslėpimo jos pavadinimas, piktograma gali būti sunkiai atpažįstamos. Norite pridėti nuorodą į pagrindinį ekraną?</string>
<string name="app_not_found">Nerasta programėlė, galinti atlikti šį veiksmą</string>
<string name="reboot_apply_change">Paleiskite iš naujo, kad pritaikytumėte pakeitimus</string>
<string name="restore_app_confirmation">Šis veiksmas atkurs paslėptą programėlę į originalią būseną. Tikrai norite tai padaryti?</string>
</resources>

View File

@@ -22,6 +22,7 @@
<string name="home_notice_content">Pobieraj Magisk tylko z oficjalnej strony GitHub. Pliki z nieznanych źródeł mogą być szkodliwe!</string>
<string name="home_support_title">Wesprzyj nas</string>
<string name="home_follow_title">Śledź nas</string>
<string name="home_item_source">Źródło</string>
<string name="home_support_content">Magisk jest i zawsze będzie darmowy i otwarty. Niemniej możesz nam pokazać, że Ci zależy, wysyłając drobną darowiznę.</string>
<string name="home_installed_version">Zainstalowany</string>
@@ -90,7 +91,7 @@
<!--SafetyNet-->
<!-- MagiskHide -->
<!--MagiskHide -->
<string name="show_system_app">Pokaż aplikacje systemowe</string>
<string name="show_os_app">Pokaż aplikacje OS</string>
<string name="hide_filter_hint">Filtruj według nazwy</string>
@@ -111,6 +112,9 @@
<string name="suspend_text_riru">Moduł uśpiony ponieważ %1$s jest włączony</string>
<string name="suspend_text_zygisk">Moduł uśpiony ponieważ %1$s jest wyłączony</string>
<string name="zygisk_module_unloaded">Moduł Zygisk nie załadowany ze względu na niekompatybilność</string>
<string name="module_empty">Żaden moduł nie jest zainstalowany</string>
<string name="confirm_install">Zainstaloać moduł %1$s?</string>
<string name="confirm_install_title">Potwierdzenie instalacji</string>
<!--Settings -->
<string name="settings_dark_mode_title">Tryb motywu</string>
@@ -217,6 +221,7 @@
<string name="setup_fail">Konfiguracja nieudana</string>
<string name="env_fix_title">Wymaga dodatkowej konfiguracji</string>
<string name="env_fix_msg">Twoje urządzenie wymaga dodatkowej konfiguracji aby Magisk działał właściwie. Czy chcesz kontynuować i uruchomić ponownie?</string>
<string name="env_full_fix_msg">Twoje urządzenie musi wgrać ponowanie Magisk, aby działać poprawnie. Proszę przeinstaluj Magisk w aplikacji, tryb Recovery nie potrafi poprawnie rozpoznać urządzenia.</string>
<string name="setup_msg">Uruchamianie środowiska konfiguracji…</string>
<string name="authenticate">Uwierzytelnianie</string>
<string name="unsupport_magisk_title">Nieobsługiwana wersja Magisk</string>
@@ -228,6 +233,7 @@
<string name="unsupport_nonroot_stub_msg">Ta aplikacja nie może dłużej działać w trybie ukrycia jako że root został utracony. Proszę przywrócić ją do oryginalnego stanu.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Zezwól na dostęp do pamięci wewnętrznej, aby włączyć tę funkcję.</string>
<string name="post_notifications_denied">Zezwól na otrzymywanie powiadomień, aby aktywować tą funkcję</string>
<string name="install_unknown_denied">Zezwól na "Instaluj z nieznanych źródeł" by włączyć tą funkcję</string>
<string name="add_shortcut_title">Utwórz skrót na ekranie głównym</string>
<string name="add_shortcut_msg">Po ukryciu tej aplikacji, jej nazwa i ikona może być trudna do rozpoznania. Czy chcesz dodać ładny skrót na ekranie głównym?</string>

View File

@@ -45,7 +45,7 @@
<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="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)</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="flash_screen_title">Instalação</string>
@@ -86,6 +86,9 @@
<string name="logs_cleared">Registro 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>
<string name="selinux_context">Contexto SELinux: %s</string>
<string name="supp_group">Grupo suplementar: %s</string>
<!--MagiskHide-->
<string name="show_system_app">Mostrar apps do Sistema</string>
@@ -109,6 +112,8 @@
<string name="suspend_text_zygisk">Módulo suspenso porque %1$s não está ativo</string>
<string name="zygisk_module_unloaded">Modulo Zygisk não carregado devido a incompatibilidade</string>
<string name="module_empty">Nenhum módulo instalado</string>
<string name="confirm_install">Instalar módulo %1$s?</string>
<string name="confirm_install_title">Confirmação de Instalação</string>
<!--Settings-->
<string name="settings_dark_mode_title">Modo de tema</string>
@@ -213,6 +218,7 @@
<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. Reinstale o Magisk no aplicativo, o modo de recuperação não pode obter as devidas informações do dispositivo.</string>
<string name="setup_msg">Executando a configuração do ambiente…</string>
<string name="authenticate">Autenticar</string>
<string name="unsupport_magisk_title">Versão do Magisk não suportada</string>

View File

@@ -45,7 +45,7 @@
<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="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)</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="flash_screen_title">Instalação</string>
@@ -86,6 +86,9 @@
<string name="logs_cleared">Registro 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>
<string name="selinux_context">Contexto SELinux: %s</string>
<string name="supp_group">Grupo suplementar: %s</string>
<!--MagiskHide-->
<string name="show_system_app">Mostrar apps do Sistema</string>
@@ -109,6 +112,8 @@
<string name="suspend_text_zygisk">Módulo suspenso porque %1$s não está ativo</string>
<string name="zygisk_module_unloaded">Modulo Zygisk não carregado devido a incompatibilidade</string>
<string name="module_empty">Nenhum módulo instalado</string>
<string name="confirm_install">Instalar módulo %1$s?</string>
<string name="confirm_install_title">Confirmação de Instalação</string>
<!--Settings-->
<string name="settings_dark_mode_title">Modo de tema</string>
@@ -213,6 +218,7 @@
<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. Reinstale o Magisk no aplicativo, o modo de recuperação não pode obter as devidas informações do dispositivo.</string>
<string name="setup_msg">Executando a configuração do ambiente…</string>
<string name="authenticate">Autenticar</string>
<string name="unsupport_magisk_title">Versão do Magisk não suportada</string>

View File

@@ -113,6 +113,8 @@
<string name="suspend_text_zygisk">Modul suspendat deoarece %1$s nu este activat</string>
<string name="zygisk_module_unloaded">Modulul Zygisk nu a fost încărcat din cauza incompatibilității</string>
<string name="module_empty">Niciun modul instalat</string>
<string name="confirm_install">Instalezi modulul %1$s?</string>
<string name="confirm_install_title">Confirmare pentru instalare</string>
<!--Settings-->
<string name="settings_dark_mode_title">Mod pentru temă</string>
@@ -219,6 +221,7 @@
<string name="setup_fail">Configurare eșuată</string>
<string name="env_fix_title">Necesită configurare suplimentară</string>
<string name="env_fix_msg">Dispozitivul are nevoie de configurare suplimentară pentru ca Magisk să funcționeze corect. Vrei să continui și să repornești?</string>
<string name="env_full_fix_msg">Dispozitivul are nevoie de rescrierea în memoria flash a Magisk pentru a funcționa corect. Te rugăm să reinstalezi Magisk în cadrul aplicației, modul de recuperare nu poate obține informații corecte despre dispozitiv.</string>
<string name="setup_msg">Rulează configurarea mediului…</string>
<string name="authenticate">Autentificare</string>
<string name="unsupport_magisk_title">Versiune Magisk nesuportată</string>
@@ -230,6 +233,7 @@
<string name="unsupport_nonroot_stub_msg">Aplicația Magisk ascunsă nu poate continua să funcționeze deoarece rootul a fost pierdut. Te rugăm să restaurezi APK-ul original.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Acordă permisiunea de stocare pentru a activa această funcționalitate</string>
<string name="post_notifications_denied">Acordă permisiunea de notificări pentru a activa această funcționalitate</string>
<string name="install_unknown_denied">Permite „instalarea de aplicații necunoscute” pentru a activa această funcționalitate</string>
<string name="add_shortcut_title">Adaugă comandă rapidă pe ecranul de pornire</string>
<string name="add_shortcut_msg">După ascunderea acestei aplicații, numele și pictograma acesteia ar putea deveni dificil de recunoscut. Vrei să adaugi o comandă rapidă frumoasă pe ecranul de pornire?</string>

View File

@@ -34,8 +34,8 @@
<!--Install-->
<string name="keep_force_encryption">Не отключать шифрование /data</string>
<string name="keep_dm_verity">Не отключать AVB 2.0/dm-verity</string>
<string name="patch_vbmeta">Патчить vbmeta в boot образе</string>
<string name="recovery_mode">Патчить recovery образ вместо boot</string>
<string name="patch_vbmeta">Патчить vbmeta в boot-образе</string>
<string name="recovery_mode">Патчить образ recovery вместо boot</string>
<string name="install_options_title">Опции</string>
<string name="install_method_title">Способ</string>
<string name="install_next">Далее</string>
@@ -45,7 +45,7 @@
<string name="install_inactive_slot">Установка во второй слот (после OTA-обновления)</string>
<string name="install_inactive_slot_msg">Ваше устройство будет принудительно перезагружено в неактивный (противоположный) слот!\nИспользуйте эту опцию только при интеграции Magisk после OTA-обновления!\nПродолжить?</string>
<string name="setup_title">Расширенная установка</string>
<string name="select_patch_file">Пропатчить boot образ</string>
<string name="select_patch_file">Пропатчить boot-образ</string>
<string name="patch_file_msg">Выберите файл образа (*.img) или архив ODIN (*.tar)</string>
<string name="reboot_delay_toast">Перезагрузка через 5 секунд…</string>
<string name="flash_screen_title">Установка</string>
@@ -113,6 +113,8 @@
<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>

View File

@@ -46,7 +46,7 @@
<string name="install_inactive_slot_msg">Vaše zariadenie bude po reštarte PRINÚTENÉ nabootovať do aktuálne neaktívneho slotu!\nTúto voľbu použite iba po skončení OTA.\nPokračovať?</string>
<string name="setup_title">Ďalšie nastavenia</string>
<string name="select_patch_file">Vybrať a zaplátať súbor</string>
<string name="patch_file_msg">Vyberte raw súbor (*.img) alebo tar súbor ODIN (*.tar)</string>
<string name="patch_file_msg">Vyberte raw súbor (*.img) alebo tar súbor ODIN (*.tar) alebo payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Reštart o 5 sekúnd…</string>
<string name="flash_screen_title">Inštalácia</string>
@@ -87,7 +87,10 @@
<string name="menuClearLog">Odstrániť záznam</string>
<string name="logs_cleared">Záznam úspešne odstránený</string>
<string name="pid">PID:%1$d</string>
<string name="target_uid">Cieľový UID: %1$d</string>
<string name="target_uid">Cieľové UID: %1$d</string>
<string name="target_pid">Pripojiť ns cieľový PID: %s</string>
<string name="selinux_context">SELinux kontext: %s</string>
<string name="supp_group">Doplnková skupina: %s</string>
<!--SafetyNet-->

View File

@@ -46,7 +46,7 @@
<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ë ODIN tar skader (*.tar)</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="flash_screen_title">Instalimi</string>
@@ -88,6 +88,9 @@
<string name="logs_cleared">Regjistrat u pastuan 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 të synuar ns: %s</string>
<string name="selinux_context">Konteksti SELinux: %s</string>
<string name="supp_group">Grupi suplementar: %s</string>
<!--SafetyNet-->

View File

@@ -2,86 +2,89 @@
<!--Sections-->
<string name="modules">Modüller</string>
<string name="superuser">Yetkili Kullanıcı</string>
<string name="logs">Günlük</string>
<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="section_home">Ana Ekran</string>
<string name="section_home">Ana Sayfa</string>
<string name="section_theme">Temalar</string>
<string name="denylist">Reddetme Listesi</string>
<!--Home-->
<string name="no_connection">Bağlantı yok</string>
<string name="app_changelog">Değişiklikler</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">Bulunmuyor</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 SADECE resmi github sayfasından indirin. Başka kaynaklardaki dosyalar kötücül olabilir!</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">Bizi Destekleyin</string>
<string name="home_follow_title">Bizi Takip Edin</string>
<string name="home_item_source">Kaynak</string>
<string name="home_support_content">Magisk özgür ve açık kaynaklıdır ve her zaman da öyle kalacaktır. Ancak küçük bir bağış göndererek bize önem verdiğinizi gösterebilirsiniz.</string>
<string name="home_installed_version">Yüklü</string>
<string name="home_latest_version">Güncel</string>
<string name="home_support_content">Magisk ücretsiz ve açık kaynaktır ve her zaman öyle kalacaktır. Ancak bağış yaparak bize değer verdiğinizi gösterebilirsiniz.</string>
<string name="home_installed_version">Yüklendi</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="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!\nRoot erişimi kaldırılacak!\nVerileriniz şifrelenmemişse potansiyel olarak şifrelenecek!</string>
<string name="uninstall_magisk_title">Magisk\'i Kaldırın</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>
<!--Install-->
<string name="keep_force_encryption">Şifrelemeye zorlamayı sürdür</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity\'yi koru</string>
<string name="keep_force_encryption">Zorla şifrelemeyi koru</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity\'yi koruyun</string>
<string name="patch_vbmeta">Önyükleme görüntüsünde vbmeta yaması</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">İleri</string>
<string name="install_start">Hadi başlayalım</string>
<string name="manager_download_install">İndirmek ve yüklemek için tıklayınız.</string>
<string name="direct_install">Doğrudan kurulum (Önerilen)</string>
<string name="install_inactive_slot">Aktif olmayan yuvaya yükle (OTA\'dan sonra)</string>
<string name="install_inactive_slot_msg">Cihazınız yeniden başlatmanın ardından mevcut etkin olmayan yuva üzerinde yeniden başlatmaya ZORLANACAK!\nBu seçeneği yalnızca OTA (güncelleme) bittikten sonra kullanın.\nDevam edilsin mi?</string>
<string name="install_next">Sonraki</string>
<string name="install_start">Hadi gidelim</string>
<string name="manager_download_install">İndirmek ve yüklemek için basın</string>
<string name="direct_install">Doğrudan Kurulum (Önerilir)</string>
<string name="install_inactive_slot">Etkin Olmayan Yuvaya Kur (OTA\'dan Sonra)</string>
<string name="install_inactive_slot_msg">Yeniden başlatmanın ardından cihazınız mevcut etkin olmayan yuvaya önyükleme yapmaya ZORLANACAK!\nBu seçeneği yalnızca OTA tamamlandıktan sonra kullanın.\nDevam edilsin mi?</string>
<string name="setup_title">Ek Kurulum</string>
<string name="select_patch_file">Dosya Seçin ve Yamalayın</string>
<string name="patch_file_msg">Bir raw imaj (*.img) veya ODIN tar dosyası (*.tar) seçin</string>
<string name="reboot_delay_toast">5 saniye içinde yeniden başlatılacak</string>
<string name="flash_screen_title">Kurulum</string>
<string name="select_patch_file">Bir Dosya Seçin ve Yamalayın</string>
<string name="patch_file_msg">Bir ham görüntü (*.img) veya bir ODIN tar dosyası (*.tar) 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>
<!--Superuser-->
<string name="su_request_title">Yetkili Kullanıcı İsteği</string>
<string name="touch_filtered_warning">Çünkü bir uygulama yetkili kullanıcı isteğini engelliyor, Magisk sizin yanıtınızı doğrulayamaz</string>
<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="deny">Reddet</string>
<string name="prompt">Sor</string>
<string name="grant">İzin ver</string>
<string name="su_warning">Cihazınıza tam erişim verir.\nEmin değilseniz reddedin!</string>
<string name="forever">Sonsuza kadar</string>
<string name="once">Bir kereliğine</string>
<string name="prompt">Hemen</string>
<string name="grant">İzin</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 kere</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 için yetkili kullanıcı hakları verildi</string>
<string name="su_deny_toast">%1$s için yetkili kullanıcı hakları reddedildi</string>
<string name="su_snack_grant">%1$s için yetkili kullanıcı hakları verildi</string>
<string name="su_snack_deny">%1$s için yetkili kullanıcı hakları reddedildi</string>
<string name="su_snack_notif_on">%1$s için bildirimler etkin</string>
<string name="su_snack_notif_off">%1$s için bildirimler devre dışı</string>
<string name="su_snack_log_on">%1$s için günlük etkin</string>
<string name="su_snack_log_off">%1$s için günlük devre dışı</string>
<string name="su_revoke_title">Geri alınsın mı?</string>
<string name="su_revoke_msg">%1$s hakları geri alınsın mı?</string>
<string name="su_allow_toast">%1$s Süper Kullanıcı hakları verildi</string>
<string name="su_deny_toast">%1$s Süper Kullanıcı hakları reddedildi</string>
<string name="su_snack_grant">%1$s Süper Kullanıcı hakları verildi</string>
<string name="su_snack_deny">%1$s 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 günlüğü etkinleştirildi</string>
<string name="su_snack_log_off">%1$s günlüğü devre dışı bırakıldı</string>
<string name="su_revoke_title">İptal et?</string>
<string name="su_revoke_msg">%1$s Süper Kullanıcı haklarını iptal etmeyi onaylayın</string>
<string name="toast">Tost</string>
<string name="none">Hiçbiri</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 yetkili kullanıcı izni istemedi.</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 boş, daha fazla Yetkili Kullanıcı İzni isteyen uygulama kullanmayı deneyin</string>
<string name="log_data_magisk_none">Magisk günlükleri boş, bu biraz garip</string>
<string name="log_data_none">Günlük kullanmıyorsunuz, kök 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üğü temizle</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>
@@ -89,132 +92,153 @@
<!--SafetyNet-->
<!--MagiskHide-->
<string name="show_system_app">Sistem uyg. göster</string>
<string name="show_os_app">İşletim Sistemi uyg. 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">İşletim sistemi 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">(Hiçbir bilgi sağlanmadı)</string>
<string name="reboot_userspace">Yazılımsal yeniden başlatma</string>
<string name="reboot_recovery">Kurtarma moduna yeniden başlat</string>
<string name="reboot_bootloader">Bootloader moduna yeniden başlat</string>
<string name="reboot_download">İndirme moduna yeniden başlat</string>
<string name="reboot_edl">EDL moduna yeniden başlat</string>
<string name="module_version_author">%1$s - %2$s</string>
<string name="no_info_provided">(Bilgi verilmedi)</string>
<string name="reboot_userspace">Yumuşak yeniden başlatma</string>
<string name="reboot_recovery">Kurtarma için Yeniden Başlatın</string>
<string name="reboot_bootloader">Bootloader için Yeniden Başlatın</string>
<string name="reboot_download">İndirmek için Yeniden Başlatın</string>
<string name="reboot_edl">EDL için Yeniden Başlatın</string>
<string name="module_version_author">%1$s / %2$s</string>
<string name="module_state_remove">Kaldır</string>
<string name="module_state_restore">Geri yükle</string>
<string name="module_action_install_external">Dahili depolamadan yükle</string>
<string name="update_available">Güncelleme mevcut</string>
<string name="module_action_install_external">Depolamadan yükle</string>
<string name="update_available">Güncelleme Mevcut</string>
<string name="suspend_text_riru">%1$s etkinleştirildiği için modül askıya alındı</string>
<string name="suspend_text_zygisk">%1$s etkin olmadığı için modül askıya alındı</string>
<string name="zygisk_module_unloaded">Uyumsuzluk nedeniyle Zygisk modülü 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>
<!--Settings-->
<string name="settings_dark_mode_title">Tema Modu</string>
<string name="settings_dark_mode_message">Stilinize en iyi uyan modu seçin!</string>
<string name="settings_dark_mode_light">Her Zaman Aydınlık</string>
<string name="settings_dark_mode_message">Tarzınıza en uygun modu seçin!</string>
<string name="settings_dark_mode_light">Daima Açık</string>
<string name="settings_dark_mode_system">Sistemi Takip Et</string>
<string name="settings_dark_mode_dark">Her Zaman Karanlık</string>
<string name="settings_download_path_title">İndirme dizini</string>
<string name="settings_dark_mode_dark">Daima Koyu</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 paket kimliğine ve isme sabip bir vekil uygulama yükle</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 ve orijinal APK\'ye geri döndür</string>
<string name="settings_hide_app_title">Magisk uygulamasını gizleyin</string>
<string name="settings_hide_app_summary">Rastgele bir paket kimliğine ve özel uygulama etiketine sahip bir proxy uygulaması yükleyin</string>
<string name="settings_restore_app_title">Magisk uygulamasını geri yükleyin</string>
<string name="settings_restore_app_summary">Uygulamayı gösterin ve orijinal APK\'yı 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 Denetle</string>
<string name="settings_check_update_summary">Periyodik olarak arka planda güncellemeleri denetle</string>
<string name="settings_check_update_title">Güncellemeleri Kontrol Et</string>
<string name="settings_check_update_summary">Arka planda güncellemeleri periyodik olarak kontrol edin</string>
<string name="settings_update_channel_title">Güncelleme Kanalı</string>
<string name="settings_update_stable">Stabil</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Özel Kanal</string>
<string name="settings_update_custom_msg">Özel URL ekleyin</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 isim</string>
<string name="settings_app_name_helper">Uygulama bu isimle yeniden paketlenecek</string>
<string name="settings_update_custom">Özel</string>
<string name="settings_update_custom_msg">Özel bir kanal URL\'si ekleyin</string>
<string name="settings_zygisk_summary">Zygisk arka plan programında Magisk\'in bazı bölümlerini çalıştırın</string>
<string name="settings_denylist_title">Reddetme Listesini Zorla</string>
<string name="settings_denylist_summary">Reddetme listesindeki işlemlerde tüm Magisk değişiklikleri geri alınır</string>
<string name="settings_denylist_error">Bu özelliğin etkinleştirilmesi için %1$s gerekir</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 host</string>
<string name="settings_hosts_summary">Reklam engelleme uygulamaları için sistemsiz host desteği</string>
<string name="settings_hosts_toast">Sistemsiz host modülü eklendi</string>
<string name="settings_app_name_hint">Yeni ad</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_app">Yalnızca uygulamalar</string>
<string name="settings_su_adb">Yalnızca 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="superuser_access">Yetkili 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">Yetkili Kullanıcı Bildirimi</string>
<string name="settings_su_reauth_title">Yükseltmeden sonra yeniden kimlik doğrula</string>
<string name="settings_su_reauth_summary">Uygulama yükseltmeleri sonrasında yetkili kullanıcı izinlerini yeniden doğrula</string>
<string name="settings_su_tapjack_title">Tapjacking Korumasını Aktifleştir</string>
<string name="settings_su_tapjack_summary">Yetkili Kullanıcı izin penceresi başka bir pencere veya arayüz tarafından engellenirken verilen yanıtlara tepki vermeyecektir</string>
<string name="settings_su_biometric_title">Biyometrik Kimlik Doğrulamayı Etkinleştir</string>
<string name="settings_su_biometric_summary">Superuser isteklerine izin vermek için biyometrik kimlik doğrulamayı kullanabilirsiniz</string>
<string name="no_biometric">Desteklenmeyen cihaz veya biyometrik ayar etkinleştirilmemiş</string>
<string name="settings_customization">Özelleştirme</string>
<string name="setting_add_shortcut_summary">Uygulamayı gizledikten sonra ismini ve simgesini tanımakta zorlanırsanız ana ekrana güzel bir kısayol ekleyebilirsiniz</string>
<string name="superuser_access">Süper Kullanıcı Erişimi</string>
<string name="auto_response">Otomatik Cevap</string>
<string name="request_timeout">İstek Zaman Aşımına Uğradı</string>
<string name="superuser_notification">Süper Kullanıcı Bildirimi</string>
<string name="settings_su_reauth_title">Yükseltmeden sonra yeniden kimlik doğrulaması yapın</string>
<string name="settings_su_reauth_summary">Uygulamaları yükselttikten sonra Süper Kullanıcı izinlerini tekrar isteyin</string>
<string name="settings_su_tapjack_title">Sahte Ekran Koruması</string>
<string name="settings_su_tapjack_summary">Süper Kullanıcı bilgi istemi iletişim kutusu, herhangi bir başka pencere veya yer paylaşımı tarafından engellendiğinde girişe yanıt vermeyecektir.</string>
<string name="settings_su_biometric_title">Biyometrik Kimlik Doğrulama</string>
<string name="settings_su_biometric_summary">Süper Kullanıcı isteklerine izin vermek için biyometrik kimlik doğrulamayı kullanın</string>
<string name="no_biometric">Desteklenmeyen cihaz veya hiçbir biyometrik ayar etkin değil</string>
<string name="settings_customization">Özelleştir</string>
<string name="setting_add_shortcut_summary">Uygulamayı gizledikten sonra adın ve simgenin tanınmasının zor olması durumunda 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 çözmeye çalışır</string>
<string name="settings_doh_description">Bazı ülkelerde DNS zehirlenmesine geçici çözüm</string>
<string name="multiuser_mode">Çoklu Kullanıcı Modu</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 Tarafından Yönetilen</string>
<string name="settings_owner_manage">Cihaz Sahibi Tarafından Yönetildi</string>
<string name="settings_user_independent">Kullanıcıdan Bağımsız</string>
<string name="owner_only_summary">Yalnızca root erişimi olan kullanıcı</string>
<string name="owner_manage_summary">Yalnızca cihaz sahibi root erişimini yönetebilir ve izin isteklerini alabilir</string>
<string name="user_independent_summary">Her kullanıcının kendine ait root erişim kuralları olur</string>
<string name="mount_namespace_mode">Ad Alanı Modunu Bağla</string>
<string name="owner_only_summary">Yalnızca sahibinin kök erişimi vardır</string>
<string name="owner_manage_summary">Yalnızca sahip, kök erişimini yönetebilir ve istek istemleri alabilir</string>
<string name="user_independent_summary">Her kullanıcının kendi ayrı kök kuralları vardır</string>
<string name="settings_ns_global">Global Ad Alanı</string>
<string name="settings_ns_requester">Devralınan Ad Alanı</string>
<string name="settings_ns_isolate">İzole Edilmiş Ad Alanı</string>
<string name="global_summary">Tüm root oturumları global bağlama ad alanını kullanır</string>
<string name="requester_summary">Root oturumları, istekte bulunanın ad alanını devralır</string>
<string name="isolate_summary">Her root oturumunun kendine ait bir izole ad alanı olur</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_requester">Ad Alanını Devral</string>
<string name="settings_ns_isolate">İzole Ad Alanı</string>
<string name="global_summary">Tüm kök oturumları, global bağlama ad alanını kullanır</string>
<string name="requester_summary">Kök oturumları, istek sahibinin ad alanını devralır</string>
<string name="isolate_summary">Her kök oturumun 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="download_complete">İndirme tamamlandı</string>
<string name="download_file_error">Dosya indirme hatası</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="updated_text">Uygulamayı açmak için dokunun</string>
<!--Toasts, Dialogs-->
<string name="yes">Evet</string>
<string name="no">Hayır</string>
<string name="repo_install_title">%1$s %2$s(%3$d) yükle</string>
<string name="download">İndir</string>
<string name="reboot">Yeniden Başlat</string>
<string name="reboot">Yeniden başlat</string>
<string name="release_notes">Sürüm notları</string>
<string name="flashing">Yükleniyor…</string>
<string name="flashing">Flaşlanıyor…</string>
<string name="done">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ı açabilecek bir uygulama bulunamadı</string>
<string name="complete_uninstall">Tamamen Kaldır</string>
<string name="restore_img">İmajları Geri Yükle</string>
<string name="restore_img_msg">Geri Yükleniyor…</string>
<string name="hide_app_title">Magisk uygulaması gizleniyor</string>
<string name="open_link_failed_toast">Bağlantıyı açacak uygulama bulunamadı</string>
<string name="complete_uninstall">Kaldırmayı Tamamla</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_done">Geri yükleme tamamlandı!</string>
<string name="restore_fail">Stock yedeği yok!</string>
<string name="setup_fail">Kurulum başarısız</string>
<string name="env_fix_title">Ek Kurulum Gerekli</string>
<string name="env_fix_msg">Cihazınızın Magisk\'i çalıştırması için ek bir kuruluma ihtiyacı var. Ek kuruluma devam etmek ve yeniden başlatmak istiyor musunuz?</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 Kurulum Gerektirir</string>
<string name="env_fix_msg">Magisk\'in düzgün çalışması için cihazınızın ek kuruluma ihtiyacı var. Devam etmek ve yeniden başlatmak istiyor musunuz?</string>
<string name="env_full_fix_msg">Cihazınızın düzgün çalışması için Magisk\'in yeniden yüklenmeye ihtiyacı var. Lütfen Magisk\'i uygulama içinde yeniden yükleyin, kurtarma modu doğru cihaz bilgilerini alamıyor.</string>
<string name="setup_msg">Ortam kurulumu çalıştırılıyor…</string>
<string name="authenticate">Kimlik Doğrulaması</string>
<string name="authenticate">Kimlik Doğrula</string>
<string name="unsupport_magisk_title">Desteklenmeyen Magisk Sürümü</string>
<string name="unsupport_magisk_msg">Uygulamanın bu sürümü %1$s\'den daha düşük Magisk sürümünü desteklememektedir.\n\nUygulama Magisk yüklü değilmiş gibi davranacaktır. Lütfen en kısa sürede Magisk\'i güncelleyiniz.</string>
<string name="unsupport_magisk_msg">Uygulamanın bu sürümü, %1$s\'den daha düşük Magisk sürümlerini desteklemiyor.\n\nUygulama, Magisk kurulu değilmiş gibi davranacak, lütfen Magisk\'i mümkün olan en kısa sürede yükseltin.</string>
<string name="unsupport_general_title">Anormal Durum</string>
<string name="unsupport_system_app_msg">Uygulamayı sistem uygulaması olarak çalıştırmak desteklenmemektedir. Lütfen uygulamayı tekrar kullanıcı uygulaması haline getiriniz.</string>
<string name="unsupport_other_su_msg">Magisk\'e ait olmayan bir \"su\" komutu algılandı. Lütfen diğer desteklenmeyen \"su\" komutlarını kaldırın.</string>
<string name="unsupport_external_storage_msg">Magisk harici bir depolamaya yüklendi. Lütfen uygulamayı dahili depolamaya taşıyınız.</string>
<string name="unsupport_nonroot_stub_msg">Root yokken uygulama gizli modda çalışmaya devam edemez. Lütfen orijinal APK\'ye geri döndürünüz.</string>
<string name="unsupport_system_app_msg">Bu uygulamayı bir sistem uygulaması olarak çalıştırmak desteklenmiyor. Lütfen uygulamayı bir kullanıcı uygulamasına geri döndürün.</string>
<string name="unsupport_other_su_msg">Magisk\'ten olmayan bir \"su\" ikili dosyası algılandı. Lütfen rakip kök çözümlerini kaldırın ve/veya Magisk\'i yeniden yükleyin.</string>
<string name="unsupport_external_storage_msg">Magisk, harici depolama birimine kurulur. Lütfen uygulamayı dahili depolamaya taşıyın.</string>
<string name="unsupport_nonroot_stub_msg">Kök kaybolduğu için gizli Magisk uygulaması çalışmaya devam edemiyor. Lütfen orijinal APK\'yı geri yükleyin.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Bu işlevi aktif etmek için depolama izni vermelisiniz</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"ye izin verin</string>
<string name="add_shortcut_title">Ana ekrana kısayol ekle</string>
<string name="add_shortcut_msg">Uygulamayı gizledikten sonra ismini ve simgesini tanımak zorlaşabilir. Ana ekrana güzel bir kısayol eklemek ister misiniz?</string>
<string name="app_not_found">Bu lemi yapabilecek bir uygulama bulunamadı</string>
<string name="add_shortcut_msg">Bu uygulamayı gizledikten sonra adını ve simgesini tanımak zorlaşabilir. Ana ekrana hoş bir kısayol eklemek ister misiniz?</string>
<string name="app_not_found">Bu eylemi gerçekleştirecek 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 musun?</string>
</resources>

View File

@@ -46,7 +46,7 @@
<string name="install_inactive_slot_msg">将在重启后强制切换到另一个槽位!注意只能在 OTA 更新完成后的重启之前使用。</string>
<string name="setup_title">修复安装</string>
<string name="select_patch_file">选择并修补一个文件</string>
<string name="patch_file_msg">选择一个原始映像文件(*.img或一个 Odin 包(*.tar</string>
<string name="patch_file_msg">选择一个原始映像文件(*.imgOdin 包(*.tar或 payload.bin*.bin</string>
<string name="reboot_delay_toast">设备将在 5 秒后重启</string>
<string name="flash_screen_title">安装</string>
@@ -88,6 +88,9 @@
<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>
<!--SafetyNet-->

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