Compare commits

...

884 Commits

Author SHA1 Message Date
topjohnwu
9476e7282d More borrowing, less copying 2025-08-08 21:06:41 -07:00
topjohnwu
251c3c3e0e Remove old ffi data structure 2025-08-08 21:06:41 -07:00
topjohnwu
cd0eca20b0 Migrate connect.cpp to Rust 2025-08-08 21:06:41 -07:00
topjohnwu
6839cb9ab2 Keep /system/xbin/su on emulators 2025-08-08 21:06:41 -07:00
topjohnwu
d11a3397d8 Reduce verbose logging in Zygisk 2025-08-08 21:06:41 -07:00
topjohnwu
975120d6a6 Release Magisk v30.2
[skip ci]
2025-08-06 03:32:32 -07:00
topjohnwu
e489b3b6dd Migrate load_modules to Rust 2025-08-05 11:24:55 -07:00
topjohnwu
589a270b8d Migrate disable/remove modules to Rust 2025-08-05 11:24:55 -07:00
topjohnwu
7961be5cfa Migrate prepare_modules to Rust 2025-08-05 11:24:55 -07:00
topjohnwu
959430e030 Fix systemless hosts installation 2025-08-05 09:44:51 -07:00
topjohnwu
2923c8ccd1 Add module upgrade test 2025-08-05 09:44:51 -07:00
topjohnwu
7df4a9d74f Add uninstaller.sh test 2025-08-05 09:44:51 -07:00
topjohnwu
bf4ed295da Update cargo dependencies 2025-08-02 13:43:27 -07:00
topjohnwu
a5fca960dc Update gradle and dependencies 2025-08-02 02:29:14 -07:00
topjohnwu
f99912b9db Update libsystem_properties 2025-07-21 13:47:30 -07:00
5ec1cff
a54bdb54e4 Skip avb 1,0 verify if tail contains avb 2.0 header
This way, magiskboot will not print "unexpected ASN.1 DER tag: expected SEQUENCE, got APPLICATION [1] (primitive)".
2025-07-21 00:51:14 -07:00
topjohnwu
cd9851a1fe Add regression test for #9179 2025-07-18 17:58:29 -07:00
Wang Han
9ca469898c Use worker for replace feature
This fixes https://github.com/topjohnwu/Magisk/issues/9179.
2025-07-18 16:57:20 -07:00
𝗛𝗼𝗹𝗶
0665549473 Update Turkish
Missing parts were filled in and made better
2025-07-14 10:46:05 -07:00
topjohnwu
9d7a14b335 Remove unnecessary return 2025-07-14 10:03:22 -07:00
Wang Han
62e29fee74 Treat bind mount failure same as C++ implementation
This fixes #9139 and #9174.
2025-07-14 00:27:24 -07:00
igor
e472db552b Update portuguese/english translations 2025-07-11 10:52:21 -07:00
topjohnwu
466e4bd4e1 Update cargo dependencies 2025-07-11 02:04:33 -07:00
topjohnwu
4cf525c588 Add Android canary builds into CI tests 2025-07-11 00:16:39 -07:00
topjohnwu
c8aec2510d Restrict sccache cache size 2025-07-11 00:16:39 -07:00
topjohnwu
ccbfe0e66e Update gradle dependencies 2025-07-10 15:55:14 -07:00
南宫雪珊
23ea28de6f scripts: fix modules_update dir context 2025-07-10 10:59:39 -07:00
topjohnwu
55c3ee3a6f Move Zygisk code out of module.cpp 2025-07-07 13:43:11 -07:00
vvb2060
2a42ca2b8f app: fix time i18n 2025-07-07 11:04:18 -07:00
topjohnwu
a897e82fa4 Remove release notes
They are embedded into GitHub releases
2025-07-07 10:37:45 -07:00
topjohnwu
ffa15831d3 Add release dates 2025-07-07 10:35:22 -07:00
topjohnwu
a344ebf28c Add v30.1 changelog 2025-07-03 18:02:27 -07:00
topjohnwu
78f7fa348e Release Magisk v30.1
[skip ci]
2025-07-03 03:10:10 -07:00
pndwal
d8c448b99d Update faq.md
Add information on restoring Magisk App functionality when stub and full apps conflict.
2025-07-03 02:51:01 -07:00
topjohnwu
d4b83b6a44 Fix app compilation 2025-07-03 02:42:08 -07:00
vvb2060
e5d36d1d24 app: support config restrict policy 2025-07-03 02:42:08 -07:00
vvb2060
ff18cb8e70 su: support drop capabilities 2025-07-03 02:42:08 -07:00
topjohnwu
37a9724a54 Apply clippy fix 2025-07-02 21:20:14 -07:00
topjohnwu
d660401063 Treat magisk symlinks differently 2025-07-02 21:20:14 -07:00
topjohnwu
88541d6f49 Fix file attribute copy in module mounting logic
Due to various reasons, we cannot directly mount module files in /data
into the real paths. Instead we bind mount the module root directory and
remount this mirror with specific mount-point flags. Relevant to this
bug, the module mount is mounted as read-only, which means the file
attribute copy operation could fail in certain configurations.

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

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

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

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

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

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

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

Co-authored-by: LoveSy <shana@zju.edu.cn>
2025-01-19 11:54:26 +08:00
topjohnwu
049db49dc8 Use preprocessor for 64bit detection 2025-01-11 00:15:10 +08:00
Wang Han
7c1d2ec61e zygisk: Let client send arch info 2025-01-11 00:15:10 +08:00
topjohnwu
a1b2830c06 Address clippy warnings 2025-01-11 00:11:48 +08:00
topjohnwu
82d1d19267 Migrate uid_granted_root to Rust 2025-01-11 00:11:48 +08:00
topjohnwu
4d4195c02d Migrate prune_su_access to Rust 2025-01-11 00:11:48 +08:00
topjohnwu
5637a258fc Migrate package detection to Rust 2025-01-11 00:11:48 +08:00
topjohnwu
ee6810f417 Rewrite magisk logging implementation 2025-01-11 00:11:48 +08:00
topjohnwu
7098248c64 Add more functionality into Rust 2025-01-11 00:11:48 +08:00
topjohnwu
0d31d356ef Use SQLite's internal time function 2025-01-05 05:04:04 -08:00
topjohnwu
b782e7dcb7 Fetch policy table from Rust 2025-01-05 05:04:04 -08:00
Softastur
a4671b4698 Update Asturian translations
Fixing and updating
2025-01-05 03:15:31 -08:00
topjohnwu
7edd8be169 Minor changes 2025-01-04 02:24:08 -08:00
topjohnwu
24650eefe4 Bind SQLite to Rust 2025-01-04 02:24:08 -08:00
topjohnwu
8e1a44e7eb Use argument binding for query 2025-01-04 02:24:08 -08:00
topjohnwu
2722875190 Use better C++ SQL APIs 2025-01-04 02:24:08 -08:00
topjohnwu
3ca6d06f69 Cleanup database code 2025-01-04 02:24:08 -08:00
topjohnwu
10e47248de Use finer grain sqlite3 APIs 2025-01-04 02:24:08 -08:00
Pzqqt
e73ff679ac scripts: flash_script.sh: Avoid overly dangerous code 2024-12-27 16:02:24 -08:00
Wang Han
53e401fa2d Perform authentication if needed for AutomaticResponse setting 2024-12-27 16:00:02 -08:00
LoveSy
d2768357da Support systemlessly deleting files or folders
After we refactor the magic mount and always mount folder as tmpfs,
we can easily support deleting files or folders now. We recognize
dummy devices with major number 0 and minor number 0 as an indicator
for removing files and folders. This indicator is borrowed from
overlayfs.
2024-12-27 15:57:54 -08:00
LoveSy
a6c2ba7c1e Allow kernel to relabel 2024-12-27 12:35:29 -08:00
LoveSy
aae5b466fb Use rust to implement collect/reset overlay context 2024-12-27 12:35:29 -08:00
5ec1cff
2b7be8b949 init: reset overlay.d files context after sepolicy loaded 2024-12-27 12:35:29 -08:00
5ec1cff
b6511a510d Revert "Allow all domains to access tmpfs files"
This reverts commit da43ac89a0.
2024-12-27 12:35:29 -08:00
Wang Han
704541aef2 Use /metadata/watchdog as preinit dir if exists
Since Android 15, all domains are allowed to search /metadata so preinit
dir will be exposed. Use /metadata/watchdog when /metadata is chosen as
preinit device, and the dir is available (since Android 11).
2024-12-27 10:35:05 -08:00
topjohnwu
005560a4c5 Always rescan manager APK when database is updated 2024-12-26 12:18:38 -08:00
topjohnwu
231a5d1853 Cleanup test code 2024-12-25 22:26:30 -08:00
topjohnwu
9e2b59060d Drive app migration tests through instrumentation
Make tests less flaky
2024-12-25 22:26:30 -08:00
topjohnwu
08ea937f7c Test su request via instrumentation 2024-12-25 22:26:30 -08:00
topjohnwu
2baedf74d1 Install and test LSPosed through test app 2024-12-25 22:26:30 -08:00
topjohnwu
32faa4ced6 Redesign test APK architecture
The test APK and the main APK share the same process and classloader,
and in the non-hidden case, the test APK's classes take precedence over
the ones in the main APK. This causes issues because the test APK and
main APK share some dependencies, but don't always use the same
version. This is especially problematic for the Kotlin stdlib and
AndroidX dependencies.

The solution here is to rely on R8's obfuscation feature and repackage
all potentially conflicting classes into a separate package in the test
APK. To ensure that the test classes are always using the same classes
as the main APK, we have to directly implement all tests inside the main
APK, making the test APK purely a "test runner with test dependencies".

As a result, the test APK can only be used when built in release mode,
because R8 no longer allow class obfuscation to be enabled when building
for debug versions.
2024-12-25 20:17:57 -08:00
topjohnwu
ccdb0b5d13 Add ability to skip certain test variants 2024-12-25 20:11:21 -08:00
topjohnwu
8506b672ad Update CI operating system 2024-12-23 22:52:30 -08:00
topjohnwu
ce2e33bb20 Cleanup test scripts 2024-12-23 20:42:54 -08:00
topjohnwu
6707b72260 Fix AVD tests 2024-12-23 20:41:42 -08:00
topjohnwu
5885b8c20d Add new tests for app hiding 2024-12-18 17:22:31 -08:00
topjohnwu
820710c086 Fix incorrect SQLite syntax 2024-12-18 17:22:31 -08:00
topjohnwu
51cf196bf7 Always use root to hide/restore app 2024-12-18 17:22:31 -08:00
Wang Han
dadba44cf9 Update module installer guide about META-INF 2024-12-17 16:36:40 -08:00
topjohnwu
2ce4a5543b Make ndk-build happy when Rust libs are missing 2024-12-13 17:00:40 -08:00
topjohnwu
9112a3a4f5 Introduce instrumentation tests 2024-12-13 12:07:42 -08:00
topjohnwu
24615afda1 Remove usage of ProcessLifecycle 2024-12-13 12:07:42 -08:00
topjohnwu
c5778f398b Cleanup imports 2024-12-13 12:07:42 -08:00
topjohnwu
4eb4097b9b Split file processing into its own class 2024-12-13 12:07:42 -08:00
vvb2060
c512496847 install_module: simplify script 2024-12-12 10:08:09 -08:00
vvb2060
506961a10d flash module: ignore META-INF 2024-12-12 10:07:47 -08:00
topjohnwu
3414415907 Support zip files with unsupported compresssion method 2024-12-12 02:50:19 -08:00
topjohnwu
dc2ae7cfd1 Disable CI on master push
Changes should be done through PRs for CI
2024-12-12 02:50:19 -08:00
topjohnwu
2e86d21c29 16k pages only work on Android B on x64 2024-12-09 20:13:27 -08:00
topjohnwu
2654382c43 Address clippy warnings 2024-12-09 18:26:39 -08:00
topjohnwu
9e26b73813 Update rust dependencies 2024-12-09 18:26:39 -08:00
topjohnwu
10cd13bf80 Update ONDK r28.1 2024-12-09 18:26:39 -08:00
topjohnwu
f10ee5f887 Test 16K pages with AVD instead of Cuttlefish 2024-12-09 14:16:08 -08:00
topjohnwu
47cc532d96 Release new canary build 2024-12-06 18:19:06 -08:00
topjohnwu
218327f92b Release Magisk v28.1 2024-12-06 17:45:41 -08:00
topjohnwu
4eae66a1a7 Add v28.1 release notes 2024-12-06 17:38:43 -08:00
vvb2060
b09ceeb43c scripts: sync avd_magisk.sh with mgiskinit 2024-12-06 02:21:17 -08:00
vvb2060
4fb539c110 core: use a new tmpfs as worker 2024-12-06 02:19:43 -08:00
vvb2060
849b284da5 core: insert symlink magisk_node 2024-12-06 02:19:32 -08:00
topjohnwu
895b5f6cbf Release new canary build 2024-12-04 01:28:31 -08:00
SonyaMedved
cb3d4ea514 strings.xml
The strings have been translated into Ukrainian.
2024-12-04 01:26:39 -08:00
topjohnwu
0d89a2a97d Update AGP 2024-12-04 01:25:44 -08:00
nedokaka
3ca5913055 Update Russian Translation 2024-12-03 19:52:53 -08:00
topjohnwu
df6b808f49 Cleanup DesugarClassVisitorFactory 2024-12-03 19:52:39 -08:00
topjohnwu
09c7ac754b Simplify MagiskD Rust/C++ FFI 2024-12-03 15:51:17 -08:00
topjohnwu
805da67c23 Update cxx-rs 2024-12-03 14:16:14 -08:00
topjohnwu
3c6889505b Stop using polymorphism in magiskinit 2024-12-03 02:18:22 -08:00
topjohnwu
c8e9ce7627 Cleanup mount code in magiskinit 2024-12-03 02:18:22 -08:00
topjohnwu
837c679a31 Update avd_test API versions 2024-12-03 02:18:22 -08:00
LoveSy
06616659b8 Only desugar ZipEntry's methods 2024-12-02 19:55:28 -08:00
topjohnwu
a34c04f999 Release new canary build 2024-12-01 14:59:57 -08:00
topjohnwu
da43ac89a0 Allow all domains to access tmpfs files
Fix #8457
2024-11-30 23:21:33 -08:00
vvb2060
830fc758b9 init: Use apex dir to determine whether 2SI 2024-11-30 23:03:29 -08:00
vvb2060
0f3cfef278 Revert "init: support 2SI devices with skip_initramfs"
This reverts commit b38fd1ca5f.
2024-11-30 23:03:29 -08:00
topjohnwu
b32d7bfafd Update gradle version 2024-11-21 21:05:35 -08:00
topjohnwu
c0899f2939 Update dependencies 2024-11-19 20:29:15 -08:00
topjohnwu
082330808f Fix building APK 2024-11-19 20:25:10 -08:00
topjohnwu
024da05888 Move several stuff into buildSrc 2024-11-09 20:08:12 -08:00
LoveSy
377b6d0cc2 avoid desugar the Desugar class 2024-11-09 19:41:06 -08:00
Georgi Boiko
c661009b31 docs(ci): update setup action to state correct jdk version 2024-11-04 11:12:01 -08:00
vvb2060
613f2d31c5 app: auto close action fragment only when focus lost 2024-11-04 11:11:41 -08:00
vvb2060
7dbb973db5 daemon: some samsung devices using incorrect mediatek-res path 2024-11-04 11:09:53 -08:00
topjohnwu
f4502f8be8 Add our own API desugaring
Some checks failed
Magisk Build / Build Magisk artifacts (push) Has been cancelled
Magisk Build / Test building on ${{ matrix.os }} (ubuntu-latest) (push) Has been cancelled
Magisk Build / Test building on ${{ matrix.os }} (windows-latest) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 23) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 24) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 25) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 26) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 27) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 28) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 29) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 30) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 31) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 32) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 33) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (, 34) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86_64) (google_apis, 35) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86) (23) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86) (24) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86) (25) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86) (26) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86) (27) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86) (28) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86) (29) (push) Has been cancelled
Magisk Build / Test API ${{ matrix.version }} (x86) (30) (push) Has been cancelled
Magisk Build / Test ${{ matrix.device }} (aosp-main, aosp_cf_x86_64_phone) (push) Has been cancelled
Magisk Build / Test ${{ matrix.device }} (aosp-main-throttled, aosp_cf_x86_64_phone_pgagnostic) (push) Has been cancelled
Fix #8452
2024-10-29 12:13:22 -07:00
topjohnwu
455b13b83c Fix download URL in stub.apk 2024-10-17 19:42:10 -07:00
topjohnwu
8b98709743 Update dependencies 2024-10-17 13:17:46 -07:00
tzagim
1b12f45f39 Update Hebrew Translation 2024-10-15 15:23:21 -07:00
vvb2060
a5cad532ff ui: fix lock screen orientation 2024-10-12 01:16:24 -07:00
topjohnwu
070719db50 Release new canary build 2024-10-10 02:10:50 -07:00
topjohnwu
28cccdf7aa Release Magisk v28.0 2024-10-10 01:47:00 -07:00
topjohnwu
b7e0986a5c Add v28.0 changelog 2024-10-10 01:40:14 -07:00
topjohnwu
da709745dd Revert #8245 2024-10-09 15:40:23 -07:00
topjohnwu
8b6771d487 Update dependencies 2024-10-08 01:40:09 -07:00
topjohnwu
e1b847fbc5 Find boot image with MagiskInstaller
Fix #8211
2024-10-07 16:52:35 -07:00
topjohnwu
7188de1205 Support unaligned boot image file
Fix #7733
2024-10-06 03:01:08 -07:00
topjohnwu
44fb7dbcbe Update Busybox
Fix #8403
2024-10-06 01:47:13 -07:00
topjohnwu
8086b5933c Update crt0
Fix #8424
2024-10-02 16:37:07 -07:00
topjohnwu
7f675f4bf7 Update dependencies 2024-09-27 14:38:32 -07:00
vvb2060
5e6b53e0da AppMigration: put suManager after installation 2024-09-25 12:34:21 -07:00
残页
5b29fefc65 Replace LOGE with LOGW so the process don't abort
Co-authored-by: 南宫雪珊 <vvb2060@gmail.com>
2024-09-25 11:59:58 -07:00
残页
16a168535d Check sepolicy database version in add_xperm_rule
Fix #8344
2024-09-25 11:59:58 -07:00
Wang Han
33f70f8f6d Update zh-rCN strings 2024-09-17 15:01:10 -07:00
topjohnwu
4f18a66d73 Release new canary build 2024-09-17 01:46:04 -07:00
Wang Han
250dc16007 Fix post-fs-data blocking time in doc
f7d3d1eeaf.
2024-09-17 01:28:01 -07:00
Wang Han
7af273e047 Don't append "start logd" in post-fs-data
This was first done in b13eb3f because magiskd was started in
post-fs stage that time. Among all android versions, logd was all
started before post-fs-data.
2024-09-16 00:30:36 -07:00
Arbri çoçka
e381aebaa0 Update strings.xml Albania (sq) 2024-09-16 00:24:47 -07:00
LoveSy
45d91c9658 Upgrade Gradle 2024-09-15 00:14:15 -07:00
igor
4a9158f667 Update Portuguese translation 2024-09-14 23:08:40 -07:00
niels
0d9ee89e7f magiskboot: cleanup bootconfig and vendor ramdisk dir 2024-09-14 23:08:22 -07:00
topjohnwu
abaff72304 Enable core library desugaring
Fix #8343
2024-09-09 01:59:32 -07:00
topjohnwu
b828e2d0b2 Update dependencies 2024-09-08 03:02:09 -07:00
Wang Han
53d7cbc11b Clarify magiskboot requirements for repacking img 2024-09-08 01:13:46 -07:00
LoveSy
310be7ab47 Return exit value of action.sh 2024-09-08 01:12:30 -07:00
LoveSy
60894e458f Automatically close action fragment when action exits successfully 2024-09-08 01:12:30 -07:00
LoveSy
fbebb6ac10 Add action.sh for user to manually trigger modules' functionality from app 2024-09-08 01:12:30 -07:00
LoveSy
a9f8c20703 Upgrade AGP 2024-09-05 21:50:56 -07:00
vvb2060
ae0b15d197 deps: update gradle to 8.10 2024-09-05 21:50:46 -07:00
vvb2060
869aa62328 ci: fix build 2024-09-05 21:50:46 -07:00
vvb2060
dcd3bc58a3 app: target api 35 2024-09-05 21:50:46 -07:00
Salvo Giangreco
a82f17c594 Disable Samsung PROCA
Signed-off-by: Salvo Giangreco <giangrecosalvo9@gmail.com>
2024-09-04 01:49:02 -07:00
vvb2060
b38fd1ca5f init: support 2SI devices with skip_initramfs 2024-09-03 16:33:57 -07:00
topjohnwu
8e82113bce Release new canary build 2024-08-23 01:07:45 -07:00
vvb2060
f723ef153b zygisk_node: skip magisk32 if 64bit zygote only 2024-08-22 11:58:29 -07:00
topjohnwu
1dc723fb6d Attempt to reuse cache on Windows 2024-08-21 22:06:12 -07:00
topjohnwu
8f271c2575 Custom sccache support in CI 2024-08-21 16:51:30 -07:00
topjohnwu
7cf56b4406 Simplify ramdisk test 2024-08-21 16:46:37 -07:00
Wang Han
c2eb603957 Require GMS to be system app
Fixes https://github.com/topjohnwu/Magisk/issues/8279.
2024-08-20 10:36:14 -07:00
topjohnwu
e6bd2ff60f Fix stock image restore
Fix #8211
2024-08-20 02:23:20 -07:00
topjohnwu
5604074eba Fix module auto install
Fix #8208
2024-08-20 01:09:25 -07:00
topjohnwu
3f061c1a1e Update dependencies 2024-08-19 17:54:02 -07:00
LoveSy
55e78a7b1a BYD XDJA container support 2024-08-19 17:50:16 -07:00
vvb2060
000f1d6041 Revert "Don't support alternative binary paths"
This reverts commit 1eeb2a34a1.
2024-08-19 11:52:55 -07:00
vvb2060
2cbec20238 find_boot_image: test GKI 1.0 2024-08-19 03:05:24 -07:00
vvb2060
4b724c7257 find_boot_image: test previous kernels (<=4.19) 2024-08-19 03:05:24 -07:00
vvb2060
ab04c6ab39 find_boot_image: keep symlink 2024-08-19 03:05:24 -07:00
topjohnwu
821a6c6954 Only save gradle cache on asset build job 2024-08-18 21:42:28 -07:00
topjohnwu
5f27a62221 Use gradle version catalog 2024-08-18 13:12:23 -07:00
topjohnwu
c76cc4c6bd Update cuttlefish hostside tools 2024-08-16 15:58:29 -07:00
𝗦𝗵𝗟𝗲𝗿𝗣
52b75c53b6 Update TR Locales 2024-08-16 11:38:36 -07:00
topjohnwu
9db2e99086 Test 16k on Cuttlefish 2024-08-15 22:51:40 -07:00
LoveSy
e9e2ecf2dd load partition_map only once 2024-08-15 10:10:18 -07:00
LoveSy
9a9e617c35 Use find_if 2024-08-15 10:10:18 -07:00
LoveSy
3a0becc783 Use parse_impl for partition_map 2024-08-15 10:10:18 -07:00
ChsBuffer
1f974cb220 Use androidboot.partition_map as a fallback for matching partition names in the preinit finding. 2024-08-15 10:10:18 -07:00
LoveSy
1db80228e8 Move worker mount to magiskinit 2024-08-15 02:39:51 -07:00
LoveSy
838e1e254d Move devpts mount to magiskinit 2024-08-15 02:39:51 -07:00
topjohnwu
554eda8fe1 Switch to gmake on macOS 2024-08-15 02:37:59 -07:00
topjohnwu
2bdc047c4d Call sqlite3_free only on sqlite3 malloc-ed objects 2024-08-14 13:23:59 -07:00
topjohnwu
e64f59ce5b Make CI faster 2024-08-14 00:21:45 -07:00
topjohnwu
b8140ad4e6 Re-enable Windows CI 2024-08-13 21:12:06 -07:00
LoveSy
5a55483698 Set -fno-threadsafe-statics for crt0
Since crt0 has no pthread support, we don't need lock for statics.
2024-08-12 10:57:45 -07:00
vvb2060
2d341863f5 set MAGISKTMP 2024-08-12 02:05:58 -07:00
LoveSy
278046becb Fix wrong cxx_extern return value
This fix UB
2024-08-12 02:05:26 -07:00
topjohnwu
5c0497354f Temporarily disable Windows CI 2024-08-12 02:04:13 -07:00
topjohnwu
98c258df93 Update AGP 2024-08-11 04:30:01 -07:00
topjohnwu
c578cccfd5 Update to ONDK r27.4 2024-08-11 04:16:19 -07:00
Andrew Gunnerson
07835a3e0e util_functions.sh: Fix syntax error due to missing then
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2024-08-06 01:16:19 -07:00
topjohnwu
09131aca89 Fix find_boot_image
Close #8255
2024-08-05 11:24:30 -07:00
topjohnwu
9ce998a6df Fix arab strings 2024-08-04 01:54:28 -07:00
topjohnwu
ca36b42d79 Update release.sh 2024-08-03 01:55:03 -07:00
topjohnwu
37df39ec37 Address clippy warnings 2024-08-03 01:52:16 -07:00
topjohnwu
1701361a73 Update cargo dependencies 2024-08-03 01:49:14 -07:00
topjohnwu
4c14ae33f5 Properly configure Rust builds 2024-08-03 01:28:53 -07:00
topjohnwu
d4a9ef7b7f Cleanup build.py 2024-08-03 00:05:49 -07:00
topjohnwu
1539cfe888 Support setting custom ABI list
Also stop building riscv64 by default
2024-08-01 14:33:08 -07:00
topjohnwu
9093be1329 Run commands through shell on Windows 2024-07-31 17:21:18 -07:00
topjohnwu
606d076251 Build debug with thin lto 2024-07-31 17:00:01 -07:00
残页
46a34e19bc Check vendor boot ramdisk table size 2024-07-31 16:59:51 -07:00
topjohnwu
5ac7dc0b37 Support vendor boot unpack/repack
Fix #6460, close #6620
2024-07-30 04:00:12 -07:00
topjohnwu
3b27de3715 Output logs to files 2024-07-25 03:48:13 -07:00
topjohnwu
939bfac920 Make sure version is fetched correctly 2024-07-25 03:04:27 -07:00
muhammadbahaa2001
f601bf12d5 Updated Arabic 2024-07-25 03:03:49 -07:00
topjohnwu
0495468d02 Release new canary build 2024-07-24 23:13:21 -07:00
topjohnwu
300a2a242c Add release script 2024-07-24 23:10:57 -07:00
topjohnwu
33aebb5976 Stop embedding executables 2024-07-24 22:49:48 -07:00
pndwal
b3d6809c0b Update README.MD
Remove redundant Canary changelog link
2024-07-24 19:04:50 -07:00
LoveSy
461f7e9f89 Use metadata even if it is f2fs 2024-07-24 19:02:35 -07:00
LoveSy
9cc50b20d8 Correctly handle comments in sepolicy.rule 2024-07-24 19:02:25 -07:00
LoveSy
f488e9df8f Fix sepolicy rule path 2024-07-24 19:02:12 -07:00
LoveSy
0dc596e206 Update Chinese translation 2024-07-24 19:01:59 -07:00
topjohnwu
c3bf03190b Use K2 in kapt 2024-07-24 17:06:41 -07:00
topjohnwu
021ae891a9 Update dependencies 2024-07-24 16:53:15 -07:00
topjohnwu
9c03514eb1 Create :app:clean task 2024-07-24 16:46:47 -07:00
topjohnwu
eb74b266e1 Do not modify args
Close #8242
2024-07-24 16:37:22 -07:00
topjohnwu
80eb6ff25a Update README 2024-07-23 21:37:04 -07:00
topjohnwu
7b81e2d2d1 Release new canary build 2024-07-23 17:23:50 -07:00
topjohnwu
a8789073f1 Run copy_preinit_files in run_migrations 2024-07-23 02:21:49 -07:00
残页
c8fe0f5524 Catch possible exceptions when the receiver is already unregistered 2024-07-23 02:06:15 -07:00
vvb2060
d33b077a13 Remove NVBASE
We only move /cache/data_adb/magisk and /data/magisk to /data/adb/magisk (#7638), so NVBASE is redundant and we can just use MAGISKBIN.
2024-07-23 02:03:47 -07:00
vvb2060
2282365cf8 clean code 2024-07-23 02:02:56 -07:00
vvb2060
9a00b7b942 update copy_preinit_files 2024-07-23 02:02:56 -07:00
vvb2060
d54baadbed Use ro.crypto.metadata.enabled 2024-07-23 02:02:56 -07:00
LoveSy
0869a90fe3 Use symlink to setup preinit 2024-07-23 02:02:56 -07:00
LoveSy
2754b1dcf8 Add comment about the choice 2024-07-23 02:02:56 -07:00
LoveSy
0db6314661 Refactor preinit finding 2024-07-23 02:02:56 -07:00
topjohnwu
b5d2ef18e8 Move more data and function into HookContext 2024-07-22 20:36:55 -07:00
topjohnwu
6e22476acc Update test scripts 2024-07-22 03:39:04 -07:00
topjohnwu
b26db8cee6 Switch over to ANDROID_HOME
Keep ANDROID_SDK_ROOT as a fallback
2024-07-21 00:53:13 -07:00
topjohnwu
33cb39c8af Minor code changes for hook.cpp 2024-07-21 00:52:43 -07:00
LoveSy
f247759a6e No need _orig to call backup 2024-07-20 21:36:26 -07:00
LoveSy
de7e5bdfe7 Update comments 2024-07-20 21:36:26 -07:00
LoveSy
53a8ba8cfe Use hookJniNativeMethods to hook zygote pre/post fork 2024-07-20 21:36:26 -07:00
LoveSy
f2d057baba Refine hookJniNativeMethods 2024-07-20 21:36:26 -07:00
LoveSy
93bcf2cd25 Correct debug symbol configuration 2024-07-20 20:29:58 -07:00
LoveSy
6d82515cfc No default features of pb-rs 2024-07-20 20:29:38 -07:00
topjohnwu
a177d3b022 Fix AVD test on API 23 2024-07-20 15:08:06 -07:00
topjohnwu
92b2e06e57 Increase cgu on debug builds 2024-07-20 04:59:20 -07:00
topjohnwu
f919bb0e99 Minor changes 2024-07-20 04:52:25 -07:00
topjohnwu
054971e899 Add permissions 2024-07-20 03:43:06 -07:00
topjohnwu
93c3d36452 Add Cuttlefish tests in CI 2024-07-20 03:10:18 -07:00
topjohnwu
4c38af994d Sync native and Java implementation 2024-07-19 23:22:08 -07:00
topjohnwu
bbb8efe92c Support Cuttlefish 2024-07-19 22:08:35 -07:00
topjohnwu
659dd09723 Do not modify system-images contents when patching 2024-07-19 16:47:12 -07:00
LoveSy
4931825912 Fix zygisk v5 2024-07-17 10:52:16 -07:00
topjohnwu
ef81cdab4f Prebuild Busybox
Prebuild with tools in ndk-box-kitchen
2024-07-17 02:58:31 -07:00
topjohnwu
7c0b25cad9 Release new canary build 2024-07-12 15:54:16 -07:00
topjohnwu
b38ab2a7d6 Use K2 to compile buildSrc
Make all Kotlin source code build with K2.
K2 seems to have bugs with lazy property assignment, revert it to set().
2024-07-12 15:27:04 -07:00
LoveSy
a97191052b Upgrade gradle 2024-07-12 13:46:06 -07:00
vvb2060
2963d4ca9e Rewrite get_manager 2024-07-12 13:45:48 -07:00
vvb2060
6aab856de7 Enhanced denylist app id tracking 2024-07-12 13:45:48 -07:00
topjohnwu
94d1c66f8a Make AVD test timeout at 10 minutes 2024-07-12 11:39:11 -07:00
topjohnwu
7ff4d7608e Update dependencies 2024-07-11 23:28:01 -07:00
sn-o-w
46ef915c83 Update Romanian 2024-07-11 22:31:32 -07:00
LoveSy
63b0a0d96b Fix incomplete native debug symbols
See https://github.com/android/ndk/issues/2039
2024-07-11 22:31:09 -07:00
LoveSy
ea4cabdfc5 Use simple property assignment 2024-07-11 22:28:59 -07:00
LoveSy
0185ddf577 Fix building on higher version of jdk 2024-07-11 22:28:59 -07:00
topjohnwu
ddae568741 Move SplashActivity logic into core module 2024-07-11 22:08:01 -07:00
topjohnwu
fcb7ebb090 Cleanup resources 2024-07-11 17:58:52 -07:00
topjohnwu
8d446fcc16 Move all core code into the same parent package 2024-07-11 16:49:01 -07:00
topjohnwu
881d3b5221 App migration minor refactoring 2024-07-11 16:28:56 -07:00
topjohnwu
fe9ec3bc6d Move app initialization routine into core module 2024-07-11 16:10:49 -07:00
topjohnwu
480198dcd0 Improve package migration 2024-07-11 15:50:40 -07:00
topjohnwu
4ab7bc0d97 Minor SettingsItem cleanup 2024-07-11 02:44:38 -07:00
topjohnwu
7173693d1b Use platform LocaleManager if possible 2024-07-11 02:44:38 -07:00
topjohnwu
6b81716440 Update stub implementation 2024-07-11 02:44:38 -07:00
topjohnwu
88e8e15607 Create singleton AppContext 2024-07-11 02:44:38 -07:00
LoveSy
69181a6b72 Fix wrong sepolicy rule 2024-07-08 12:09:45 -07:00
Wang Han
b11b81122a Tighten rules for tmpfs file
Before magiskd is executed, all files in magisk tmpfs still shares
tmpfs label. This commit tightens the rule to only allow init, zygote
and shell to access magisk tmpfs files. Zygotes rules is needed
because lower Android versions don't have rule for zygote itself
using memfd even memfd is supported in kernel.
2024-07-08 12:06:49 -07:00
Wang Han
648e3ee36b Update build.yml 2024-07-08 12:02:51 -07:00
LoveSy
724b94f320 Update README.MD (#8192)
Co-authored-by: 南宫雪珊 <vvb2060@gmail.com>
2024-07-08 12:02:14 -07:00
topjohnwu
a6e65f9a7e Fix building release builds 2024-07-06 01:55:09 -07:00
topjohnwu
af5c4d09c4 Re-enable nonTransitiveRClass 2024-07-06 01:31:43 -07:00
topjohnwu
872394cb58 Decouple core module from AppCompatActivity 2024-07-05 00:49:26 -07:00
topjohnwu
fcbbe9a22e Move :app to :app:apk 2024-07-04 02:27:20 -07:00
topjohnwu
b168163ef0 Move :stub to :app:stub 2024-07-04 00:21:34 -07:00
topjohnwu
3e38b8fed1 Separate core codebase into its own module
- Separate UI specific code and resources outside of the core
  application logic
- Allow most of the code to move forward and use KSP for annotation
  processing and isolate rotton code that is stuck with databinding
- Make full UI rewrite more feasible
2024-07-04 00:02:42 -07:00
kubalav
f90c548f27 Update Slovak translation 2024-07-03 22:55:31 -07:00
igor
c981c40218 Update Portuguese translation 2024-07-03 22:55:12 -07:00
Rom
dcbf37c5e8 Update French translation
To match with changes of "Add option to disable filename randomization"
2024-07-03 22:54:47 -07:00
topjohnwu
300b233a27 Simplify MediaStoreUtils 2024-07-02 17:15:27 -07:00
topjohnwu
e32cd03d0b Update docs to cover riscv64 2024-07-02 14:53:46 -07:00
LoveSy
a07b9315a5 Add riscv64 support 2024-07-02 14:34:22 -07:00
topjohnwu
e9694c6195 Add option to disable filename randomization 2024-07-02 14:28:26 -07:00
Wang Han
4a2a37c87a Catch PendingIntent.CanceledException caused by send()
Accidentally changed in 050a073.
2024-07-02 14:24:27 -07:00
vvb2060
7dca5b831a check empty init_boot partition
For upgrading devices that continue to use Android 12 or older kernel versions, the generic ramdisk remains where it was with no requirement for a new init_boot image.
2024-07-02 14:23:28 -07:00
topjohnwu
be5ff68140 Exclude apache commons codec resources 2024-07-01 18:56:08 -07:00
topjohnwu
59f40d5fe5 Move manager.sh to app_functions.sh 2024-07-01 18:42:05 -07:00
topjohnwu
1fbd053a42 Prevent polluting global shell env 2024-07-01 18:20:21 -07:00
topjohnwu
966c6314f8 Cleanup configs 2024-07-01 17:23:48 -07:00
Li Hua
c92204c724 Update Simplified Chinese Translation
Signed-off-by: Li Hua <lihua@email.com>
2024-07-01 14:51:06 -07:00
igor
bb9947d4d2 Update Portuguese translation 2024-07-01 14:50:52 -07:00
Wang Han
7c8cdb4ad6 Set default visibility of restart button to GONE
This fixes the issue that button still shows when installation fails.
2024-07-01 14:50:34 -07:00
Wang Han
bd7f9c9e46 Unset FLAG_ACTIVITY_NO_HISTORY for SuRequestActivity
This fixes device credential confirm activity on OnePlus devices
because SuRequestActivity is accidentally finished before a valid
response is delivered to it.
2024-07-01 14:50:09 -07:00
vvb2060
9a33a4dfe2 Fix StackOverflowError
Now field from base class java.io.ByteArrayOutputStream shadows the property with custom getter from derived class com.topjohnwu.magisk.core.utils.AXML.RawByteStream. This behavior will be changed soon in favor of the property. Please use explicit cast to java.io.ByteArrayOutputStream if you wish to preserve current behavior. See https://youtrack.jetbrains.com/issue/KT-55017 for details
2024-07-01 14:36:20 -07:00
topjohnwu
47e918bc92 Fix vbmeta.img tar patching 2024-07-01 03:20:09 -07:00
Wang Han
c194168d9b Fix item match when extracting lib from stub
Close #8083.
2024-06-29 22:14:24 -07:00
topjohnwu
cacc60b1ac Migrate to Apache commons-compress
Close #8121
2024-06-29 22:11:02 -07:00
topjohnwu
52063b3652 Update to Kotlin 2.0.0 2024-06-29 17:04:40 -07:00
topjohnwu
85a4eaff59 Release new canary build 2024-06-28 16:16:41 -07:00
topjohnwu
45fa1fce70 Update libsu 2024-06-28 15:45:40 -07:00
loselarry
2112c916f5 chore: remove repetitive word
Signed-off-by: loselarry <bikangning@yeah.net>
2024-06-22 19:17:20 -07:00
LoveSy
d6e159bff9 Use pidfd in more senarios 2024-06-22 19:16:58 -07:00
LoveSy
2f710a564f allow more -v for build.py for more verbose output 2024-06-22 19:16:37 -07:00
Fontan030
27cfc4945c Kazakh translation 2024-06-22 18:53:14 -07:00
eklerismunir
7cdada92c8 Improve azerbaijani locales and add the missing strings 2024-06-22 18:52:59 -07:00
topjohnwu
8f1e57d4f9 16k pages on x64 is broken 2024-06-22 18:51:44 -07:00
topjohnwu
8178666b49 Add 16k page testing in CI 2024-06-21 03:13:16 -07:00
topjohnwu
313532dcaa Disable verbose output by default 2024-06-21 02:45:48 -07:00
topjohnwu
2f8f3dc266 Add new test cases 2024-06-20 21:39:30 -07:00
topjohnwu
df6ada5ce3 Update avd_test to support custom type 2024-06-20 18:25:49 -07:00
topjohnwu
a89b9e6af1 Support 16K page size 2024-06-18 22:04:53 -07:00
topjohnwu
23ed275614 Update to ONDK r27.2 2024-06-18 14:34:30 -07:00
topjohnwu
cfd1e0cf22 Update libsu and dependencies 2024-06-18 11:26:18 -07:00
topjohnwu
eb400f19b1 Support Python 3.12+ 2024-06-18 03:36:16 -07:00
LoveSy
19f15f16f6 Use icf to further minimize binary size 2024-06-10 14:47:26 -07:00
topjohnwu
e158cfddfa Update system_properties 2024-06-07 13:51:24 -07:00
pndwal
d0cf93a08d Fix typos install.md 2024-06-06 21:12:18 -07:00
LoveSy
08ad0e74dd Upgrade deps
Co-authored-by: vvb2060 <vvb2060@gmail.com>
2024-06-06 21:11:52 -07:00
topjohnwu
722374a024 Update system_properties 2024-06-05 18:42:30 -07:00
LoveSy
c6f0762510 Use pidfd_open for setns
which is more efficient on newer kernel
2024-05-20 03:26:55 +08:00
LoveSy
941a363c5a Support waiting on non-exist prop 2024-05-18 13:55:33 +08:00
Arbri çoçka
2afcdc64a0 Update strings.xml sq 2024-05-18 13:52:31 +08:00
VD $ VD171 @ Priv8
3c66c4bbc5 Update PORTUGUESE translation 2024-05-18 13:52:14 +08:00
VD $ VD171 @ Priv8
9f5cd5e1cc Update PORTUGUESE translation 2024-05-18 13:52:14 +08:00
kubalav
a35f2bb73b Update Slovak translation 2024-05-18 13:51:59 +08:00
topjohnwu
6cf00130f4 Check Magisk version instead of app version 2024-05-15 12:42:55 +08:00
topjohnwu
6c27ba6b88 Rename db entry name 2024-05-15 12:42:55 +08:00
vvb2060
dd3b9980e7 app: add safe mode config to menu 2024-05-15 12:42:55 +08:00
vvb2060
02e189a029 core: add safe mode config to db 2024-05-15 12:42:55 +08:00
topjohnwu
72b8d12ee4 Update development guide 2024-05-11 20:40:33 -07:00
topjohnwu
eed03080c1 Update to ONDK r27.1 2024-05-09 09:42:40 -07:00
LoveSy
090cb4b0f9 Upgrade AGP to 8.4.0 2024-05-09 09:42:27 -07:00
topjohnwu
6f2c76b898 Fix build script 2024-05-09 02:19:24 -07:00
topjohnwu
f61827cbec Switch rustup_wrapper to Rust implementation
For better Windows portability
2024-05-09 02:19:07 -07:00
topjohnwu
3f2264f2c7 Support rustup wrapper 2024-05-09 00:34:12 -07:00
topjohnwu
c1cadf4bdc Update build.py to use pathlib 2024-05-09 00:31:41 -07:00
Rodrigo Martínez
0e56991369 Improve and add missing strings for Spanish 2024-04-29 22:23:02 -07:00
LoveSy
4dc1c59040 add missing xz_dec_end 2024-04-29 22:22:47 -07:00
topjohnwu
33b7b8b297 Update resetprop 2024-04-26 16:42:24 -07:00
topjohnwu
e6af5ed460 Address Rust warnings 2024-04-26 16:28:46 -07:00
topjohnwu
b678afa4b6 Update to ONDK r27.0
Co-authored-by: LoveSy <shana@zju.edu.cn>
2024-04-26 03:09:44 -07:00
WINZORT
4bac2df4e7 Improve turkish locales and add the missing strings 2024-04-18 02:14:21 -07:00
igor
50416eee09 Improve Portuguese translation 2024-04-18 02:13:50 -07:00
igor
73cf501d33 Improve Brazilian Portuguese translation 2024-04-18 02:13:50 -07:00
Hen_Ry
d2b7907bed Update german strings.xml 2024-04-18 02:13:28 -07:00
topjohnwu
99d5dd5ea8 Update crt0 2024-04-17 10:12:27 -07:00
cloudchamb3r
5fdb841fa8 Fix typo
Fix typo in values-ko/strings.xml
2024-04-17 09:18:14 -07:00
topjohnwu
7c88484d64 Fix #7988 2024-04-16 19:45:01 -07:00
topjohnwu
b22b6a4204 Refactor cpio 2024-04-10 22:46:21 -07:00
topjohnwu
2a3d34c812 Fix mkdirs 2024-04-10 22:36:47 -07:00
topjohnwu
c50ee722a1 Use memmem for finding needle in haystack 2024-04-10 14:57:44 -07:00
topjohnwu
ffc1e38e48 Add 32 bit CI 2024-04-10 02:56:23 -07:00
topjohnwu
6219d5fcbf Update crt0 for 32 bit 2024-04-10 02:43:37 -07:00
topjohnwu
2e4440b702 Support 32-bit magiskboot 2024-04-09 19:34:14 -07:00
topjohnwu
0d9ec0931b Code cleanup 2024-04-08 23:00:59 -07:00
vvb2060
60e8415369 Make denylist work when zygisk is disabled
Co-authored-by: topjohnwu <topjohnwu@gmail.com>
2024-04-08 23:00:50 -07:00
LoveSy
652a26d5d9 Fix comment of sepolicy 2024-04-03 21:03:41 -07:00
topjohnwu
f57839379a Update RustCrypto dependencies 2024-04-03 21:03:05 -07:00
LoveSy
36bd00a046 Add p521 to magiskboot 2024-04-03 21:03:05 -07:00
topjohnwu
fb5ee86615 Install one single ABI in ramdisk 2024-03-31 22:01:22 -07:00
topjohnwu
30bf5c8448 Fix typos 2024-03-31 14:17:25 -07:00
topjohnwu
2051836a73 Remove unused code 2024-03-30 21:03:51 -07:00
topjohnwu
2cb0af1ff3 Move revert_unmount into Rust 2024-03-30 02:51:39 -07:00
topjohnwu
a1b6568226 Implement preinit related features in Rust 2024-03-28 14:11:03 -07:00
topjohnwu
1eddbfd72c Use const_format for const strings 2024-03-26 18:03:40 -07:00
topjohnwu
21ed095601 Update crt0 2024-03-25 16:11:02 -07:00
Js0n
000a2e4d59 Upgrade AGP to 8.3.1 2024-03-22 17:02:18 -07:00
Js0n
7abe635de9 fix: AGP 8.3.X 2024-03-22 17:02:18 -07:00
topjohnwu
9a008c17ba Optimize for binary size 2024-03-22 16:53:44 -07:00
topjohnwu
08dbf728a4 Allow platform_app to access MagiskSU 2024-03-22 16:53:44 -07:00
topjohnwu
4670f762d3 Disable debug only features 2024-03-22 16:53:44 -07:00
topjohnwu
efa49567fa Fix parsing logic for term and sterm 2024-03-21 18:17:28 -07:00
topjohnwu
0ffc4527a7 Better error reporting 2024-03-21 15:10:34 -07:00
topjohnwu
dd9d43be96 Move sepolicy parsing error message into Rust 2024-03-21 14:07:28 -07:00
topjohnwu
865fca71a5 Optimize sepolicy rules
Close #7916

Co-authored-by: vvb2060 <vvb2060@gmail.com>
2024-03-21 01:51:35 -07:00
topjohnwu
6b4baa3bcd Change a little parsing handling 2024-03-21 00:04:09 -07:00
topjohnwu
a9ee2d7d18 Fix xperm parsing logic 2024-03-20 23:13:54 -07:00
topjohnwu
d654b9cb97 Several code cleanups in sepolicy 2024-03-20 23:09:22 -07:00
LoveSy
4d2921e742 Rewrite sepolicy statement parsing in Rust 2024-03-20 10:12:23 -07:00
vvb2060
ecc74d45d1 Let magic mount optional 2024-03-19 23:21:41 -07:00
vvb2060
5de597f079 No need to unshare 2024-03-19 23:21:41 -07:00
LoveSy
156b0e67ca No need extra tmpfs for worker 2024-03-19 23:21:41 -07:00
vvb2060
10069215f4 Rename dir name 2024-03-19 23:21:41 -07:00
LoveSy
92b305a389 Remove unnecessary mirror for magic mount
Mirror was previously used for accessing the original file during
magic mount when we are using a tmpfs to cover the target. However,
since we introduce atomic mount, we switch all tmpfs mount in
worker and then move to the target at once. It means that we can
still access the original file when we are constructing the tmpfs
mount point. Thus we no longer need mirror.
2024-03-19 23:21:41 -07:00
topjohnwu
d20b30c771 Update libsepol
Close #7915
2024-03-19 02:54:01 -07:00
topjohnwu
83209b21ff Release new canary build 2024-03-19 00:51:07 -07:00
topjohnwu
81658d45f7 Support tar with files larger than 8GiB
Fix #7838
2024-03-14 16:54:46 -07:00
topjohnwu
c951b208a1 Always update stub APK when upgrade 2024-03-14 14:31:02 -07:00
topjohnwu
050a073771 Make all I/O suspendable 2024-03-12 03:24:42 -07:00
topjohnwu
21d374214f Minor cleanup of DownloadEngine 2024-03-12 03:14:06 -07:00
LoveSy
19ea25a9d0 Upgrade AGP 2024-03-08 17:12:46 -08:00
topjohnwu
dbf6e40dfe Ensure stub APK is expected
Fix #7884
2024-03-08 17:09:54 -08:00
topjohnwu
d56f4fbc90 Fix stub on API 34 2024-03-08 15:57:49 -08:00
topjohnwu
73c3d741a7 Reorganize some code 2024-03-06 18:07:01 -08:00
pndwal
2b5fc75127 Update faq.md
Since system Safe Mode may activate without Magisk 'Safe Mode', this clarification will prevent users from erroneously concluding either that Safe Mode doesn't work or that modules are not the issue since 'Safe Mode' was apparently triggered...

Fixes this: #4624
2024-03-06 17:48:54 -08:00
osm0sis
991802ab82 Add no decompression flag to magiskboot split 2024-03-06 16:15:30 -08:00
WindowsFan9600
7f6b5305ba Improve Turkish language translation
Updated "reboot_download" string
2024-03-06 02:37:58 -08:00
canyie
825c6c4316 Reverse format template argument order 2024-03-06 01:39:16 -08:00
canyie
f00408c793 Fix zygote restart monitor 2024-03-06 01:39:16 -08:00
topjohnwu
a6ff3672af Update crt0 2024-03-04 16:42:25 -08:00
LoveSy
2290ddeb89 Fix segfault when sepolicy.rule has empty line 2024-03-02 06:15:45 -08:00
topjohnwu
74af79ad03 Update crt0 2024-03-02 05:57:48 -08:00
LoveSy
b6c24a3a8a No more sony init.real tricks
Co-authored-by: canyie <a1364259@163.com>
Co-authored-by: vvb2060 <vvb2060@gmail.com>
2024-02-29 23:40:00 -08:00
LoveSy
a8c2ae223a Avoid hexpatch /init for 2SI when possible
Previous we hexpatch /init from /system/bin/init to /data/magiskinit
to redirect the second stage init. However, some devices like sony
has /init that does not directly invoke /system/bin/init, and thus
the hexpatch fails.

In this patch, we further make use of AOSP `SwitchRoot` to help us
bind mount /data/magisk to /system/bin/init after `SwitchRoot`.

Two important assumption about 2SI are i) that the second stage init
is always /system/bin/init and ii) that the /sdcard (path after
`SwitchRoot`) is always a symlink to `/storage/self/primary`. When
these assumptions hold, during first stage init (before `SwitchRoot`)
we can bind mount magiskinit to /sdcard, and create a symlink
/storage/self/primary to /system/system/bin/init. By these steps,
during `SwitchRoot`, AOSP init will try to mount move /sdcard to
/system/sdcard. And /system/sdcard is symlink to /storage/self/primary,
it will try to mount move /sdcard to /storage/self/primary. And
/storage/self/primary in ramfs is now a symlink that points to
/system/system/bin/init, thus AOSP will try to mount move /sdcard
(which is a bind mount to magiskinit) to /system/system/bin/init.
After chroot done by AOSP init, we then have a magiskinit bind mount
on /system/bin/init, which is the second stage init.

An edge case is that some devices (like meizu) use 2SI but
does not switch root. In this case, they must already have a /sdcard
in the ramfs, thus we can check if /sdcard exists and fallback to
hexpatch.
2024-02-29 23:40:00 -08:00
topjohnwu
953d44302c Remove ancient NDK binaries 2024-02-29 23:26:58 -08:00
topjohnwu
24e46a5971 Build magiskboot with crt0 2024-02-29 02:36:05 -08:00
topjohnwu
b1297c4192 Less usage of C stdio 2024-02-28 15:52:03 -08:00
topjohnwu
9ae328fd84 Further reduce code size 2024-02-28 11:19:56 -08:00
topjohnwu
625a1d6f44 Remove seek support from streams 2024-02-28 11:07:53 -08:00
topjohnwu
987e5f5413 Address clippy warnings 2024-02-27 21:03:34 -08:00
topjohnwu
715284b70d Reorganize code 2024-02-27 18:14:30 -08:00
LoveSy
62fc7868ac Use self implemented parse_mount_info 2024-02-27 17:03:22 -08:00
topjohnwu
1a70796339 Replace all parse_mount_info usage with Rust 2024-02-27 03:49:17 -08:00
topjohnwu
af6965eefa Update init logging implementation
Use less std::fs
2024-02-26 17:49:11 -08:00
topjohnwu
8f7d2e38f7 Make crt0 an external submodule 2024-02-26 17:34:17 -08:00
topjohnwu
be433fa667 Use Rust for formatting
The fprintf implementation included in crt0 is too rudimental
2024-02-26 00:26:23 -08:00
topjohnwu
0ccd6e7381 Fix fread and fwrite implementation 2024-02-25 23:20:30 -08:00
topjohnwu
907bbbda41 Remove usage of patched static lib 2024-02-25 22:11:34 -08:00
topjohnwu
4393bc077d Implement string routines 2024-02-25 21:12:19 -08:00
topjohnwu
365b373480 Make it easy to build without crt0 2024-02-24 22:32:22 -08:00
topjohnwu
47e6dd286d Minor fixes 2024-02-24 22:00:09 -08:00
topjohnwu
0dbaf52566 Make all platforms build properly 2024-02-24 05:10:54 -08:00
topjohnwu
66f49dfab5 Remove unnecessary lock usage 2024-02-24 04:20:28 -08:00
topjohnwu
f8967e9274 Implement strerror 2024-02-24 04:02:46 -08:00
topjohnwu
a4f008fde5 Reorganize files 2024-02-24 03:41:22 -08:00
topjohnwu
e9980c778b Implement stub functions 2024-02-24 03:41:03 -08:00
topjohnwu
06b6fb0c33 Add setenv 2024-02-24 03:27:09 -08:00
topjohnwu
38cb3d4105 Add dirent implementation 2024-02-24 03:26:53 -08:00
topjohnwu
db99caf258 Use execve directly 2024-02-24 01:47:11 -08:00
topjohnwu
39dbffadfe Complete stdio 2024-02-24 01:28:58 -08:00
topjohnwu
b7505c3c9c Remove fopen usage in magiskinit 2024-02-24 00:45:07 -08:00
topjohnwu
3185e5a7ca Introduce string/mem functions 2024-02-23 23:56:31 -08:00
topjohnwu
e0cbe28711 Add the generic syscall function 2024-02-23 18:41:39 -08:00
topjohnwu
66cee19cea Add printf and sscanf family 2024-02-23 17:44:12 -08:00
topjohnwu
2ec29ade79 Add all missing syscalls 2024-02-23 14:35:12 -08:00
topjohnwu
c865d4e187 Add memory allocator 2024-02-22 21:22:27 -08:00
topjohnwu
a42a0a53ce Declare more symbols 2024-02-22 21:22:27 -08:00
topjohnwu
6d79de7d71 Initial crt0 implementation
Builds but cannot link, missing a lot of symbols
2024-02-22 21:22:27 -08:00
topjohnwu
7e9abe6e90 Update ONDK 2024-02-22 20:58:40 -08:00
残页
4d5510be4f Prompt users to use reboot button in System Updates
So the update engine can write verify info of partitions which fixes bootloop on newer Pixel devices
2024-02-19 02:14:12 -08:00
topjohnwu
b04e1394c0 Update README 2024-02-07 14:39:53 -08:00
topjohnwu
2aa923191e Rename DownloadManager to DownloadEngine
Also add some documentation
2024-02-06 17:54:15 -08:00
topjohnwu
4bf1c74164 Disable foreground service on API 34+ 2024-02-06 17:29:42 -08:00
topjohnwu
472c7878b2 Update AGP 2024-02-06 17:04:48 -08:00
topjohnwu
38ad871e33 Use user-initiated jobs for download tasks on API 34+ 2024-02-06 17:04:39 -08:00
topjohnwu
c5d34670c4 Isolate download logic from service lifecycle 2024-02-06 00:56:14 -08:00
topjohnwu
154121f3dd Release new canary build 2024-02-02 23:51:35 -08:00
topjohnwu
3d91a561fe Update README 2024-02-02 23:35:14 -08:00
topjohnwu
2c6adbc69b Release Magisk v27.0 2024-02-02 22:54:41 -08:00
topjohnwu
5280982363 Add v27.0 changelog 2024-02-02 22:47:35 -08:00
topjohnwu
18c45ae289 Update cxx and Rust dependencies 2024-02-02 14:35:30 -08:00
LoveSy
41fbd2a7be Upgrade gradle 2024-02-02 10:55:11 -08:00
LoveSy
5e45884af4 Use Apple Silicon for CI
https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/
2024-02-01 15:09:42 -08:00
topjohnwu
d78ee171bc Release new canary build 2024-01-30 15:59:02 -08:00
LoveSy
356ee1febd Code clean up 2024-01-30 11:07:37 -08:00
LoveSy
cc044ccc4c Fix zygisk unload 2024-01-30 11:07:37 -08:00
LoveSy
9c638cc463 Remove rust workaround 2024-01-29 15:07:21 -08:00
topjohnwu
df786eb2b6 Separate Linux and other jobs 2024-01-29 01:53:09 -08:00
topjohnwu
8e7186eebb Try out composite actions 2024-01-29 01:36:51 -08:00
topjohnwu
74b7b84561 Test all APIs on Linux 2024-01-28 00:46:03 -08:00
topjohnwu
308c9999fa Properly detect package changes 2024-01-28 00:42:43 -08:00
topjohnwu
930bb8687f Minor zygisk refactoring 2024-01-25 00:17:47 -08:00
topjohnwu
f2c4288d2d Run pthread_atfork only once
Close #7704
2024-01-25 00:17:05 -08:00
topjohnwu
b44141ae39 Run tests on Linux 2024-01-22 18:10:26 -08:00
kam821
86e0020964 Update Polish translation
- Added missing strings, fixed translation, escaped quotas.
- Some context dependent values (like target_pid) may require better translation in the future.
- Also, 'DenyList' translation, although correct, could be replaced in the future by better fitting polish equivalent of 'block list' / 'rejection list'.
2024-01-17 16:13:20 -08:00
残页
94d3daeadf Fix Sony init.real check 2024-01-17 16:09:50 -08:00
LoveSy
79334b7702 One stage zygisk loading 2024-01-11 16:19:39 -08:00
LoveSy
df66458db6 Check full path of init.rc instead of its dir
Some devices has `/system/etc/init/hw` but has no init.rc in it.
2024-01-11 16:18:57 -08:00
LoveSy
97705704e2 install or uninstall apk asynchronously 2024-01-11 16:16:36 -08:00
topjohnwu
1206179580 Update dependencies 2024-01-10 15:46:30 -08:00
topjohnwu
a0b8aa4da6 Release new canary build 2023-12-27 01:42:42 +08:00
topjohnwu
65207f96c8 Create custom cxx binding to Utf8CStr 2023-12-26 23:10:55 +08:00
Abhishek Girish
062e498bdd Update Malayalam translations 2023-12-25 18:46:08 +08:00
topjohnwu
1057cb3e3c Set serial on Rust binding 2023-12-24 04:36:58 +08:00
topjohnwu
2dd23b2518 Update system_properties 2023-12-24 04:36:58 +08:00
RafaeloxMC
8cab12998c Update strings.xml / German translation 2023-12-23 16:49:47 +08:00
topjohnwu
48b1c26dc8 Prevent race condition in wait 2023-12-23 06:33:12 +08:00
topjohnwu
f1e0bc3e4a Use platform implementation if possible 2023-12-23 06:24:20 +08:00
topjohnwu
38527cd58f Slightly change wait usage and API 2023-12-23 06:23:29 +08:00
LoveSy
e94d65b4b2 Add resetprop -w for waiting property change
It's very easy to wait for property change both in Java and C++,
but it's not the case in shell script. With this patch, developers
can now easily to wait for property change, just like what we have
in `.rc` files, and to wait for boot complete.
2023-12-23 00:12:42 +08:00
LoveSy
27ece3c7df Keep mirror shared before magic mount
This allows mounting during post-fs-data be kept after magic mount
2023-12-22 21:39:03 +08:00
LoveSy
06687abffc Fix magisk --stop by making mirror shared
Previously mirror is private and then unshared to zygote, which
makes magisk --stop cannot propagate umount mirror to zygote.
2023-12-22 21:39:03 +08:00
vvb2060
deedb462a0 Hide magisk internal mount point 2023-12-22 21:38:15 +08:00
igor
c48962bdf7 Update Portuguese translation 2023-12-22 01:31:55 +08:00
Wang Han
1ef3f6e13b Remove useless rule for prctl PR_SET_MM
* There is no use-case for it now.
2023-12-22 00:36:06 +08:00
topjohnwu
83a34a9004 Update emulator 2023-12-21 21:30:35 +08:00
topjohnwu
e30bda6c8d Rebase libsepol to AOSP main 2023-12-21 19:23:02 +08:00
vvb2060
00e9d76a5a Revert "Avoid doing any unmounts for SysUI" 2023-12-20 17:23:17 +08:00
LoveSy
6cda6c2fae Upgrade github action deps 2023-12-18 16:25:56 +08:00
VD $ VD171 @ Priv8
6dfda6dc39 Update Portuguese Translation 2023-12-18 16:24:14 +08:00
LoveSy
f41994cb52 Skip svc for ro properties
ro properties' triggers should only be triggered once, otherwise it
may undefined behaviour.
This patch avoids triggering ro properties' actions again when using
resetprop to modify them.

Co-authored-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com>
2023-12-18 16:21:08 +08:00
topjohnwu
a003336497 Update system_properties for pre Android 10 2023-12-18 16:21:08 +08:00
LoveSy
401090d6fe Avoid zygiskd restarts when boot-complete 2023-12-18 16:21:08 +08:00
LoveSy
90dcc1cd30 Do not always zero initialize for rust resize vec 2023-12-18 16:21:08 +08:00
LoveSy
2ac464b186 Only compress regular file 2023-12-18 16:21:08 +08:00
LoveSy
8b7fae278b Support compressing during cpio backup 2023-12-18 16:21:08 +08:00
topjohnwu
d73c2daf6d Use special emulator to make tests less flaky 2023-12-16 15:50:53 +08:00
topjohnwu
ca25935de3 Release new canary build 2023-12-14 03:21:22 +08:00
LoveSy
d7750b7220 uiautomator dump to /data/local/tmp 2023-12-13 03:28:30 +08:00
LoveSy
98861f0b5a Clone dir attr for tmpfs in advance 2023-12-13 03:28:30 +08:00
topjohnwu
e35925d520 Properly version zygisk APIs 2023-12-13 03:27:38 +08:00
Kieron Quinn
685a2d2101 Fixes for Android 14 QPR2 B2
Added new method signatures and arguments
2023-12-13 00:16:54 +08:00
LoveSy
f7e471616d Fix clone_attr for newly created dirs 2023-12-10 23:37:47 +08:00
残页
c013a349af Update install guide
- Remove boot vbmeta patching because the checkbox is removed in b1363ee
- Remove meaningless slot argument from `fastboot flash` as it will automatically flash the active slot. Fix #7571
2023-12-10 23:37:02 +08:00
topjohnwu
61ea59a27b API 34 AOSP ATD image is released 2023-12-08 17:59:24 +08:00
VD $ VD171 @ Priv8
e55f338367 Update Portuguese Translation 2023-12-08 17:03:48 +08:00
VD $ VD171 @ Priv8
1425cf4105 Update Portuguese Translation 2023-12-08 17:03:48 +08:00
topjohnwu
b493a985b0 Update dependencies 2023-12-08 17:03:18 +08:00
canyie
1fe9ede940 Update selinux to disable validation for policydb 2023-12-08 16:50:45 +08:00
LoveSy
1fd49e4987 Make tmpfs mount of magic mount atomic
This avoid system libraries disappear temporarily during magic mount,
which causes some dynamic executables fails to run during post-fs-data.
2023-12-08 13:59:02 +08:00
LoveSy
d49b02b274 Fix zygiskd not restart when zygote restarts 2023-12-07 20:44:44 +08:00
LoveSy
d47e70cfaa Fix native symbol strips
`ndkVersion` is also needed by app for striping native symbols.
Set it in `setupCommon` instead.
2023-12-04 00:37:09 +08:00
topjohnwu
40cb031af5 Release new canary build 2023-12-04 00:30:46 +08:00
topjohnwu
1dcf325547 Minor cleanup 2023-12-03 19:32:58 +08:00
LoveSy
4e99997013 Upgrade AGP 2023-12-02 15:25:58 +08:00
LoveSy
334554697d Enable rust parallel front-end
See https://blog.rust-lang.org/2023/11/09/parallel-rustc.html
2023-12-02 15:25:41 +08:00
LoveSy
e77cbd0c15 Upgrade gradle 2023-11-30 11:49:40 +08:00
topjohnwu
46ba008b9d Disable SCCACHE_DIRECT 2023-11-30 01:55:38 +08:00
LoveSy
58aded31c2 Enable iter_intersperse 2023-11-29 23:47:51 +08:00
LoveSy
6f6b0ade06 Correct cpio's norm_path 2023-11-29 23:47:51 +08:00
topjohnwu
d9b67a207b Update ONDK 2023-11-27 17:41:11 +08:00
topjohnwu
c7083659aa Directly guard boot state with mutex 2023-11-27 17:40:58 +08:00
topjohnwu
a6d1803105 Update dependencies 2023-11-26 23:09:20 +08:00
Re*Index. (ot_inc)
66eef75673 Update strings.xml 2023-11-26 22:54:53 +08:00
Alessandro Sangiorgi
367f5f7b44 Update italian translation
Co-authored-by: Francesco Saltori <francescosaltori@gmail.com>
2023-11-26 22:54:33 +08:00
topjohnwu
0edcb03c45 Update test API levels 2023-11-26 21:41:43 +08:00
canyie
63eef153de Warn about unsupported installation methods 2023-11-17 13:58:41 -08:00
canyie
68442f38ac Misc changes
- actions: Update all actions/checkout references to v4
- magiskboot: Add missing new line to dtb help message
- docs: Update documents, fix some errors and remove outdated info
2023-11-17 13:58:41 -08:00
topjohnwu
8d5b9e5329 C++/Rust 2 way binding for MagiskD 2023-11-17 13:35:50 -08:00
topjohnwu
6c0966b795 Move some global state into Rust 2023-11-16 15:38:38 -08:00
topjohnwu
7c2e93d266 Introduce owned_fd 2023-11-16 15:38:38 -08:00
topjohnwu
1ff7b9055f Add LSPosed launch test 2023-11-16 15:38:38 -08:00
topjohnwu
49f241b77c Allow running scripts with incomplete env 2023-11-10 00:55:05 -08:00
topjohnwu
cfb20b0f86 Zygisk refactoring part 2 2023-11-09 20:55:58 -08:00
topjohnwu
6d6f14fcb3 Use bitflags 2023-11-09 14:35:49 -08:00
topjohnwu
977c981265 Make sure native bridge is restored on daemon restart 2023-11-08 17:55:25 -08:00
topjohnwu
ef48abf19d Reorganize zygisk code 2023-11-08 17:46:39 -08:00
topjohnwu
65c18f9c09 Restructure project files 2023-11-08 01:46:02 -08:00
残页
ecb31eed40 Prevent Zygisk from closing new fds created by Zygote itself 2023-11-08 00:34:38 -08:00
topjohnwu
a80cadf587 Refactor hookJniNativeMethods
Utilize NativeBridgeRuntimeCallbacks we obtained from native bridge
to directly fetch and modify registered native JNI methods.
By doing so, we do not need to keep a copy of every single
JNINativeMethod registered in order to provide JNI hooking
functionality.

Co-authored-by: LoveSy <shana@zju.edu.cn>
2023-11-07 23:57:55 -08:00
LoveSy
fce1bf2365 Obtain NativeBridgeRuntimeCallbacks for future use
NativeBridgeRuntimeCallbacks can be used for better JNI method hooking

Co-authored-by: topjohnwu <topjohnwu@gmail.com>
2023-11-07 16:56:40 -08:00
LoveSy
cbc6d40b2c Clean up codes 2023-11-07 14:25:57 -08:00
LoveSy
9fbd079560 Refactor zygisk to use native bridge to inject
Co-authored-by: vvb2060 <vvb2060@gmail.com>
Co-authored-by: topjohnwu <topjohnwu@gmail.com>
2023-11-07 14:25:57 -08:00
LoveSy
42eb928054 Inject zygisk.rc for sync --zygisk-restart 2023-11-06 15:39:48 -08:00
topjohnwu
577483fde1 Release new canary build 2023-11-05 23:49:35 -08:00
topjohnwu
aa6c7c15cc Update README 2023-11-05 23:44:07 -08:00
topjohnwu
6c807d35b2 Release Magisk v26.4 2023-11-05 23:31:15 -08:00
topjohnwu
8ca8cdae97 Add v26.4 release notes 2023-11-05 23:07:53 -08:00
topjohnwu
75e37be6f3 Do not need to check pkg in magisk_env 2023-11-05 23:02:40 -08:00
WindowsFan9600
4985314ca6 Update language "tr" on main application 2023-11-05 22:37:39 -08:00
topjohnwu
ac5ceb18c8 Guard log FIFO with SELinux 2023-11-04 23:59:11 -07:00
topjohnwu
72b39594d3 Always close logd_fd during fork 2023-11-04 02:36:14 -07:00
topjohnwu
16ae4aedf1 Remove usage of MAGISKTMP 2023-11-02 15:50:36 -07:00
topjohnwu
3ba00858e6 Allow avd_magisk on API 28 2023-11-01 09:15:17 -07:00
topjohnwu
489100c755 Fix fd sanitization 2023-11-01 02:01:29 -07:00
topjohnwu
da766f2a4e Do not go through magiskd for getting the log pipe 2023-11-01 02:01:18 -07:00
topjohnwu
c81d7ff76c Remove unnecessary RefCell usage 2023-10-31 18:22:48 -07:00
topjohnwu
a6e50d3648 Make log pipe a FIFO instead of anonymous pipe 2023-10-31 18:05:22 -07:00
topjohnwu
a177846044 Better logging in recv_fds 2023-10-31 17:40:59 -07:00
topjohnwu
19a4e11645 Make tmpfs path static strings 2023-10-29 00:47:28 -07:00
topjohnwu
67cc36268e Simplify zygisk log pipe 2023-10-26 18:13:56 -07:00
topjohnwu
28770b9a32 Support baseline profiles 2023-10-26 15:56:51 -07:00
WindowsFan9600
9f92e1bf15 [STRINGS] Improve Turkish (tr) language 2023-10-26 15:23:35 -07:00
topjohnwu
23fe5d5a19 Update build.yml 2023-10-26 14:50:42 -07:00
LoveSy
9088b584f6 Use official argh 2023-10-25 15:14:16 -07:00
vvb2060
beaf636415 Use ccache for C code 2023-10-25 15:05:41 -07:00
vvb2060
09bb2fe8dc Update dependencies 2023-10-25 14:58:02 -07:00
tzagim
1d6747d90e Update Hebrew translation 2023-10-24 21:06:15 -07:00
南宫雪珊
efadd94de3 Update strings.xml 2023-10-24 21:02:32 -07:00
vvb2060
8c0b4e444a Update zh-rCN translation 2023-10-24 21:02:32 -07:00
Rom
32c7106e40 Update French translation 2023-10-24 21:01:53 -07:00
topjohnwu
d2f2a9e4c8 Make avd_test less flaky 2023-10-24 16:45:24 -07:00
topjohnwu
985454afd4 Better logging 2023-10-24 16:41:49 -07:00
topjohnwu
9e1322de25 Make sure the shared preference is committed 2023-10-24 16:41:38 -07:00
topjohnwu
4e4ec73d94 Make gradle.properties optional 2023-10-19 15:44:34 -07:00
topjohnwu
bb39a524d0 Switch to default images for faster boot time 2023-10-19 05:31:03 -07:00
topjohnwu
196d9af099 Add application and Zygisk tests to avd_test.sh 2023-10-19 05:15:53 -07:00
topjohnwu
1eeb2a34a1 Don't support alternative binary paths
The Magisk app will guide users through repair setup
2023-10-19 05:11:43 -07:00
Arbri çoçka
cf43c56218 Update strings.xml sq 2023-10-18 14:29:55 -07:00
kubalav
e6c1aec443 Update Slovak translation 2023-10-18 14:29:38 -07:00
topjohnwu
43fd1c4c1b Update stub version 2023-10-17 19:22:53 -07:00
topjohnwu
022caca979 Release new canary build 2023-10-17 19:13:16 -07:00
topjohnwu
0352ea2cca Rename biometrics to user authentication 2023-10-17 18:43:27 -07:00
topjohnwu
e483d6befe Do not go through a fragment for auth 2023-10-17 17:39:31 -07:00
vvb2060
678c07fff5 suBiometric: remove biometric
use device credential to support more devices and second user
2023-10-17 17:39:05 -07:00
topjohnwu
91c92051f1 Simplify C++ SELinux routines 2023-10-17 16:04:59 -07:00
topjohnwu
4b8a0388e7 Make SELinux support a feature 2023-10-17 13:29:15 -07:00
topjohnwu
66788dc58c Cleanup SELinux support 2023-10-16 17:38:44 -07:00
topjohnwu
dd8c28b1cb Upgrade AGP 2023-10-16 17:25:57 -07:00
残页
32c5153e8e Increase boot timeout to 600s 2023-10-16 01:20:25 -07:00
topjohnwu
36de62873a Fix error logging on the C++ side 2023-10-13 16:59:54 -07:00
topjohnwu
51e37880c6 Add repr(transparent) to guarantee soundness 2023-10-12 18:59:16 -07:00
topjohnwu
4b83c1e76c Cleanup messy error messages 2023-10-12 18:54:09 -07:00
topjohnwu
b0b04690d5 Use newer bash version for avd_test.sh 2023-10-12 00:45:53 -07:00
topjohnwu
6d1e8d86cb Cleaner cstr code 2023-10-11 23:53:55 -07:00
topjohnwu
eda8c70a80 Borrow value instead of moving in FsPath::from()
When accepting a value of AsRef<Utf8CStr> in FsPath::from(), the
existing code will move a value of Utf8CStrBufArr, creating a reference
that lives longer than the borrowing value, causing undefined behavior.

The issue is only visible on release builds, as more advanced
optimizations will be more aggressive re-using the stack of variables
that no longer lives.

Fix #7408
2023-10-11 23:48:54 -07:00
topjohnwu
587b6cfd41 Update avd_test.sh 2023-10-11 22:42:45 -07:00
topjohnwu
e774408782 Allow AVD hacks on release builds 2023-10-11 14:17:31 -07:00
canyie
187f583c95 Fix $RECOVERYMODE from config being incorrectly overridden
Move legacy SAR checking logic into mount_partitions, and avoid calling get_flags before check_boot_ramdisk
Fix #7346
2023-10-10 15:53:18 -07:00
topjohnwu
f5d3a71478 Update ONDK to r26.1 2023-10-10 15:52:59 -07:00
残页
d868ff3080 AVD test release builds as well 2023-10-10 15:52:41 -07:00
nkh0472
f80198a669 typo fix 2023-10-09 17:22:48 -07:00
topjohnwu
6076b52c48 Update libcxx 2023-10-03 17:22:25 -07:00
topjohnwu
79a1c39b30 Simplify fd sanitization 2023-09-28 20:38:16 -07:00
topjohnwu
5c92d39498 Enable Zygisk by default in emulators
Make sure CI tests Zygisk
2023-09-28 20:25:26 -07:00
topjohnwu
6e7a995716 Introduce UtfCString 2023-09-27 15:21:24 -07:00
topjohnwu
a55d570213 Move more I/O operations into Rust 2023-09-27 02:28:43 -07:00
topjohnwu
5d07d0b964 Do not support systems without SELinux 2023-09-27 02:28:43 -07:00
Wang Han
ec115cd7e3 Don't skip fd sanitization if fds_to_ignore does not exist 2023-09-25 09:45:03 -07:00
osm0sis
9b3896fd3d Retain PREINITDEVICE during A-only addon.d 2023-09-23 23:51:36 -07:00
topjohnwu
a3f5918d25 Fix bug in libsepol
Fix #7308
2023-09-23 22:34:51 -07:00
topjohnwu
b28326198c Use crates for cpio code 2023-09-22 01:39:21 -07:00
topjohnwu
46275b90c2 Generalize unxz 2023-09-21 05:47:21 -07:00
topjohnwu
15e13a8d8b Organize logging code 2023-09-19 03:02:30 -07:00
topjohnwu
b750c89c87 Address clippy warnings 2023-09-19 01:11:50 -07:00
LoveSy
8d7c7c3dfb Refactor dtb in rust 2023-09-19 00:41:42 -07:00
topjohnwu
8e1a91509c Remove readlink_unsafe 2023-09-19 00:06:21 -07:00
LoveSy
927cd571f8 Fix read_cert crash when receive fd = -1 2023-09-18 22:32:32 -07:00
LoveSy
5fbd3e5c65 Fix buf len update of read_link to Utf8CStrBuf 2023-09-18 22:31:12 -07:00
LoveSy
877aeb66cb Upgrade to Gradle 8.3 2023-09-14 13:16:59 -07:00
topjohnwu
8a88d8465a Prevent OOM
Fix #7341
2023-09-14 13:14:30 -07:00
topjohnwu
dda8cc85c9 Use bytemuck 2023-09-14 13:10:09 -07:00
topjohnwu
6a59939d9a Remove for_all_file 2023-09-13 18:09:16 -07:00
topjohnwu
4745e86c1b Fix #7301 2023-09-13 14:44:20 -07:00
topjohnwu
9aa466c773 Fix genfscon and filename_trans
Fix #7329
2023-09-12 21:31:31 -07:00
LoveSy
0243610c09 No trailing zeros if the signed boot img is larger 2023-09-12 18:09:20 -07:00
topjohnwu
0a2a590ab7 Use Utf8CStr for logging 2023-09-12 17:35:20 -07:00
topjohnwu
89aee6ffa7 Add more to the Utf8CStr family
Better C strings with path operations
2023-09-12 17:35:01 -07:00
topjohnwu
4eaf701cb7 Address clippy warnings 2023-09-06 21:45:12 -07:00
topjohnwu
4fff2aa7d8 Fix proto read and write 2023-09-06 20:45:59 -07:00
topjohnwu
35b3c8ba5c Cleanup persist props code 2023-09-06 15:52:14 -07:00
topjohnwu
1d7cff7703 Update Cargo dependencies 2023-09-06 13:57:43 -07:00
LoveSy
8d81bd0e33 resetprop: replace nanopb with quick-protobuf for persist 2023-09-05 22:20:57 -07:00
topjohnwu
7826d7527f Release new canary build 2023-09-04 00:35:17 -07:00
topjohnwu
d4e552d08b Update README 2023-09-04 00:26:48 -07:00
766 changed files with 27504 additions and 22092 deletions

6
.gitattributes vendored
View File

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

107
.github/actions/setup/action.yml vendored Normal file
View File

@@ -0,0 +1,107 @@
name: Magisk Setup
inputs:
is-asset-build:
required: false
default: false
runs:
using: "composite"
steps:
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "21"
- name: Set up Python 3
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install GNU make
if: runner.os == 'macOS'
shell: bash
run: |
brew install make
echo 'GNUMAKE=gmake' >> "$GITHUB_ENV"
- name: Cache sccache
uses: actions/cache@v4
if: ${{ github.event_name != 'pull_request' }}
with:
path: .sccache
key: sccache-${{ runner.os }}-${{ github.sha }}
restore-keys: sccache-${{ runner.os }}-
- name: Restore sccache
uses: actions/cache/restore@v4
if: ${{ github.event_name == 'pull_request' }}
with:
path: .sccache
key: sccache-${{ runner.os }}-${{ github.sha }}
restore-keys: sccache-${{ runner.os }}-
- name: Set up sccache
shell: bash
env:
SCCACHE_DIRECT: false
SCCACHE_DIR: ${{ github.workspace }}/.sccache
SCCACHE_CACHE_SIZE: ${{ inputs.is-asset-build == 'true' && '2G' || '300M' }}
SCCACHE_IDLE_TIMEOUT: 0
run: |
bash $GITHUB_ACTION_PATH/sccache.sh
sccache --start-server
sccache -z
- name: Show sccache stats
uses: gacts/run-and-post-run@v1
with:
run: sccache -s
post: sccache -s
- name: Set GRADLE_USER_HOME
shell: bash
run: echo "GRADLE_USER_HOME=$GITHUB_WORKSPACE/.gradle" >> "$GITHUB_ENV"
- name: Cache Gradle dependencies
uses: actions/cache@v4
if: ${{ inputs.is-asset-build == 'true' && github.event_name != 'pull_request' }}
with:
path: |
.gradle/caches
.gradle/wrapper
!.gradle/caches/build-cache-*
key: gradle-cache-${{ hashFiles('app/gradle/**') }}
restore-keys: gradle-cache-
- name: Restore Gradle dependencies
uses: actions/cache/restore@v4
if: ${{ inputs.is-asset-build == 'false' || github.event_name == 'pull_request' }}
with:
path: |
.gradle/caches
.gradle/wrapper
!.gradle/caches/build-cache-*
key: gradle-cache-${{ hashFiles('gradle/**') }}
restore-keys: gradle-cache-
enableCrossOsArchive: true
- name: Cache Gradle build cache
uses: actions/cache@v4
if: ${{ inputs.is-asset-build == 'true' && github.event_name != 'pull_request' }}
with:
path: .gradle/caches/build-cache-*
key: gradle-build-cache-${{ github.sha }}
restore-keys: gradle-build-cache-
- name: Restore Gradle build cache
uses: actions/cache/restore@v4
if: ${{ inputs.is-asset-build == 'false' || github.event_name == 'pull_request' }}
with:
path: .gradle/caches/build-cache-*
key: gradle-build-cache-${{ github.sha }}
restore-keys: gradle-build-cache-
enableCrossOsArchive: true
- name: Set up NDK
shell: bash
run: python build.py -v ndk

25
.github/actions/setup/sccache.sh vendored Executable file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env bash
# Get latest sccache version
get_sccache_ver() {
curl -sL 'https://api.github.com/repos/mozilla/sccache/releases/latest' | jq -r .name
}
# $1=variant
# $2=install_dir
# $3=exe
install_from_gh() {
local ver=$(curl -sL 'https://api.github.com/repos/mozilla/sccache/releases/latest' | jq -r .name)
local url="https://github.com/mozilla/sccache/releases/download/${ver}/sccache-${ver}-$1.tar.gz"
local dest="$2/$3"
curl -L "$url" | tar xz -O --wildcards "*/$3" > $dest
chmod +x $dest
}
if [ $RUNNER_OS = "macOS" ]; then
brew install sccache
elif [ $RUNNER_OS = "Linux" ]; then
install_from_gh x86_64-unknown-linux-musl /usr/local/bin sccache
elif [ $RUNNER_OS = "Windows" ]; then
install_from_gh x86_64-pc-windows-msvc $USERPROFILE/.cargo/bin sccache.exe
fi

1
.github/ci.prop vendored Normal file
View File

@@ -0,0 +1 @@
abiList=arm64-v8a

View File

@@ -6,10 +6,7 @@ on:
paths:
- "app/**"
- "native/**"
- "stub/**"
- "buildSrc/**"
- "build.py"
- "gradle.properties"
- ".github/workflows/build.yml"
pull_request:
branches: [master]
@@ -17,118 +14,191 @@ on:
jobs:
build:
name: Build on ${{ matrix.os }}
name: Build Magisk artifacts
runs-on: macos-15
strategy:
fail-fast: false
steps:
- name: Check out
uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Setup environment
uses: ./.github/actions/setup
with:
is-asset-build: true
- name: Build release
run: ./build.py -vr all
- name: Build debug
run: ./build.py -v all
- name: Stop gradle daemon
run: ./app/gradlew --stop
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: ${{ github.sha }}
path: out
compression-level: 9
- name: Upload mapping and native debug symbols
uses: actions/upload-artifact@v4
with:
name: ${{ github.sha }}-symbols
path: app/apk/build/outputs
compression-level: 9
test-build:
name: Test building on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [windows-2025, ubuntu-24.04]
steps:
- name: Check out
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: "recursive"
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: "temurin"
java-version: "17"
- name: Setup environment
uses: ./.github/actions/setup
- name: Set up Python 3
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Set up sccache
uses: hendrikmuhs/ccache-action@v1.2
with:
variant: sccache
key: ${{ runner.os }}-${{ github.sha }}
restore-keys: ${{ runner.os }}
max-size: 10000M
- name: Cache Gradle dependencies
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
!~/.gradle/caches/build-cache-*
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: ${{ runner.os }}-gradle-
- name: Cache build cache
uses: actions/cache@v3
with:
path: |
~/.gradle/caches/build-cache-*
key: ${{ runner.os }}-build-cache-${{ github.sha }}
restore-keys: ${{ runner.os }}-build-cache-
- name: Set up NDK
run: python build.py -v ndk
- name: Build release
run: |
python build.py -vr all
- name: Build debug
run: |
python build.py -v all
- name: Test build
run: python build.py -v -c .github/ci.prop all
- name: Stop gradle daemon
run: ./gradlew --stop
run: ./app/gradlew --stop
# Only upload artifacts built on Linux
- name: Upload build artifact
if: runner.os == 'Linux'
uses: actions/upload-artifact@v3
with:
name: ${{ github.sha }}
path: out
- name: Upload mapping and native debug symbols
if: runner.os == 'Linux'
uses: actions/upload-artifact@v3
with:
name: ${{ github.sha }}-symbols
path: app/build/outputs
test:
name: Test on ${{ matrix.api }}
runs-on: macos-latest
avd-test:
name: Test API ${{ matrix.version }} (x86_64)
runs-on: ubuntu-24.04
needs: build
if: ${{ github.event_name != 'push' }}
strategy:
fail-fast: false
matrix:
api: [23, 26, 28, 29, 34]
version: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, "36.0-CANARY"]
type: [""]
include:
- version: "36.0-CANARY"
type: "google_apis_ps16k"
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"
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: ${{ github.sha }}
path: out
- name: AVD test
- name: Enable KVM group perms
run: |
brew install coreutils
scripts/avd_test.sh ${{ matrix.api }}
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run AVD test
timeout-minutes: 10
env:
AVD_TEST_LOG: 1
run: scripts/avd.sh test ${{ matrix.version }} ${{ matrix.type }}
- name: Upload logs on error
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: "avd-logs-${{ matrix.version }}"
path: |
kernel.log
logcat.log
avd-test-32:
name: Test API ${{ matrix.version }} (x86)
runs-on: ubuntu-24.04
needs: build
if: ${{ github.event_name != 'push' }}
strategy:
fail-fast: false
matrix:
version: [23, 24, 25, 26, 27, 28, 29, 30]
steps:
- name: Check out
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: ${{ github.sha }}
path: out
- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run AVD test
timeout-minutes: 10
env:
FORCE_32_BIT: 1
AVD_TEST_LOG: 1
run: scripts/avd.sh test ${{ matrix.version }}
- name: Upload logs on error
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: "avd32-logs-${{ matrix.version }}"
path: |
kernel.log
logcat.log
cf-test:
name: Test ${{ matrix.device }}
runs-on: ubuntu-24.04
needs: build
if: ${{ github.event_name != 'push' }}
env:
CF_HOME: /home/runner/aosp_cf_phone
strategy:
fail-fast: false
matrix:
include:
- branch: "aosp-android-latest-release"
device: "aosp_cf_x86_64_only_phone"
steps:
- name: Check out
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: ${{ github.sha }}
path: out
- name: Setup Cuttlefish environment
run: |
scripts/cuttlefish.sh setup
scripts/cuttlefish.sh download ${{ matrix.branch }} ${{ matrix.device }}
- name: Run Cuttlefish test
timeout-minutes: 10
run: sudo -E -u $USER scripts/cuttlefish.sh test
- name: Upload logs on error
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: "cvd-logs-${{ matrix.device }}"
path: |
/home/runner/aosp_cf_phone/cuttlefish/instances/cvd-1/logs
/home/runner/aosp_cf_phone/cuttlefish/instances/cvd-1/cuttlefish_config.json

12
.gitignore vendored
View File

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

30
.gitmodules vendored
View File

@@ -1,39 +1,15 @@
[submodule "selinux"]
path = native/src/external/selinux
url = https://github.com/topjohnwu/selinux.git
[submodule "busybox"]
path = native/src/external/busybox
url = https://github.com/topjohnwu/ndk-busybox.git
[submodule "dtc"]
path = native/src/external/dtc
url = https://github.com/dgibson/dtc.git
[submodule "lz4"]
path = native/src/external/lz4
url = https://github.com/lz4/lz4.git
[submodule "bzip2"]
path = native/src/external/bzip2
url = https://github.com/nemequ/bzip2.git
[submodule "xz"]
path = native/src/external/xz
url = https://github.com/xz-mirror/xz.git
[submodule "nanopb"]
path = native/src/external/nanopb
url = https://github.com/nanopb/nanopb.git
[submodule "pcre"]
path = native/src/external/pcre
url = https://android.googlesource.com/platform/external/pcre
[submodule "libcxx"]
path = native/src/external/libcxx
url = https://github.com/topjohnwu/libcxx.git
[submodule "zlib"]
path = native/src/external/zlib
url = https://android.googlesource.com/platform/external/zlib
[submodule "parallel-hashmap"]
path = native/src/external/parallel-hashmap
url = https://github.com/greg7mdp/parallel-hashmap.git
[submodule "zopfli"]
path = native/src/external/zopfli
url = https://github.com/google/zopfli.git
[submodule "cxx-rs"]
path = native/src/external/cxx-rs
url = https://github.com/topjohnwu/cxx.git
@@ -43,6 +19,6 @@
[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
[submodule "crt0"]
path = native/src/external/crt0
url = https://github.com/topjohnwu/crt0.git

View File

@@ -16,18 +16,14 @@ Some highlight features:
## Downloads
[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-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)
[Github](https://github.com/topjohnwu/Magisk/releases) is the only source where you can get official Magisk information and downloads.
## 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/)
- [Zygisk module sample](https://github.com/topjohnwu/zygisk-module-sample)
## Bug Reports
@@ -41,8 +37,8 @@ For Magisk app crashes, record and upload the logcat when the crash occurs.
Default string resources for the Magisk app and its stub APK are located here:
- `app/src/main/res/values/strings.xml`
- `stub/src/main/res/values/strings.xml`
- `app/core/src/main/res/values/strings.xml`
- `app/stub/src/main/res/values/strings.xml`
Translate each and place them in the respective locations (`[module]/src/main/res/values-[lang]/strings.xml`).

12
app/.gitignore vendored
View File

@@ -1,11 +1,7 @@
*.iml
/dict.txt
# Gradle
.gradle
.kotlin
/local.properties
.idea/
/build
*.hprof
.externalNativeBuild/
*.apk
src/*/assets
src/*/jniLibs
src/*/resources

59
app/apk/build.gradle.kts Normal file
View File

@@ -0,0 +1,59 @@
plugins {
id("com.android.application")
kotlin("android")
kotlin("plugin.parcelize")
kotlin("kapt")
id("androidx.navigation.safeargs.kotlin")
}
setupMainApk()
kapt {
correctErrorTypes = true
useBuildCache = true
mapDiagnosticLocations = true
javacOptions {
option("-Xmaxerrs", "1000")
}
}
android {
buildFeatures {
dataBinding = true
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
}
}
}
dependencies {
implementation(project(":core"))
coreLibraryDesugaring(libs.jdk.libs)
implementation(libs.indeterminate.checkbox)
implementation(libs.rikka.layoutinflater)
implementation(libs.rikka.insets)
implementation(libs.rikka.recyclerview)
implementation(libs.navigation.fragment.ktx)
implementation(libs.navigation.ui.ktx)
implementation(libs.constraintlayout)
implementation(libs.swiperefreshlayout)
implementation(libs.recyclerview)
implementation(libs.transition)
implementation(libs.fragment.ktx)
implementation(libs.appcompat)
implementation(libs.material)
// Make sure kapt runs with a proper kotlin-stdlib
kapt(kotlin("stdlib"))
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application android:localeConfig="@xml/locale_config">
<activity
android:name=".ui.MainActivity"
android:exported="true"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".ui.surequest.SuRequestActivity"
android:directBootAware="true"
android:exported="false"
android:taskAffinity=""
tools:ignore="AppLinkUrlError">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,6 +1,8 @@
package com.topjohnwu.magisk.arch
import android.Manifest.permission.*
import android.Manifest.permission.POST_NOTIFICATIONS
import android.Manifest.permission.REQUEST_INSTALL_PACKAGES
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.databinding.PropertyChangeRegistry
@@ -8,7 +10,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.navigation.NavDirections
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.databinding.ObservableHost
import com.topjohnwu.magisk.events.BackPressEvent
import com.topjohnwu.magisk.events.DialogBuilder

View File

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

View File

@@ -1,11 +1,13 @@
package com.topjohnwu.magisk.arch
import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.res.use
import androidx.core.view.WindowCompat
@@ -18,14 +20,20 @@ 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 com.topjohnwu.magisk.core.base.ActivityExtension
import com.topjohnwu.magisk.core.base.IActivityExtension
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.reflectField
import com.topjohnwu.magisk.core.wrap
import rikka.insets.WindowInsetsHelper
import rikka.layoutinflater.view.LayoutInflaterFactory
abstract class UIActivity<Binding : ViewDataBinding> : BaseActivity(), ViewModelHolder {
abstract class UIActivity<Binding : ViewDataBinding>
: AppCompatActivity(), ViewModelHolder, IActivityExtension {
protected lateinit var binding: Binding
protected abstract val layoutRes: Int
override val extension = ActivityExtension(this)
protected val binded get() = ::binding.isInitialized
@@ -36,10 +44,23 @@ abstract class UIActivity<Binding : ViewDataBinding> : BaseActivity(), ViewModel
AppCompatDelegate.setDefaultNightMode(Config.darkTheme)
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.wrap())
}
override fun onCreate(savedInstanceState: Bundle?) {
layoutInflater.factory2 = LayoutInflaterFactory(delegate)
.addOnViewCreatedListener(WindowInsetsHelper.LISTENER)
extension.onCreate(savedInstanceState)
if (isRunningAsStub) {
// Overwrite private members to avoid nasty "false" stack traces being logged
val delegate = delegate
val clz = delegate.javaClass
clz.reflectField("mActivityHandlesConfigFlagsChecked").set(delegate, true)
clz.reflectField("mActivityHandlesConfigFlags").set(delegate, 0)
}
super.onCreate(savedInstanceState)
startObserveLiveData()
@@ -70,6 +91,11 @@ abstract class UIActivity<Binding : ViewDataBinding> : BaseActivity(), ViewModel
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
extension.onSaveInstanceState(outState)
}
fun setContentView() {
binding = DataBindingUtil.setContentView<Binding>(this, layoutRes).also {
it.setVariable(BR.viewModel, viewModel)

View File

@@ -8,7 +8,12 @@ import android.text.Spanned
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.*
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.Spinner
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.appcompat.widget.Toolbar
import androidx.cardview.widget.CardView
@@ -19,14 +24,21 @@ import androidx.core.widget.ImageViewCompat
import androidx.databinding.BindingAdapter
import androidx.databinding.InverseBindingAdapter
import androidx.databinding.InverseBindingListener
import androidx.databinding.InverseMethod
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.recyclerview.widget.*
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView
import com.google.android.material.chip.Chip
import com.google.android.material.slider.Slider
import com.google.android.material.textfield.TextInputLayout
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.superuser.internal.UiThreadHandler
import com.topjohnwu.widget.IndeterminateCheckBox
@@ -297,3 +309,38 @@ fun TextView.setText(text: TextHolder) {
fun Spinner.setAdapter(items: Array<Any>, layoutRes: Int) {
adapter = ArrayAdapter(context, layoutRes, items)
}
@BindingAdapter("labelFormatter")
fun Slider.setLabelFormatter(formatter: (Float) -> Int) {
setLabelFormatter { value -> resources.getString(formatter(value)) }
}
@InverseBindingAdapter(attribute = "android:value")
fun Slider.getValueBinding() = value
@BindingAdapter("android:valueAttrChanged")
fun Slider.setListener(attrChange: InverseBindingListener) {
addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
override fun onStartTrackingTouch(slider: Slider) = Unit
override fun onStopTrackingTouch(slider: Slider) = attrChange.onChange()
})
}
@InverseMethod("sliderValueToPolicy")
fun policyToSliderValue(policy: Int): Float {
return when (policy) {
SuPolicy.DENY -> 1f
SuPolicy.RESTRICT -> 2f
SuPolicy.ALLOW -> 3f
else -> 1f
}
}
fun sliderValueToPolicy(value: Float): Int {
return when (value) {
1f -> SuPolicy.DENY
2f -> SuPolicy.RESTRICT
3f -> SuPolicy.ALLOW
else -> SuPolicy.DENY
}
}

View File

@@ -3,7 +3,7 @@ package com.topjohnwu.magisk.databinding
import androidx.databinding.ListChangeRegistry
import androidx.databinding.ObservableList
import androidx.databinding.ObservableList.OnListChangedCallback
import java.util.*
import java.util.AbstractList
@Suppress("UNCHECKED_CAST")
class MergeObservableList<T> : AbstractList<T>(), ObservableList<T> {

View File

@@ -7,26 +7,27 @@ import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.core.R as CoreR
class DarkThemeDialog : DialogBuilder {
override fun build(dialog: MagiskDialog) {
val activity = dialog.ownerActivity!!
dialog.apply {
setTitle(R.string.settings_dark_mode_title)
setMessage(R.string.settings_dark_mode_message)
setTitle(CoreR.string.settings_dark_mode_title)
setMessage(CoreR.string.settings_dark_mode_message)
setButton(MagiskDialog.ButtonType.POSITIVE) {
text = R.string.settings_dark_mode_light
text = CoreR.string.settings_dark_mode_light
icon = R.drawable.ic_day
onClick { selectTheme(AppCompatDelegate.MODE_NIGHT_NO, activity) }
}
setButton(MagiskDialog.ButtonType.NEUTRAL) {
text = R.string.settings_dark_mode_system
text = CoreR.string.settings_dark_mode_system
icon = R.drawable.ic_day_night
onClick { selectTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, activity) }
}
setButton(MagiskDialog.ButtonType.NEGATIVE) {
text = R.string.settings_dark_mode_dark
text = CoreR.string.settings_dark_mode_dark
icon = R.drawable.ic_night
onClick { selectTheme(AppCompatDelegate.MODE_NIGHT_YES, activity) }
}

View File

@@ -1,14 +1,18 @@
package com.topjohnwu.magisk.dialog
import android.widget.Toast
import androidx.core.os.postDelayed
import androidx.lifecycle.lifecycleScope
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.ktx.reboot
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.ui.home.HomeViewModel
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.superuser.internal.UiThreadHandler
import kotlinx.coroutines.launch
class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : DialogBuilder {
@@ -27,10 +31,16 @@ class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : Dialo
resetButtons()
setCancelable(false)
}
(dialog.ownerActivity as BaseActivity).lifecycleScope.launch {
MagiskInstaller.FixEnv {
dialog.activity.lifecycleScope.launch {
MagiskInstaller.FixEnv().exec { success ->
dialog.dismiss()
}.exec()
context.toast(
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
Toast.LENGTH_LONG
)
if (success)
UiThreadHandler.handler.postDelayed(5000) { reboot() }
}
}
}
}
@@ -40,8 +50,8 @@ class EnvFixDialog(private val vm: HomeViewModel, private val code: Int) : Dialo
}
if (code == 2 || // No rules block, module policy not loaded
Info.env.versionCode != BuildConfig.VERSION_CODE ||
Info.env.versionString != BuildConfig.VERSION_NAME) {
Info.env.versionCode != BuildConfig.APP_VERSION_CODE ||
Info.env.versionString != BuildConfig.APP_VERSION_NAME) {
dialog.setMessage(R.string.env_full_fix_msg)
dialog.setButton(MagiskDialog.ButtonType.POSITIVE) {
text = android.R.string.ok

View File

@@ -2,8 +2,8 @@ package com.topjohnwu.magisk.dialog
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.R
import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.ui.module.ModuleViewModel
import com.topjohnwu.magisk.view.MagiskDialog

View File

@@ -1,25 +1,19 @@
package com.topjohnwu.magisk.dialog
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.download.DownloadEngine
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.view.MagiskDialog
import java.io.File
class ManagerInstallDialog : MarkDownDialog() {
private val svc get() = ServiceLocator.networkService
override suspend fun getMarkdownText(): String {
val text = svc.fetchString(Info.remote.magisk.note)
val text = Info.update.note
// Cache the changelog
AppContext.cacheDir.listFiles { _, name -> name.endsWith(".md") }.orEmpty().forEach {
it.delete()
}
File(AppContext.cacheDir, "${Info.remote.magisk.versionCode}.md").writeText(text)
File(AppContext.cacheDir, "${Info.update.versionCode}.md").writeText(text)
return text
}
@@ -29,7 +23,7 @@ class ManagerInstallDialog : MarkDownDialog() {
setCancelable(true)
setButton(MagiskDialog.ButtonType.POSITIVE) {
text = R.string.install
onClick { DownloadService.start(activity, Subject.App()) }
onClick { DownloadEngine.startWithActivity(activity, Subject.App()) }
}
setButton(MagiskDialog.ButtonType.NEGATIVE) {
text = android.R.string.cancel

View File

@@ -13,6 +13,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.IOException
import com.topjohnwu.magisk.core.R as CoreR
abstract class MarkDownDialog : DialogBuilder {
@@ -30,7 +31,7 @@ abstract class MarkDownDialog : DialogBuilder {
ServiceLocator.markwon.setMarkdown(tv, text)
} catch (e: IOException) {
Timber.e(e)
tv.setText(R.string.download_file_error)
tv.setText(CoreR.string.download_file_error)
}
}
}

View File

@@ -1,12 +1,15 @@
package com.topjohnwu.magisk.dialog
import com.topjohnwu.magisk.R
import android.content.Context
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.download.Action
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.DownloadEngine
import com.topjohnwu.magisk.core.download.Subject
import com.topjohnwu.magisk.core.model.module.OnlineModule
import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Notifications
import kotlinx.parcelize.Parcelize
class OnlineModuleInstallDialog(private val item: OnlineModule) : MarkDownDialog() {
@@ -17,14 +20,21 @@ class OnlineModuleInstallDialog(private val item: OnlineModule) : MarkDownDialog
return if (str.length > 1000) str.substring(0, 1000) else str
}
@Parcelize
class Module(
override val module: OnlineModule,
override val autoLaunch: Boolean,
override val notifyId: Int = Notifications.nextId()
) : Subject.Module() {
override fun pendingIntent(context: Context) = FlashFragment.installIntent(context, file)
}
override fun build(dialog: MagiskDialog) {
super.build(dialog)
dialog.apply {
fun download(install: Boolean) {
val action = if (install) Action.Flash else Action.Download
val subject = Subject.Module(item, action)
DownloadService.start(activity, subject)
DownloadEngine.startWithActivity(activity, Module(item, install))
}
val title = context.getString(R.string.repo_install_title,

View File

@@ -1,6 +1,6 @@
package com.topjohnwu.magisk.dialog
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.view.MagiskDialog

View File

@@ -1,6 +1,6 @@
package com.topjohnwu.magisk.dialog
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.view.MagiskDialog

View File

@@ -1,15 +1,17 @@
package com.topjohnwu.magisk.dialog
import android.app.ProgressDialog
import android.content.Context
import android.widget.Toast
import com.topjohnwu.magisk.R
import androidx.lifecycle.lifecycleScope
import com.topjohnwu.magisk.arch.NavigationActivity
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.events.DialogBuilder
import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
class UninstallDialog : DialogBuilder {
@@ -19,7 +21,7 @@ class UninstallDialog : DialogBuilder {
setMessage(R.string.uninstall_magisk_msg)
setButton(MagiskDialog.ButtonType.POSITIVE) {
text = R.string.restore_img
onClick { restore(dialog.context) }
onClick { restore(dialog.activity) }
}
setButton(MagiskDialog.ButtonType.NEGATIVE) {
text = R.string.complete_uninstall
@@ -29,18 +31,20 @@ class UninstallDialog : DialogBuilder {
}
@Suppress("DEPRECATION")
private fun restore(context: Context) {
val dialog = ProgressDialog(context).apply {
setMessage(context.getString(R.string.restore_img_msg))
private fun restore(activity: UIActivity<*>) {
val dialog = ProgressDialog(activity).apply {
setMessage(activity.getString(R.string.restore_img_msg))
show()
}
Shell.cmd("restore_imgs").submit { result ->
dialog.dismiss()
if (result.isSuccess) {
context.toast(R.string.restore_done, Toast.LENGTH_SHORT)
} else {
context.toast(R.string.restore_fail, Toast.LENGTH_LONG)
activity.lifecycleScope.launch {
MagiskInstaller.Restore().exec { success ->
dialog.dismiss()
if (success) {
activity.toast(R.string.restore_done, Toast.LENGTH_SHORT)
} else {
activity.toast(R.string.restore_fail, Toast.LENGTH_LONG)
}
}
}
}

View File

@@ -11,6 +11,7 @@ import com.topjohnwu.magisk.arch.NavigationActivity
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.core.base.ContentResultCallback
import com.topjohnwu.magisk.core.base.relaunch
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.view.MagiskDialog
@@ -47,7 +48,16 @@ class ShowUIEvent(private val delegate: View.AccessibilityDelegate?)
class RecreateEvent : ViewEvent(), ActivityExecutor {
override fun invoke(activity: UIActivity<*>) {
activity.recreate()
activity.relaunch()
}
}
class AuthEvent(
private val callback: () -> Unit
) : ViewEvent(), ActivityExecutor {
override fun invoke(activity: UIActivity<*>) {
activity.withAuthentication { if (it) callback() }
}
}

View File

@@ -1,6 +1,7 @@
package com.topjohnwu.magisk.ui
import android.Manifest
import android.Manifest.permission.REQUEST_INSTALL_PACKAGES
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.ApplicationInfo
@@ -8,6 +9,7 @@ import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import android.widget.Toast
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.view.forEach
import androidx.core.view.isGone
@@ -17,29 +19,35 @@ 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.NavigationActivity
import com.topjohnwu.magisk.arch.startAnimations
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.SplashController
import com.topjohnwu.magisk.core.base.SplashScreenHost
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.core.tasks.AppMigration
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
import com.topjohnwu.magisk.ui.home.HomeFragmentDirections
import com.topjohnwu.magisk.ui.theme.Theme
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Shortcuts
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import com.topjohnwu.magisk.core.R as CoreR
class MainViewModel : BaseViewModel()
class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
class MainActivity : NavigationActivity<ActivityMainMd2Binding>(), SplashScreenHost {
override val layoutRes = R.layout.activity_main_md2
override val viewModel by viewModel<MainViewModel>()
override val navHostId: Int = R.id.main_nav_host
override val splashController = SplashController(this)
override val snackbarView: View
get() {
val fragmentOverride = currentFragment?.snackbarView
@@ -57,12 +65,23 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
private var isRootFragment = true
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(Theme.selected.themeRes)
splashController.preOnCreate()
super.onCreate(savedInstanceState)
splashController.onCreate(savedInstanceState)
}
override fun onResume() {
super.onResume()
splashController.onResume()
}
@SuppressLint("InlinedApi")
override fun showMainUI(savedInstanceState: Bundle?) {
override fun onCreateUi(savedInstanceState: Bundle?) {
setContentView()
showUnsupportedMessage()
askForHomeShortcut()
checkStubComponent()
// Ask permission to post notifications for background update check
if (Config.checkUpdate) {
@@ -169,11 +188,36 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
}
}
@SuppressLint("InlinedApi")
override fun showInvalidStateMessage(): Unit = runOnUiThread {
MagiskDialog(this).apply {
setTitle(CoreR.string.unsupport_nonroot_stub_title)
setMessage(CoreR.string.unsupport_nonroot_stub_msg)
setButton(MagiskDialog.ButtonType.POSITIVE) {
text = CoreR.string.install
onClick {
withPermission(REQUEST_INSTALL_PACKAGES) {
if (!it) {
toast(CoreR.string.install_unknown_denied, Toast.LENGTH_SHORT)
showInvalidStateMessage()
} else {
lifecycleScope.launch {
AppMigration.restore(this@MainActivity)
}
}
}
}
}
setCancelable(false)
show()
}
}
private fun showUnsupportedMessage() {
if (Info.env.isUnsupported) {
MagiskDialog(this).apply {
setTitle(R.string.unsupport_magisk_title)
setMessage(R.string.unsupport_magisk_msg, Const.Version.MIN_VERSION)
setTitle(CoreR.string.unsupport_magisk_title)
setMessage(CoreR.string.unsupport_magisk_msg, Const.Version.MIN_VERSION)
setButton(MagiskDialog.ButtonType.POSITIVE) { text = android.R.string.ok }
setCancelable(false)
}.show()
@@ -184,8 +228,8 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
?.filterNot { File("$it/magisk").exists() }
?.any { File("$it/su").exists() } == true) {
MagiskDialog(this).apply {
setTitle(R.string.unsupport_general_title)
setMessage(R.string.unsupport_other_su_msg)
setTitle(CoreR.string.unsupport_general_title)
setMessage(CoreR.string.unsupport_other_su_msg)
setButton(MagiskDialog.ButtonType.POSITIVE) { text = android.R.string.ok }
setCancelable(false)
}.show()
@@ -193,8 +237,8 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
if (applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) {
MagiskDialog(this).apply {
setTitle(R.string.unsupport_general_title)
setMessage(R.string.unsupport_system_app_msg)
setTitle(CoreR.string.unsupport_general_title)
setMessage(CoreR.string.unsupport_system_app_msg)
setButton(MagiskDialog.ButtonType.POSITIVE) { text = android.R.string.ok }
setCancelable(false)
}.show()
@@ -202,8 +246,8 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
if (applicationInfo.flags and ApplicationInfo.FLAG_EXTERNAL_STORAGE != 0) {
MagiskDialog(this).apply {
setTitle(R.string.unsupport_general_title)
setMessage(R.string.unsupport_external_storage_msg)
setTitle(CoreR.string.unsupport_general_title)
setMessage(CoreR.string.unsupport_external_storage_msg)
setButton(MagiskDialog.ButtonType.POSITIVE) { text = android.R.string.ok }
setCancelable(false)
}.show()
@@ -216,8 +260,8 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
// Ask and show dialog
Config.askedHome = true
MagiskDialog(this).apply {
setTitle(R.string.add_shortcut_title)
setMessage(R.string.add_shortcut_msg)
setTitle(CoreR.string.add_shortcut_title)
setMessage(CoreR.string.add_shortcut_msg)
setButton(MagiskDialog.ButtonType.NEGATIVE) {
text = android.R.string.cancel
}
@@ -231,22 +275,4 @@ class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
}.show()
}
}
@SuppressLint("InlinedApi")
private fun checkStubComponent() {
if (intent.component?.className?.contains(HideAPK.PLACEHOLDER) == true) {
// The stub APK was not properly patched, re-apply our changes
withPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES) { granted ->
if (granted) {
lifecycleScope.launch(Dispatchers.IO) {
val apk = File(applicationInfo.sourceDir)
HideAPK.upgrade(this@MainActivity, apk)?.let {
startActivity(it)
}
}
}
}
}
}
}

View File

@@ -4,15 +4,20 @@ import android.annotation.SuppressLint
import android.content.pm.ApplicationInfo
import android.content.pm.ComponentInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.*
import android.content.pm.PackageManager.GET_ACTIVITIES
import android.content.pm.PackageManager.GET_PROVIDERS
import android.content.pm.PackageManager.GET_RECEIVERS
import android.content.pm.PackageManager.GET_SERVICES
import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS
import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
import android.content.pm.ServiceInfo
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 java.util.*
import java.util.Locale
import java.util.TreeSet
class CmdlineListItem(line: String) {
val packageName: String
@@ -97,7 +102,7 @@ class AppProcessInfo(
companion object {
private val comparator = compareBy<AppProcessInfo>(
{ it.label.lowercase(currentLocale) },
{ it.label.lowercase(Locale.ROOT) },
{ it.info.packageName }
)
}

View File

@@ -16,6 +16,7 @@ import com.topjohnwu.magisk.databinding.FragmentDenyMd2Binding
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
import com.topjohnwu.magisk.core.R as CoreR
class DenyListFragment : BaseFragment<FragmentDenyMd2Binding>(), MenuProvider {
@@ -26,7 +27,7 @@ class DenyListFragment : BaseFragment<FragmentDenyMd2Binding>(), MenuProvider {
override fun onStart() {
super.onStart()
activity?.setTitle(R.string.denylist)
activity?.setTitle(CoreR.string.denylist)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -58,7 +59,7 @@ class DenyListFragment : BaseFragment<FragmentDenyMd2Binding>(), MenuProvider {
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_deny_md2, menu)
searchView = menu.findItem(R.id.action_search).actionView as SearchView
searchView.queryHint = searchView.context.getString(R.string.hide_filter_hint)
searchView.queryHint = searchView.context.getString(CoreR.string.hide_filter_hint)
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
viewModel.query = query ?: ""

View File

@@ -6,7 +6,7 @@ import androidx.databinding.Bindable
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.core.AppContext
import com.topjohnwu.magisk.core.ktx.concurrentMap
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.databinding.filterList

View File

@@ -5,7 +5,11 @@ import android.content.Context
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Bundle
import android.view.*
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import androidx.navigation.NavDeepLinkBuilder
@@ -17,6 +21,7 @@ import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.cmp
import com.topjohnwu.magisk.databinding.FragmentFlashMd2Binding
import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.core.R as CoreR
class FlashFragment : BaseFragment<FragmentFlashMd2Binding>(), MenuProvider {
@@ -35,14 +40,14 @@ class FlashFragment : BaseFragment<FragmentFlashMd2Binding>(), MenuProvider {
override fun onStart() {
super.onStart()
activity?.setTitle(R.string.flash_screen_title)
activity?.setTitle(CoreR.string.flash_screen_title)
viewModel.state.observe(this) {
activity?.supportActionBar?.setSubtitle(
when (it) {
FlashViewModel.State.FLASHING -> R.string.flashing
FlashViewModel.State.SUCCESS -> R.string.done
FlashViewModel.State.FAILED -> R.string.failure
FlashViewModel.State.FLASHING -> CoreR.string.flashing
FlashViewModel.State.SUCCESS -> CoreR.string.done
FlashViewModel.State.FAILED -> CoreR.string.failure
}
)
if (it == FlashViewModel.State.SUCCESS && viewModel.showReboot) {
@@ -66,7 +71,7 @@ class FlashFragment : BaseFragment<FragmentFlashMd2Binding>(), MenuProvider {
super.onViewCreated(view, savedInstanceState)
defaultOrientation = activity?.requestedOrientation ?: -1
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED
if (savedInstanceState == null) {
viewModel.startFlashing()
}

View File

@@ -72,6 +72,7 @@ class FlashViewModel : BaseViewModel() {
MagiskInstaller.Direct(outItems, logItems).exec()
}
Const.Value.FLASH_INACTIVE_SLOT -> {
showReboot = false
MagiskInstaller.SecondSlot(outItems, logItems).exec()
}
Const.Value.PATCH_FILE -> {
@@ -104,7 +105,7 @@ class FlashViewModel : BaseViewModel() {
val name = "magisk_install_log_%s.log".format(
System.currentTimeMillis().toTime(timeFormatStandard)
)
val file = MediaStoreUtils.getFile(name, true)
val file = MediaStoreUtils.getFile(name)
file.uri.outputStream().bufferedWriter().use { writer ->
synchronized(logItems) {
logItems.forEach {

View File

@@ -3,6 +3,7 @@ package com.topjohnwu.magisk.ui.home
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.databinding.RvItem
import com.topjohnwu.magisk.core.R as CoreR
interface Dev {
val name: String
@@ -84,8 +85,8 @@ sealed class IconLink : RvItem() {
override val layoutRes get() = R.layout.item_icon_link
abstract class PayPal : IconLink(), Dev {
override val icon get() = R.drawable.ic_paypal
override val title get() = R.string.paypal
override val icon get() = CoreR.drawable.ic_paypal
override val title get() = CoreR.string.paypal
override val link get() = "https://paypal.me/$name"
object Project : PayPal() {
@@ -94,20 +95,20 @@ sealed class IconLink : RvItem() {
}
object Patreon : IconLink() {
override val icon get() = R.drawable.ic_patreon
override val title get() = R.string.patreon
override val icon get() = CoreR.drawable.ic_patreon
override val title get() = CoreR.string.patreon
override val link get() = Const.Url.PATREON_URL
}
abstract class Twitter : IconLink(), Dev {
override val icon get() = R.drawable.ic_twitter
override val title get() = R.string.twitter
override val icon get() = CoreR.drawable.ic_twitter
override val title get() = CoreR.string.twitter
override val link get() = "https://twitter.com/$name"
}
abstract class Github : IconLink() {
override val icon get() = R.drawable.ic_github
override val title get() = R.string.github
override val icon get() = CoreR.drawable.ic_github
override val title get() = CoreR.string.github
abstract class User : Github(), Dev {
override val link get() = "https://github.com/$name"
@@ -119,8 +120,8 @@ sealed class IconLink : RvItem() {
}
abstract class Sponsor : IconLink(), Dev {
override val icon get() = R.drawable.ic_favorite
override val title get() = R.string.github
override val icon get() = CoreR.drawable.ic_favorite
override val title get() = CoreR.string.github
override val link get() = "https://github.com/sponsors/$name"
}
}

View File

@@ -14,8 +14,11 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.download.DownloadEngine
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
import com.topjohnwu.magisk.core.R as CoreR
import androidx.navigation.findNavController
import com.topjohnwu.magisk.arch.NavigationActivity
class HomeFragment : BaseFragment<FragmentHomeMd2Binding>(), MenuProvider {
@@ -24,8 +27,8 @@ class HomeFragment : BaseFragment<FragmentHomeMd2Binding>(), MenuProvider {
override fun onStart() {
super.onStart()
activity?.setTitle(R.string.section_home)
DownloadService.observeProgress(this, viewModel::onProgressUpdate)
activity?.setTitle(CoreR.string.section_home)
DownloadEngine.observeProgress(this, viewModel::onProgressUpdate)
}
private fun checkTitle(text: TextView, icon: ImageView) {
@@ -67,7 +70,13 @@ class HomeFragment : BaseFragment<FragmentHomeMd2Binding>(), MenuProvider {
override fun onMenuItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_settings ->
HomeFragmentDirections.actionHomeFragmentToSettingsFragment().navigate()
activity?.let {
NavigationActivity.navigate(
HomeFragmentDirections.actionHomeFragmentToSettingsFragment(),
it.findNavController(R.id.main_nav_host),
it.contentResolver,
)
}
R.id.action_reboot -> activity?.let { RebootMenu.inflate(it).show() }
else -> return super.onOptionsItemSelected(item)
}

View File

@@ -7,13 +7,13 @@ import android.widget.Toast
import androidx.core.net.toUri
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.ActivityExecutor
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.arch.ContextExecutor
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.Subject
@@ -30,6 +30,7 @@ import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.superuser.Shell
import kotlin.math.roundToInt
import com.topjohnwu.magisk.core.R as CoreR
class HomeViewModel(
private val svc: NetworkService
@@ -52,7 +53,7 @@ class HomeViewModel(
get() = when {
Info.isRooted && Info.env.isUnsupported -> State.OUTDATED
!Info.env.isActive -> State.INVALID
Info.env.versionCode < BuildConfig.VERSION_CODE -> State.OUTDATED
Info.env.versionCode < BuildConfig.APP_VERSION_CODE -> State.OUTDATED
else -> State.UP_TO_DATE
}
@@ -65,15 +66,15 @@ class HomeViewModel(
if (isActive)
("$versionString ($versionCode)" + if (isDebug) " (D)" else "").asText()
else
R.string.not_available.asText()
CoreR.string.not_available.asText()
}
@get:Bindable
var managerRemoteVersion = R.string.loading.asText()
var managerRemoteVersion = CoreR.string.loading.asText()
set(value) = set(value, field, { field = it }, BR.managerRemoteVersion)
val managerInstalledVersion
get() = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})" +
get() = "${BuildConfig.APP_VERSION_NAME} (${BuildConfig.APP_VERSION_CODE})" +
if (BuildConfig.DEBUG) " (D)" else ""
@get:Bindable
@@ -90,19 +91,18 @@ class HomeViewModel(
override suspend fun doLoadWork() {
appState = State.LOADING
Info.getRemote(svc)?.apply {
Info.fetchUpdate(svc)?.apply {
appState = when {
BuildConfig.VERSION_CODE < magisk.versionCode -> State.OUTDATED
BuildConfig.APP_VERSION_CODE < versionCode -> State.OUTDATED
else -> State.UP_TO_DATE
}
val isDebug = Config.updateChannel == Config.Value.DEBUG_CHANNEL
managerRemoteVersion =
("${magisk.version} (${magisk.versionCode})" +
if (isDebug) " (D)" else "").asText()
("$version (${versionCode})" + if (isDebug) " (D)" else "").asText()
} ?: run {
appState = State.INVALID
managerRemoteVersion = R.string.not_available.asText()
managerRemoteVersion = CoreR.string.not_available.asText()
}
ensureEnv()
}
@@ -121,7 +121,7 @@ class HomeViewModel(
try {
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
context.toast(R.string.open_link_failed_toast, Toast.LENGTH_SHORT)
context.toast(CoreR.string.open_link_failed_toast, Toast.LENGTH_SHORT)
}
}
}.publish()
@@ -129,8 +129,8 @@ class HomeViewModel(
fun onDeletePressed() = UninstallDialog().show()
fun onManagerPressed() = when (appState) {
State.LOADING -> SnackbarEvent(R.string.loading).publish()
State.INVALID -> SnackbarEvent(R.string.no_connection).publish()
State.LOADING -> SnackbarEvent(CoreR.string.loading).publish()
State.INVALID -> SnackbarEvent(CoreR.string.no_connection).publish()
else -> withExternalRW {
withInstallPermission {
ManagerInstallDialog().show()

View File

@@ -1,5 +1,6 @@
package com.topjohnwu.magisk.ui.home
import android.app.Activity
import android.os.Build
import android.os.PowerManager
import android.view.ContextThemeWrapper
@@ -7,7 +8,8 @@ import android.view.MenuItem
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.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.ktx.reboot as systemReboot
object RebootMenu {
@@ -20,19 +22,30 @@ object RebootMenu {
R.id.action_reboot_download -> systemReboot("download")
R.id.action_reboot_edl -> systemReboot("edl")
R.id.action_reboot_recovery -> systemReboot("recovery")
R.id.action_reboot_safe_mode -> {
val status = !item.isChecked
item.isChecked = status
Config.bootloop = if (status) 2 else 0
}
else -> Unit
}
return true
}
fun inflate(activity: BaseActivity): PopupMenu {
fun inflate(activity: Activity): PopupMenu {
val themeWrapper = ContextThemeWrapper(activity, R.style.Foundation_PopupMenu)
val menu = PopupMenu(themeWrapper, activity.findViewById(R.id.action_reboot))
activity.menuInflater.inflate(R.menu.menu_reboot, menu.menu)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
activity.getSystemService<PowerManager>()?.isRebootingUserspaceSupported == true)
menu.menu.findItem(R.id.action_reboot_userspace).isVisible = true
menu.setOnMenuItemClickListener(RebootMenu::reboot)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
activity.getSystemService<PowerManager>()?.isRebootingUserspaceSupported == true) {
menu.menu.findItem(R.id.action_reboot_userspace).isVisible = true
}
if (Const.Version.atLeast_28_0()) {
menu.menu.findItem(R.id.action_reboot_safe_mode).isChecked = Config.bootloop >= 2
} else {
menu.menu.findItem(R.id.action_reboot_safe_mode).isVisible = false
}
return menu
}

View File

@@ -4,6 +4,7 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
import com.topjohnwu.magisk.core.R as CoreR
class InstallFragment : BaseFragment<FragmentInstallMd2Binding>() {
@@ -12,6 +13,6 @@ class InstallFragment : BaseFragment<FragmentInstallMd2Binding>() {
override fun onStart() {
super.onStart()
requireActivity().setTitle(R.string.install)
requireActivity().setTitle(CoreR.string.install)
}
}

View File

@@ -11,14 +11,13 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.BuildConfig.APP_VERSION_CODE
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.ContentResultCallback
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.repository.NetworkService
import com.topjohnwu.magisk.databinding.set
@@ -33,6 +32,7 @@ import kotlinx.parcelize.Parcelize
import timber.log.Timber
import java.io.File
import java.io.IOException
import com.topjohnwu.magisk.core.R as CoreR
class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel() {
@@ -69,17 +69,16 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
init {
viewModelScope.launch(Dispatchers.IO) {
try {
val file = File(AppContext.cacheDir, "${BuildConfig.VERSION_CODE}.md")
val text = when {
file.exists() -> file.readText()
Const.Url.CHANGELOG_URL.isEmpty() -> ""
val noteFile = File(AppContext.cacheDir, "${APP_VERSION_CODE}.md")
val noteText = when {
noteFile.exists() -> noteFile.readText()
else -> {
val str = svc.fetchString(Const.Url.CHANGELOG_URL)
file.writeText(str)
str
val note = svc.fetchUpdate(APP_VERSION_CODE).note
noteFile.writeText(note)
note
}
}
val spanned = markwon.toMarkdown(text)
val spanned = markwon.toMarkdown(noteText)
withContext(Dispatchers.Main) {
notes = spanned
}
@@ -99,13 +98,15 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
}
override fun onSaveState(state: Bundle) {
state.putParcelable(INSTALL_STATE_KEY, InstallState(
methodId,
step,
Config.keepVerity,
Config.keepEnc,
Config.recovery
))
state.putParcelable(
INSTALL_STATE_KEY, InstallState(
methodId,
step,
Config.keepVerity,
Config.keepEnc,
Config.recovery
)
)
}
override fun onRestoreState(state: Bundle) {
@@ -121,8 +122,9 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
@Parcelize
class UriCallback : ContentResultCallback {
override fun onActivityLaunch() {
AppContext.toast(R.string.patch_file_msg, Toast.LENGTH_LONG)
AppContext.toast(CoreR.string.patch_file_msg, Toast.LENGTH_LONG)
}
override fun onActivityResult(result: Uri) {
uri.value = result
}

View File

@@ -5,6 +5,7 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.HorizontalScrollView
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import com.topjohnwu.magisk.R
@@ -12,10 +13,12 @@ import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.utils.AccessibilityUtils
import com.topjohnwu.magisk.utils.MotionRevealHelper
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
import com.topjohnwu.magisk.core.R as CoreR
class LogFragment : BaseFragment<FragmentLogMd2Binding>(), MenuProvider {
@@ -41,7 +44,7 @@ class LogFragment : BaseFragment<FragmentLogMd2Binding>(), MenuProvider {
override fun onStart() {
super.onStart()
activity?.setTitle(R.string.logs)
activity?.setTitle(CoreR.string.logs)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -55,6 +58,11 @@ class LogFragment : BaseFragment<FragmentLogMd2Binding>(), MenuProvider {
addItemSpacing(R.dimen.l1, R.dimen.l_50, R.dimen.l1)
fixEdgeEffect()
}
if (!AccessibilityUtils.isAnimationEnabled(requireContext().contentResolver)) {
val scrollView = view.findViewById<HorizontalScrollView>(R.id.log_scroll_magisk)
scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER)
}
}

View File

@@ -4,10 +4,10 @@ import android.system.Os
import androidx.databinding.Bindable
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.R
import com.topjohnwu.magisk.core.ktx.timeFormatStandard
import com.topjohnwu.magisk.core.ktx.toTime
import com.topjohnwu.magisk.core.repository.LogRepository
@@ -69,7 +69,7 @@ class LogViewModel(
viewModelScope.launch(Dispatchers.IO) {
val filename = "magisk_log_%s.log".format(
System.currentTimeMillis().toTime(timeFormatStandard))
val logFile = MediaStoreUtils.getFile(filename, true)
val logFile = MediaStoreUtils.getFile(filename)
logFile.uri.outputStream().bufferedWriter().use { file ->
file.write("---Detected Device Info---\n\n")
file.write("isAB=${Info.isAB}\n")
@@ -93,7 +93,7 @@ class LogViewModel(
if (Info.env.isActive) file.write(magiskLogRaw)
file.write("\n---Manager Logs---\n")
file.write("${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})\n\n")
file.write("${BuildConfig.APP_VERSION_NAME} (${BuildConfig.APP_VERSION_CODE})\n\n")
ProcessBuilder("logcat", "-d").start()
.inputStream.reader().use { it.copyTo(file) }
}

View File

@@ -3,13 +3,14 @@ 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.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.core.R as CoreR
class SuLogRvItem(val log: SuLog) : ObservableRvItem(), DiffItem<SuLogRvItem> {
@@ -31,20 +32,20 @@ class SuLogRvItem(val log: SuLog) : ObservableRvItem(), DiffItem<SuLogRvItem> {
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)
val toUid = res.getString(CoreR.string.target_uid, log.toUid)
val fromPid = res.getString(CoreR.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)
val target = res.getString(CoreR.string.target_pid, pid)
sb.append(" $target")
}
if (log.context.isNotEmpty()) {
val context = res.getString(R.string.selinux_context, log.context)
val context = res.getString(CoreR.string.selinux_context, log.context)
sb.append("\n$context")
}
if (log.gids.isNotEmpty()) {
val gids = res.getString(R.string.supp_group, log.gids)
val gids = res.getString(CoreR.string.supp_group, log.gids)
sb.append("\n$gids")
}
sb.append("\n${log.command}")

View File

@@ -0,0 +1,108 @@
package com.topjohnwu.magisk.ui.module
import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewTreeObserver
import android.widget.Toast
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.databinding.FragmentActionMd2Binding
import com.topjohnwu.magisk.core.R as CoreR
class ActionFragment : BaseFragment<FragmentActionMd2Binding>(), MenuProvider {
override val layoutRes = R.layout.fragment_action_md2
override val viewModel by viewModel<ActionViewModel>()
override val snackbarView: View get() = binding.snackbarContainer
private var defaultOrientation = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.args = ActionFragmentArgs.fromBundle(requireArguments())
}
override fun onStart() {
super.onStart()
activity?.setTitle(viewModel.args.name)
binding.closeBtn.setOnClickListener {
activity?.onBackPressed()
}
viewModel.state.observe(this) {
if (it != ActionViewModel.State.RUNNING) {
binding.closeBtn.apply {
if (!this.isVisible) this.show()
if (!this.isFocused) this.requestFocus()
}
}
if (it != ActionViewModel.State.SUCCESS) return@observe
view?.viewTreeObserver?.addOnWindowFocusChangeListener(
object : ViewTreeObserver.OnWindowFocusChangeListener {
override fun onWindowFocusChanged(hasFocus: Boolean) {
if (hasFocus) return
view?.viewTreeObserver?.removeOnWindowFocusChangeListener(this)
view?.context?.apply {
toast(
getString(CoreR.string.done_action, viewModel.args.name),
Toast.LENGTH_SHORT
)
}
viewModel.back()
}
}
)
}
}
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_flash, menu)
}
override fun onMenuItemSelected(item: MenuItem): Boolean {
return viewModel.onMenuItemClicked(item)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
defaultOrientation = activity?.requestedOrientation ?: -1
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED
if (savedInstanceState == null) {
viewModel.startRunAction()
}
}
@SuppressLint("WrongConstant")
override fun onDestroyView() {
if (defaultOrientation != -1) {
activity?.requestedOrientation = defaultOrientation
}
super.onDestroyView()
}
override fun onKeyEvent(event: KeyEvent): Boolean {
return when (event.keyCode) {
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> true
else -> false
}
}
override fun onBackPressed(): Boolean {
if (viewModel.state.value == ActionViewModel.State.RUNNING) return true
return super.onBackPressed()
}
override fun onPreBind(binding: FragmentActionMd2Binding) = Unit
}

View File

@@ -0,0 +1,88 @@
package com.topjohnwu.magisk.ui.module
import android.view.MenuItem
import androidx.databinding.ObservableArrayList
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel
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.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ui.flash.ConsoleItem
import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.IOException
class ActionViewModel : BaseViewModel() {
enum class State {
RUNNING, SUCCESS, FAILED
}
private val _state = MutableLiveData(State.RUNNING)
val state: LiveData<State> get() = _state
val items = ObservableArrayList<ConsoleItem>()
lateinit var args: ActionFragmentArgs
private val logItems = mutableListOf<String>().synchronized()
private val outItems = object : CallbackList<String>() {
override fun onAddElement(e: String?) {
e ?: return
items.add(ConsoleItem(e))
logItems.add(e)
}
}
fun startRunAction() = viewModelScope.launch {
onResult(withContext(Dispatchers.IO) {
try {
Shell.cmd("run_action \'${args.id}\'")
.to(outItems, logItems)
.exec().isSuccess
} catch (e: IOException) {
Timber.e(e)
false
}
})
}
private fun onResult(success: Boolean) {
_state.value = if (success) State.SUCCESS else State.FAILED
}
fun onMenuItemClicked(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_save -> savePressed()
}
return true
}
private fun savePressed() = withExternalRW {
viewModelScope.launch(Dispatchers.IO) {
val name = "%s_action_log_%s.log".format(
args.name,
System.currentTimeMillis().toTime(timeFormatStandard)
)
val file = MediaStoreUtils.getFile(name)
file.uri.outputStream().bufferedWriter().use { writer ->
synchronized(logItems) {
logItems.forEach {
writer.write(it)
writer.newLine()
}
}
}
SnackbarEvent(file.toString()).publish()
}
}
}

View File

@@ -11,6 +11,7 @@ import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addInvalidateItemDecorationsObserver
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
import com.topjohnwu.magisk.core.R as CoreR
class ModuleFragment : BaseFragment<FragmentModuleMd2Binding>() {
@@ -19,7 +20,7 @@ class ModuleFragment : BaseFragment<FragmentModuleMd2Binding>() {
override fun onStart() {
super.onStart()
activity?.title = resources.getString(R.string.modules)
activity?.title = resources.getString(CoreR.string.modules)
viewModel.data.observe(this) {
it ?: return@observe
val displayName = runCatching { it.displayName }.getOrNull() ?: return@observe

View File

@@ -12,6 +12,7 @@ import com.topjohnwu.magisk.databinding.RvItem
import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.core.R as CoreR
object InstallModule : RvItem(), DiffItem<InstallModule> {
override val layoutRes = R.layout.item_module_download
@@ -24,6 +25,7 @@ class LocalModuleRvItem(
override val layoutRes = R.layout.item_module_md2
val showNotice: Boolean
val showAction: Boolean
val noticeText: TextHolder
init {
@@ -34,11 +36,12 @@ class LocalModuleRvItem(
showNotice = zygiskUnloaded ||
(Info.isZygiskEnabled && isRiru) ||
(!Info.isZygiskEnabled && isZygisk)
showAction = item.hasAction && !showNotice
noticeText =
when {
zygiskUnloaded -> R.string.zygisk_module_unloaded.asText()
isRiru -> R.string.suspend_text_riru.asText(R.string.zygisk.asText())
else -> R.string.suspend_text_zygisk.asText(R.string.zygisk.asText())
zygiskUnloaded -> CoreR.string.zygisk_module_unloaded.asText()
isRiru -> CoreR.string.suspend_text_riru.asText(CoreR.string.zygisk.asText())
else -> CoreR.string.suspend_text_zygisk.asText(CoreR.string.zygisk.asText())
}
}

View File

@@ -4,8 +4,10 @@ import android.net.Uri
import androidx.databinding.Bindable
import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.MainDirections
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.base.ContentResultCallback
import com.topjohnwu.magisk.core.model.module.LocalModule
@@ -22,6 +24,7 @@ import com.topjohnwu.magisk.events.SnackbarEvent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
import com.topjohnwu.magisk.core.R as CoreR
class ModuleViewModel : AsyncLoadViewModel() {
@@ -77,7 +80,7 @@ class ModuleViewModel : AsyncLoadViewModel() {
if (item != null && Info.isConnected.value == true) {
withExternalRW { OnlineModuleInstallDialog(item).show() }
} else {
SnackbarEvent(R.string.no_connection).publish()
SnackbarEvent(CoreR.string.no_connection).publish()
}
fun installPressed() = withExternalRW {
@@ -95,6 +98,10 @@ class ModuleViewModel : AsyncLoadViewModel() {
}
}
fun runAction(id: String, name: String) {
MainDirections.actionActionFragment(id, name).navigate()
}
companion object {
private val uri = MutableLiveData<Uri?>()
}

View File

@@ -14,29 +14,34 @@ import com.topjohnwu.magisk.view.MagiskDialog
sealed class BaseSettingsItem : ObservableRvItem() {
interface Handler {
fun onItemPressed(view: View, item: BaseSettingsItem, andThen: () -> Unit)
fun onItemAction(view: View, item: BaseSettingsItem)
}
override val layoutRes get() = R.layout.item_settings
open val icon: Int get() = 0
open val title: TextHolder get() = TextHolder.EMPTY
@get:Bindable
open val description: TextHolder get() = TextHolder.EMPTY
open val showSwitch get() = false
@get:Bindable
open val isChecked get() = false
@get:Bindable
var isEnabled = true
set(value) = set(value, field, { field = it }, BR.enabled, BR.description)
open fun onToggle(view: View, handler: Handler, checked: Boolean) {}
open fun onPressed(view: View, handler: Handler) {
handler.onItemPressed(view, this)
handler.onItemPressed(view, this) {
handler.onItemAction(view, this)
}
}
open fun refresh() {}
interface Handler {
fun onItemPressed(view: View, item: BaseSettingsItem, andThen: () -> Unit = {})
fun onItemAction(view: View, item: BaseSettingsItem)
}
// Only for toggle
open val showSwitch get() = false
@get:Bindable
open val isChecked get() = false
fun onToggle(view: View, handler: Handler, checked: Boolean) =
set(checked, isChecked, { onPressed(view, handler) })
abstract class Value<T> : BaseSettingsItem() {
@@ -54,9 +59,6 @@ sealed class BaseSettingsItem : ObservableRvItem() {
override val showSwitch get() = true
override val isChecked get() = value
override fun onToggle(view: View, handler: Handler, checked: Boolean) =
set(checked, value, { onPressed(view, handler) })
override fun onPressed(view: View, handler: Handler) {
// Make sure the checked state is synced
notifyPropertyChanged(BR.checked)
@@ -140,5 +142,4 @@ sealed class BaseSettingsItem : ObservableRvItem() {
abstract class Section : BaseSettingsItem() {
override val layoutRes = R.layout.item_settings_section
}
}

View File

@@ -9,6 +9,7 @@ import com.topjohnwu.magisk.databinding.FragmentSettingsMd2Binding
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
import com.topjohnwu.magisk.core.R as CoreR
class SettingsFragment : BaseFragment<FragmentSettingsMd2Binding>() {
@@ -19,7 +20,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsMd2Binding>() {
override fun onStart() {
super.onStart()
activity?.title = resources.getString(R.string.settings)
activity?.title = resources.getString(CoreR.string.settings)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@@ -7,82 +7,70 @@ import android.view.LayoutInflater
import android.view.View
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.BuildConfig
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.tasks.AppMigration
import com.topjohnwu.magisk.core.utils.LocaleSetting
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.availableLocales
import com.topjohnwu.magisk.core.utils.currentLocale
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.utils.TextHolder
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import com.topjohnwu.magisk.core.R as CoreR
// --- Customization
object Customization : BaseSettingsItem.Section() {
override val title = R.string.settings_customization.asText()
override val title = CoreR.string.settings_customization.asText()
}
object Language : BaseSettingsItem.Selector() {
private val names: Array<String> get() = LocaleSetting.available.names
private val tags: Array<String> get() = LocaleSetting.available.tags
override var value
get() = index
get() = tags.indexOf(Config.locale)
set(value) {
index = value
Config.locale = entryValues[value]
Config.locale = tags[value]
}
override val title = R.string.language.asText()
override val title = CoreR.string.language.asText()
private var entries = emptyArray<String>()
private var entryValues = emptyArray<String>()
private var index = -1
override fun entries(res: Resources) = names
override fun descriptions(res: Resources) = names
}
override fun entries(res: Resources) = entries
override fun descriptions(res: Resources) = entries
override fun onPressed(view: View, handler: Handler) {
if (entries.isNotEmpty())
super.onPressed(view, handler)
}
suspend fun loadLanguages(scope: CoroutineScope) {
scope.launch {
availableLocales().let { (names, values) ->
entries = names
entryValues = values
val selectedLocale = currentLocale.getDisplayName(currentLocale)
index = names.indexOfFirst { it == selectedLocale }.let { if (it == -1) 0 else it }
notifyPropertyChanged(BR.description)
}
object LanguageSystem : BaseSettingsItem.Blank() {
override val title = CoreR.string.language.asText()
override val description: TextHolder
get() {
val locale = LocaleSetting.instance.appLocale
return locale?.getDisplayName(locale)?.asText() ?: CoreR.string.system_default.asText()
}
}
}
object Theme : BaseSettingsItem.Blank() {
override val icon = R.drawable.ic_paint
override val title = R.string.section_theme.asText()
override val title = CoreR.string.section_theme.asText()
}
// --- App
object AppSettings : BaseSettingsItem.Section() {
override val title = R.string.home_app_title.asText()
override val title = CoreR.string.home_app_title.asText()
}
object Hide : BaseSettingsItem.Input() {
override val title = R.string.settings_hide_app_title.asText()
override val description = R.string.settings_hide_app_summary.asText()
override val title = CoreR.string.settings_hide_app_title.asText()
override val description = CoreR.string.settings_hide_app_summary.asText()
override var value = ""
override val inputResult
@@ -93,7 +81,7 @@ object Hide : BaseSettingsItem.Input() {
set(value) = set(value, field, { field = it }, BR.result, BR.error)
val maxLength
get() = HideAPK.MAX_LABEL_LENGTH
get() = AppMigration.MAX_LABEL_LENGTH
@get:Bindable
val isError
@@ -104,14 +92,14 @@ object Hide : BaseSettingsItem.Input() {
}
object Restore : BaseSettingsItem.Blank() {
override val title = R.string.settings_restore_app_title.asText()
override val description = R.string.settings_restore_app_summary.asText()
override val title = CoreR.string.settings_restore_app_title.asText()
override val description = CoreR.string.settings_restore_app_summary.asText()
override fun onPressed(view: View, handler: Handler) {
handler.onItemPressed(view, this) {
MagiskDialog(view.activity).apply {
setTitle(R.string.settings_restore_app_title)
setMessage(R.string.restore_app_confirmation)
setTitle(CoreR.string.settings_restore_app_title)
setMessage(CoreR.string.restore_app_confirmation)
setButton(MagiskDialog.ButtonType.POSITIVE) {
text = android.R.string.ok
onClick {
@@ -129,8 +117,8 @@ object Restore : BaseSettingsItem.Blank() {
}
object AddShortcut : BaseSettingsItem.Blank() {
override val title = R.string.add_shortcut_title.asText()
override val description = R.string.setting_add_shortcut_summary.asText()
override val title = CoreR.string.add_shortcut_title.asText()
override val description = CoreR.string.setting_add_shortcut_summary.asText()
}
object DownloadPath : BaseSettingsItem.Input() {
@@ -141,7 +129,7 @@ object DownloadPath : BaseSettingsItem.Input() {
notifyPropertyChanged(BR.description)
}
override val title = R.string.settings_download_path_title.asText()
override val title = CoreR.string.settings_download_path_title.asText()
override val description get() = MediaStoreUtils.fullPath(value).asText()
override var inputResult: String = value
@@ -159,29 +147,21 @@ object UpdateChannel : BaseSettingsItem.Selector() {
get() = Config.updateChannel
set(value) {
Config.updateChannel = value
Info.remote = Info.EMPTY_REMOTE
Info.resetUpdate()
}
override val title = R.string.settings_update_channel_title.asText()
override val entryRes = R.array.update_channel
override fun entries(res: Resources): Array<String> {
return super.entries(res).let {
if (!Const.APP_IS_CANARY && !BuildConfig.DEBUG)
it.copyOfRange(0, Config.Value.CANARY_CHANNEL)
else it
}
}
override val title = CoreR.string.settings_update_channel_title.asText()
override val entryRes = CoreR.array.update_channel
}
object UpdateChannelUrl : BaseSettingsItem.Input() {
override val title = R.string.settings_update_custom.asText()
override val title = CoreR.string.settings_update_custom.asText()
override val description get() = value.asText()
override var value
get() = Config.customChannelUrl
set(value) {
Config.customChannelUrl = value
Info.remote = Info.EMPTY_REMOTE
Info.resetUpdate()
notifyPropertyChanged(BR.description)
}
@@ -197,56 +177,51 @@ object UpdateChannelUrl : BaseSettingsItem.Input() {
}
object UpdateChecker : BaseSettingsItem.Toggle() {
override val title = R.string.settings_check_update_title.asText()
override val description = R.string.settings_check_update_summary.asText()
override val title = CoreR.string.settings_check_update_title.asText()
override val description = CoreR.string.settings_check_update_summary.asText()
override var value by Config::checkUpdate
}
object DoHToggle : BaseSettingsItem.Toggle() {
override val title = R.string.settings_doh_title.asText()
override val description = R.string.settings_doh_description.asText()
override val title = CoreR.string.settings_doh_title.asText()
override val description = CoreR.string.settings_doh_description.asText()
override var value by Config::doh
}
object SystemlessHosts : BaseSettingsItem.Blank() {
override val title = R.string.settings_hosts_title.asText()
override val description = R.string.settings_hosts_summary.asText()
override val title = CoreR.string.settings_hosts_title.asText()
override val description = CoreR.string.settings_hosts_summary.asText()
}
object RandNameToggle : BaseSettingsItem.Toggle() {
override val title = CoreR.string.settings_random_name_title.asText()
override val description = CoreR.string.settings_random_name_description.asText()
override var value by Config::randName
}
// --- Magisk
object Magisk : BaseSettingsItem.Section() {
override val title = R.string.magisk.asText()
override val title = CoreR.string.magisk.asText()
}
object Zygisk : BaseSettingsItem.Toggle() {
override val title = R.string.zygisk.asText()
override val title = CoreR.string.zygisk.asText()
override val description get() =
if (mismatch) R.string.reboot_apply_change.asText()
else R.string.settings_zygisk_summary.asText()
if (mismatch) CoreR.string.reboot_apply_change.asText()
else CoreR.string.settings_zygisk_summary.asText()
override var value
get() = Config.zygisk
set(value) {
Config.zygisk = value
DenyList.isEnabled = value
DenyListConfig.isEnabled = value
notifyPropertyChanged(BR.description)
DenyList.notifyPropertyChanged(BR.description)
}
val mismatch get() = value != Info.isZygiskEnabled
}
object DenyList : BaseSettingsItem.Toggle() {
override val title = R.string.settings_denylist_title.asText()
override val description get() =
if (isEnabled) {
if (Zygisk.mismatch)
R.string.reboot_apply_change.asText()
else
R.string.settings_denylist_summary.asText()
} else {
R.string.settings_denylist_error.asText(R.string.zygisk.asText())
}
override val title = CoreR.string.settings_denylist_title.asText()
override val description get() = CoreR.string.settings_denylist_summary.asText()
override var value = Config.denyList
set(value) {
@@ -261,59 +236,48 @@ object DenyList : BaseSettingsItem.Toggle() {
}
}
}
override fun refresh() {
isEnabled = Zygisk.value
}
}
object DenyListConfig : BaseSettingsItem.Blank() {
override val title = R.string.settings_denylist_config_title.asText()
override val description = R.string.settings_denylist_config_summary.asText()
override fun refresh() {
isEnabled = Zygisk.value
}
override val title = CoreR.string.settings_denylist_config_title.asText()
override val description = CoreR.string.settings_denylist_config_summary.asText()
}
// --- Superuser
object Tapjack : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_tapjack_title.asText()
override val description = R.string.settings_su_tapjack_summary.asText()
override val title = CoreR.string.settings_su_tapjack_title.asText()
override val description = CoreR.string.settings_su_tapjack_summary.asText()
override var value by Config::suTapjack
}
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
get() = ServiceLocator.biometrics.isEnabled
set(value) {
Config.suBiometric = value
}
object Authentication : BaseSettingsItem.Toggle() {
override val title = CoreR.string.settings_su_auth_title.asText()
override var description = CoreR.string.settings_su_auth_summary.asText()
override var value by Config::suAuth
override fun refresh() {
isEnabled = ServiceLocator.biometrics.isSupported
isEnabled = Info.isDeviceSecure
if (!isEnabled) {
description = R.string.no_biometric.asText()
description = CoreR.string.settings_su_auth_insecure.asText()
}
}
}
object Superuser : BaseSettingsItem.Section() {
override val title = R.string.superuser.asText()
override val title = CoreR.string.superuser.asText()
}
object AccessMode : BaseSettingsItem.Selector() {
override val title = R.string.superuser_access.asText()
override val entryRes = R.array.su_access
override val title = CoreR.string.superuser_access.asText()
override val entryRes = CoreR.array.su_access
override var value by Config::rootMode
}
object MultiuserMode : BaseSettingsItem.Selector() {
override val title = R.string.multiuser_mode.asText()
override val entryRes = R.array.multiuser_mode
override val descriptionRes = R.array.multiuser_summary
override val title = CoreR.string.multiuser_mode.asText()
override val entryRes = CoreR.array.multiuser_mode
override val descriptionRes = CoreR.array.multiuser_summary
override var value by Config::suMultiuserMode
override fun refresh() {
@@ -322,21 +286,21 @@ object MultiuserMode : BaseSettingsItem.Selector() {
}
object MountNamespaceMode : BaseSettingsItem.Selector() {
override val title = R.string.mount_namespace_mode.asText()
override val entryRes = R.array.namespace
override val descriptionRes = R.array.namespace_summary
override val title = CoreR.string.mount_namespace_mode.asText()
override val entryRes = CoreR.array.namespace
override val descriptionRes = CoreR.array.namespace_summary
override var value by Config::suMntNamespaceMode
}
object AutomaticResponse : BaseSettingsItem.Selector() {
override val title = R.string.auto_response.asText()
override val entryRes = R.array.auto_response
override val title = CoreR.string.auto_response.asText()
override val entryRes = CoreR.array.auto_response
override var value by Config::suAutoResponse
}
object RequestTimeout : BaseSettingsItem.Selector() {
override val title = R.string.request_timeout.asText()
override val entryRes = R.array.request_timeout
override val title = CoreR.string.request_timeout.asText()
override val entryRes = CoreR.array.request_timeout
private val entryValues = listOf(10, 15, 20, 30, 45, 60)
override var value = entryValues.indexOfFirst { it == Config.suDefaultTimeout }
@@ -347,17 +311,23 @@ object RequestTimeout : BaseSettingsItem.Selector() {
}
object SUNotification : BaseSettingsItem.Selector() {
override val title = R.string.superuser_notification.asText()
override val entryRes = R.array.su_notification
override val title = CoreR.string.superuser_notification.asText()
override val entryRes = CoreR.array.su_notification
override var value by Config::suNotification
}
object Reauthenticate : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_reauth_title.asText()
override val description = R.string.settings_su_reauth_summary.asText()
override val title = CoreR.string.settings_su_reauth_title.asText()
override val description = CoreR.string.settings_su_reauth_summary.asText()
override var value by Config::suReAuth
override fun refresh() {
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Info.showSuperUser
isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O
}
}
object Restrict : BaseSettingsItem.Toggle() {
override val title = CoreR.string.settings_su_restrict_title.asText()
override val description = CoreR.string.settings_su_restrict_summary.asText()
override var value by Config::suRestrict
}

View File

@@ -1,26 +1,32 @@
package com.topjohnwu.magisk.ui.settings
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.view.View
import android.widget.Toast
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.BuildConfig
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.R
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.core.tasks.AppMigration
import com.topjohnwu.magisk.core.utils.LocaleSetting
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.BiometricEvent
import com.topjohnwu.magisk.events.AuthEvent
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
@@ -30,20 +36,14 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
it.put(BR.handler, this)
}
init {
viewModelScope.launch {
Language.loadLanguages(this)
}
}
private fun createItems(): List<BaseSettingsItem> {
val context = AppContext
val hidden = context.packageName != BuildConfig.APPLICATION_ID
val hidden = context.packageName != BuildConfig.APP_PACKAGE_NAME
// Customization
val list = mutableListOf(
Customization,
Theme, Language
Theme, if (LocaleSetting.useLocaleManager) LanguageSystem else Language
)
if (isRunningAsStub && ShortcutManagerCompat.isRequestPinShortcutSupported(context))
list.add(AddShortcut)
@@ -51,7 +51,7 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
// Manager
list.addAll(listOf(
AppSettings,
UpdateChannel, UpdateChannelUrl, DoHToggle, UpdateChecker, DownloadPath
UpdateChannel, UpdateChannelUrl, DoHToggle, UpdateChecker, DownloadPath, RandNameToggle
))
if (Info.env.isActive && Const.USER_ID == 0) {
if (hidden) list.add(Restore) else list.add(Hide)
@@ -72,7 +72,7 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
if (Info.showSuperUser) {
list.addAll(listOf(
Superuser,
Tapjack, Biometrics, AccessMode, MultiuserMode, MountNamespaceMode,
Tapjack, Authentication, AccessMode, MultiuserMode, MountNamespaceMode,
AutomaticResponse, RequestTimeout, SUNotification
))
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
@@ -83,35 +83,45 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
// Can hide overlay windows on 12.0+
list.remove(Tapjack)
}
if (Const.Version.atLeast_30_1()) {
list.add(Restrict)
}
}
return list
}
override fun onItemPressed(view: View, item: BaseSettingsItem, andThen: () -> Unit) {
override fun onItemPressed(view: View, item: BaseSettingsItem, doAction: () -> Unit) {
when (item) {
DownloadPath -> withExternalRW(andThen)
UpdateChecker -> withPostNotificationPermission(andThen)
Biometrics -> authenticate(andThen)
Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().navigate()
DenyListConfig -> SettingsFragmentDirections.actionSettingsFragmentToDenyFragment().navigate()
SystemlessHosts -> createHosts()
Hide, Restore -> withInstallPermission(andThen)
AddShortcut -> AddHomeIconEvent().publish()
else -> andThen()
DownloadPath -> withExternalRW(doAction)
UpdateChecker -> withPostNotificationPermission(doAction)
Authentication -> AuthEvent(doAction).publish()
AutomaticResponse -> if (Config.suAuth) AuthEvent(doAction).publish() else doAction()
else -> doAction()
}
}
override fun onItemAction(view: View, item: BaseSettingsItem) {
when (item) {
Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().navigate()
LanguageSystem -> launchAppLocaleSettings(view.activity)
AddShortcut -> AddHomeIconEvent().publish()
SystemlessHosts -> createHosts()
DenyListConfig -> SettingsFragmentDirections.actionSettingsFragmentToDenyFragment().navigate()
UpdateChannel -> openUrlIfNecessary(view)
is Hide -> viewModelScope.launch { HideAPK.hide(view.activity, item.value) }
Restore -> viewModelScope.launch { HideAPK.restore(view.activity) }
is Hide -> viewModelScope.launch { AppMigration.hide(view.activity, item.value) }
Restore -> viewModelScope.launch { AppMigration.restore(view.activity) }
Zygisk -> if (Zygisk.mismatch) SnackbarEvent(R.string.reboot_apply_change).publish()
else -> Unit
}
}
private fun launchAppLocaleSettings(activity: Activity) {
val intent = Intent(Settings.ACTION_APP_LOCALE_SETTINGS)
intent.data = Uri.fromParts("package", activity.packageName, null)
activity.startActivity(intent)
}
private fun openUrlIfNecessary(view: View) {
UpdateChannelUrl.refresh()
if (UpdateChannelUrl.isEnabled && UpdateChannelUrl.value.isBlank()) {
@@ -119,15 +129,9 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
}
}
private fun authenticate(callback: () -> Unit) {
BiometricEvent {
// allow the change on success
onSuccess { callback() }
}.publish()
}
private fun createHosts() {
Shell.cmd("add_hosts_module").submit {
viewModelScope.launch {
RootUtils.addSystemlessHosts()
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
}
}

View File

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

View File

@@ -9,6 +9,7 @@ import com.topjohnwu.magisk.databinding.FragmentSuperuserMd2Binding
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
import com.topjohnwu.magisk.core.R as CoreR
class SuperuserFragment : BaseFragment<FragmentSuperuserMd2Binding>() {
@@ -17,7 +18,7 @@ class SuperuserFragment : BaseFragment<FragmentSuperuserMd2Binding>() {
override fun onStart() {
super.onStart()
activity?.title = resources.getString(R.string.superuser)
activity?.title = resources.getString(CoreR.string.superuser)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@@ -8,24 +8,28 @@ import androidx.databinding.Bindable
import androidx.databinding.ObservableArrayList
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.AppContext
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.R
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.currentLocale
import com.topjohnwu.magisk.databinding.*
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.SuperuserRevokeDialog
import com.topjohnwu.magisk.events.BiometricEvent
import com.topjohnwu.magisk.events.AuthEvent
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.view.TextItem
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Locale
class SuperuserViewModel(
private val db: PolicyDao
@@ -74,8 +78,8 @@ class SuperuserViewModel(
this@SuperuserViewModel, policy,
info.packageName,
info.sharedUserId != null,
info.applicationInfo.loadIcon(pm),
info.applicationInfo.getLabel(pm)
info.applicationInfo?.loadIcon(pm) ?: pm.defaultActivityIcon,
info.applicationInfo?.getLabel(pm) ?: info.packageName
)
} catch (e: PackageManager.NameNotFoundException) {
null
@@ -88,7 +92,7 @@ class SuperuserViewModel(
policies.addAll(map)
}
policies.sortWith(compareBy(
{ it.appName.lowercase(currentLocale) },
{ it.appName.lowercase(Locale.ROOT) },
{ it.packageName }
))
itemsPolicies.update(policies)
@@ -113,10 +117,8 @@ class SuperuserViewModel(
}
}
if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent {
onSuccess { updateState() }
}.publish()
if (Config.suAuth) {
AuthEvent { updateState() }.publish()
} else {
SuperuserRevokeDialog(item.title) { updateState() }.show()
}
@@ -154,24 +156,23 @@ class SuperuserViewModel(
}
}
fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
fun updatePolicy(item: PolicyRvItem, policy: Int) {
val items = itemsPolicies.filter { it.item.uid == item.item.uid }
fun updateState() {
viewModelScope.launch {
val res = if (enable) R.string.su_snack_grant else R.string.su_snack_deny
item.item.policy = if (enable) SuPolicy.ALLOW else SuPolicy.DENY
val res = if (policy >= SuPolicy.ALLOW) R.string.su_snack_grant else R.string.su_snack_deny
item.item.policy = policy
db.update(item.item)
items.forEach {
it.notifyPropertyChanged(BR.enabled)
it.notifyPropertyChanged(BR.sliderValue)
}
SnackbarEvent(res.asText(item.appName)).publish()
}
}
if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent {
onSuccess { updateState() }
}.publish()
if (Config.suAuth) {
AuthEvent { updateState() }.publish()
} else {
updateState()
}

View File

@@ -11,6 +11,7 @@ import androidx.lifecycle.lifecycleScope
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.core.base.UntrackedActivity
import com.topjohnwu.magisk.core.su.SuCallbackHandler
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
@@ -19,7 +20,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
open class SuRequestActivity : UIActivity<ActivityRequestBinding>() {
open class SuRequestActivity : UIActivity<ActivityRequestBinding>(), UntrackedActivity {
override val layoutRes: Int = R.layout.activity_request
override val viewModel: SuRequestViewModel by viewModel()

View File

@@ -17,19 +17,18 @@ import android.widget.Toast
import androidx.databinding.Bindable
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.AppContext
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.R
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.databinding.set
import com.topjohnwu.magisk.events.BiometricEvent
import com.topjohnwu.magisk.events.AuthEvent
import com.topjohnwu.magisk.events.DieEvent
import com.topjohnwu.magisk.events.ShowUIEvent
import com.topjohnwu.magisk.utils.TextHolder
@@ -77,12 +76,8 @@ class SuRequestViewModel(
fun grantPressed() {
cancelTimer()
if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent {
onSuccess {
respond(ALLOW)
}
}.publish()
if (Config.suAuth) {
AuthEvent { respond(ALLOW) }.publish()
} else {
respond(ALLOW)
}
@@ -116,7 +111,7 @@ class SuRequestViewModel(
// shared UID. We have no way to know where this request comes from.
icon = pm.defaultActivityIcon
title = "[SharedUID] ${info.sharedUserId}"
packageName = info.sharedUserId
packageName = info.sharedUserId.toString()
} else {
val prefix = if (info.sharedUserId == null) "" else "[SharedUID] "
icon = app.loadIcon(pm)

View File

@@ -12,6 +12,7 @@ import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.arch.viewModel
import com.topjohnwu.magisk.databinding.FragmentThemeMd2Binding
import com.topjohnwu.magisk.databinding.ItemThemeBindingImpl
import com.topjohnwu.magisk.core.R as CoreR
class ThemeFragment : BaseFragment<FragmentThemeMd2Binding>() {
@@ -61,7 +62,7 @@ class ThemeFragment : BaseFragment<FragmentThemeMd2Binding>() {
override fun onStart() {
super.onStart()
activity?.title = getString(R.string.section_theme)
activity?.title = getString(CoreR.string.section_theme)
}
}

View File

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

View File

@@ -14,7 +14,7 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.google.android.material.circularreveal.CircularRevealCompat
import com.google.android.material.circularreveal.CircularRevealWidget
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.core.utils.LocaleSetting
import kotlin.math.hypot
object MotionRevealHelper {
@@ -63,7 +63,9 @@ object MotionRevealHelper {
it.interpolator = FastOutSlowInInterpolator()
it.addListener(onStart = { show() }, onEnd = { if (revealInfo.radius != 0f) hide() })
val rtlMod = if (currentLocale.layoutDirection == View.LAYOUT_DIRECTION_RTL) 1f else -1f
val rtlMod =
if (LocaleSetting.instance.currentLocale.layoutDirection == View.LAYOUT_DIRECTION_RTL)
1f else -1f
val maxX = revealInfo.centerX - marginEnd - measuredWidth / 2f
val targetX = if (revealInfo.radius == 0f) 0f else maxX * rtlMod
val moveX = ObjectAnimator.ofFloat(this, View.TRANSLATION_X, targetX)

View File

@@ -21,7 +21,7 @@ import com.google.android.material.color.MaterialColors
import com.google.android.material.shape.MaterialShapeDrawable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.databinding.DialogMagiskBaseBinding
import com.topjohnwu.magisk.databinding.DiffItem
import com.topjohnwu.magisk.databinding.ItemWrapper
@@ -42,7 +42,7 @@ class MagiskDialog(
DialogMagiskBaseBinding.inflate(LayoutInflater.from(context))
private val data = Data()
val activity: BaseActivity get() = ownerActivity as BaseActivity
val activity: UIActivity<*> get() = ownerActivity as UIActivity<*>
init {
binding.setVariable(BR.data, data)

View File

@@ -3,6 +3,7 @@ package com.topjohnwu.magisk.view
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.DiffItem
import com.topjohnwu.magisk.databinding.RvItem
import com.topjohnwu.magisk.core.R as CoreR
sealed class TappableHeadlineItem : RvItem(), DiffItem<TappableHeadlineItem> {
@@ -22,7 +23,7 @@ sealed class TappableHeadlineItem : RvItem(), DiffItem<TappableHeadlineItem> {
// --- objects
object ThemeMode : TappableHeadlineItem() {
override val title = R.string.settings_dark_mode_title
override val title = CoreR.string.settings_dark_mode_title
override val icon = R.drawable.ic_day_night
}

View File

@@ -18,7 +18,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 20 8 L 20 8 L 17.19 8 C 16.74 7.22 16.12 6.55 15.37 6.04 L 17 4.41 L 15.59 3 L 13.42 5.17 C 12.96 5.06 12.49 5 12 5 C 11.51 5 11.04 5.06 10.59 5.17 L 8.41 3 L 7 4.41 L 8.62 6.04 C 7.88 6.55 7.26 7.22 6.81 8 L 4 8 L 4 10 L 6.09 10 C 6.04 10.33 6 10.66 6 11 L 6 12 L 4 12 L 4 14 L 6 14 L 6 15 C 6 15.34 6.04 15.67 6.09 16 L 4 16 L 4 18 L 6.81 18 C 7.85 19.79 9.78 21 12 21 C 14.22 21 16.15 19.79 17.19 18 L 20 18 L 20 16 L 17.91 16 C 17.96 15.67 18 15.34 18 15 L 18 14 L 20 14 L 20 12 L 18 12 L 18 11 C 18 10.66 17.96 10.33 17.91 10 L 20 10 L 20 8 M 14 16 C 14 15.43 14 14.859 14 14.289 L 14 14 C 13.869 14 13.739 14 13.608 14 C 12.405 14 11.203 14 10 14 C 10 14.509 10 15.017 10 15.526 C 10 15.684 10 15.842 10 16 L 10.33 16 C 10.392 16 10.454 16 10.515 16 C 11.677 16 12.838 16 14 16 C 14 16 14 16 14 16 M 14 10 L 14 12 L 14 12 L 10 12 L 10 10 L 14 10 M 12 15 L 12 15 L 12 15 L 12 15 L 12 15 L 12 15"
android:valueTo="M 20 8 L 18.595 8 L 17.19 8 C 16.74 7.2 16.12 6.5 15.37 6 L 17 4.41 L 15.59 3 L 13.42 5.17 C 12.96 5.06 12.5 5 12 5 C 11.5 5 11.05 5.06 10.59 5.17 L 8.41 3 L 7 4.41 L 8.62 6 C 7.87 6.5 7.26 7.21 6.81 8 L 4 8 L 4 10 L 6.09 10 C 6.03 10.33 6 10.66 6 11 L 6 12 L 4 12 L 4 14 L 6 14 L 6 15 C 6 15.34 6.03 15.67 6.09 16 L 4 16 L 4 18 L 6.81 18 C 8.47 20.87 12.14 21.84 15 20.18 C 15.91 19.66 16.67 18.9 17.19 18 L 20 18 L 20 16 L 17.91 16 C 17.97 15.67 18 15.34 18 15 L 18 14 L 20 14 L 20 12 L 18 12 L 18 11 C 18 10.66 17.97 10.33 17.91 10 L 20 10 L 20 8 M 14.828 17.828 C 15.578 17.079 16 16.06 16 15 L 16 11 C 16 9.94 15.578 8.921 14.828 8.172 C 14.079 7.422 13.06 7 12 7 C 10.94 7 9.921 7.422 9.172 8.172 C 8.422 8.921 8 9.94 8 11 L 8 15 C 8 16.06 8.422 17.079 9.172 17.828 C 9.921 18.578 10.94 19 12 19 C 13.06 19 14.079 18.578 14.828 17.828 M 14 10 L 14 11 L 14 12 L 10 12 L 10 10 L 14 10 M 10 14 L 14 14 L 14 16 L 10 16 L 10 14 L 10 14"

View File

@@ -18,7 +18,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 20 8 L 18.595 8 L 17.19 8 C 16.74 7.2 16.12 6.5 15.37 6 L 17 4.41 L 15.59 3 L 13.42 5.17 C 12.96 5.06 12.5 5 12 5 C 11.5 5 11.05 5.06 10.59 5.17 L 8.41 3 L 7 4.41 L 8.62 6 C 7.87 6.5 7.26 7.21 6.81 8 L 4 8 L 4 10 L 6.09 10 C 6.03 10.33 6 10.66 6 11 L 6 12 L 4 12 L 4 14 L 6 14 L 6 15 C 6 15.34 6.03 15.67 6.09 16 L 4 16 L 4 18 L 6.81 18 C 8.47 20.87 12.14 21.84 15 20.18 C 15.91 19.66 16.67 18.9 17.19 18 L 20 18 L 20 16 L 17.91 16 C 17.97 15.67 18 15.34 18 15 L 18 14 L 20 14 L 20 12 L 18 12 L 18 11 C 18 10.66 17.97 10.33 17.91 10 L 20 10 L 20 8 M 14.828 17.828 C 15.578 17.079 16 16.06 16 15 L 16 11 C 16 9.94 15.578 8.921 14.828 8.172 C 14.079 7.422 13.06 7 12 7 C 10.94 7 9.921 7.422 9.172 8.172 C 8.422 8.921 8 9.94 8 11 L 8 15 C 8 16.06 8.422 17.079 9.172 17.828 C 9.921 18.578 10.94 19 12 19 C 13.06 19 14.079 18.578 14.828 17.828 M 14 10 L 14 11 L 14 12 L 10 12 L 10 10 L 14 10 M 10 14 L 14 14 L 14 16 L 10 16 L 10 14 L 10 14"
android:valueTo="M 20 8 L 20 8 L 17.19 8 C 16.74 7.22 16.12 6.55 15.37 6.04 L 17 4.41 L 15.59 3 L 13.42 5.17 C 12.96 5.06 12.49 5 12 5 C 11.51 5 11.04 5.06 10.59 5.17 L 8.41 3 L 7 4.41 L 8.62 6.04 C 7.88 6.55 7.26 7.22 6.81 8 L 4 8 L 4 10 L 6.09 10 C 6.04 10.33 6 10.66 6 11 L 6 12 L 4 12 L 4 14 L 6 14 L 6 15 C 6 15.34 6.04 15.67 6.09 16 L 4 16 L 4 18 L 6.81 18 C 7.85 19.79 9.78 21 12 21 C 14.22 21 16.15 19.79 17.19 18 L 20 18 L 20 16 L 17.91 16 C 17.96 15.67 18 15.34 18 15 L 18 14 L 20 14 L 20 12 L 18 12 L 18 11 C 18 10.66 17.96 10.33 17.91 10 L 20 10 L 20 8 M 14 16 C 14 15.43 14 14.859 14 14.289 L 14 14 C 13.869 14 13.739 14 13.608 14 C 12.405 14 11.203 14 10 14 C 10 14.509 10 15.017 10 15.526 C 10 15.684 10 15.842 10 16 L 10.33 16 C 10.392 16 10.454 16 10.515 16 C 11.677 16 12.838 16 14 16 C 14 16 14 16 14 16 M 14 10 L 14 12 L 14 12 L 10 12 L 10 10 L 14 10 M 12 15 L 12 15 L 12 15 L 12 15 L 12 15 L 12 15"

View File

@@ -17,7 +17,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="500"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 12 2 C 9.217 2 6.689 3.152 4.872 5.004 C 3.098 6.811 2 9.283 2 12 C 2 14.744 3.12 17.24 4.927 19.052 C 6.74 20.87 9.244 22 12 22 C 13.911 22 15.701 21.457 17.224 20.517 C 18.628 19.651 19.804 18.448 20.638 17.024 C 21.503 15.545 22 13.828 22 12 C 22 10.2 21.518 8.507 20.677 7.044 C 19.755 5.441 18.402 4.114 16.779 3.224 C 15.357 2.444 13.728 2 12 2 M 12 20 C 7.59 20 4 16.41 4 12 C 4 7.59 7.59 4 12 4 C 16.41 4 20 7.59 20 12 C 20 16.41 16.41 20 12 20 M 6 13 L 10 17 L 18 9 L 16.59 7.58 L 16.59 7.58 L 10 14.17 L 7.41 11.59 L 6 13"
android:valueTo="M 12 2 C 9.349 2 6.804 3.054 4.929 4.929 C 3.054 6.804 2 9.349 2 12 C 2 14.651 3.054 17.196 4.929 19.071 C 6.804 20.946 9.349 22 12 22 C 13.755 22 15.48 21.538 17 20.66 C 18.52 19.783 19.783 18.52 20.66 17 C 21.538 15.48 22 13.755 22 12 C 22 10.245 21.538 8.52 20.66 7 C 19.783 5.48 18.52 4.217 17 3.34 C 15.48 2.462 13.755 2 12 2 M 12 20 C 7.59 20 4 16.41 4 12 C 4 7.59 7.59 4 12 4 C 16.41 4 20 7.59 20 12 C 20 16.41 16.41 20 12 20 M 7 13 L 7 13 L 17 13 L 17 11 L 17 11 L 7 11 L 7 11 L 7 11"

View File

@@ -17,7 +17,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="500"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 12 2 C 9.349 2 6.804 3.054 4.929 4.929 C 3.054 6.804 2 9.349 2 12 C 2 14.651 3.054 17.196 4.929 19.071 C 6.804 20.946 9.349 22 12 22 C 13.755 22 15.48 21.538 17 20.66 C 18.52 19.783 19.783 18.52 20.66 17 C 21.538 15.48 22 13.755 22 12 C 22 10.245 21.538 8.52 20.66 7 C 19.783 5.48 18.52 4.217 17 3.34 C 15.48 2.462 13.755 2 12 2 M 12 20 C 7.59 20 4 16.41 4 12 C 4 7.59 7.59 4 12 4 C 16.41 4 20 7.59 20 12 C 20 16.41 16.41 20 12 20 M 7 13 L 7 13 L 17 13 L 17 11 L 17 11 L 7 11 L 7 11 L 7 11"
android:valueTo="M 12 2 C 9.217 2 6.689 3.152 4.872 5.004 C 3.098 6.811 2 9.283 2 12 C 2 14.856 3.213 17.442 5.149 19.268 C 6.942 20.96 9.356 22 12 22 C 14.061 22 15.982 21.368 17.578 20.288 C 19.114 19.249 20.349 17.796 21.119 16.092 C 21.685 14.841 22 13.456 22 12 C 22 10.122 21.475 8.361 20.566 6.856 C 19.691 5.408 18.46 4.197 16.997 3.347 C 15.524 2.491 13.817 2 12 2 M 12 20 C 7.59 20 4 16.41 4 12 C 4 7.59 7.59 4 12 4 C 16.41 4 20 7.59 20 12 C 20 16.41 16.41 20 12 20 M 6 13 L 10 17 L 18 9 L 16.59 7.58 L 16.59 7.58 L 10 14.17 L 7.41 11.59 L 6 13"

View File

@@ -19,7 +19,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 9 14 L 9 21 L 4 21 L 4 9 L 12 3 L 12 3 L 20 9 L 20 21 L 15 21 L 15 14 L 9 14 M 12 13.4 L 12 13.4 L 12 13.4 L 12 13.4 L 12 13.4 L 12 13.4 L 12 13.4"
android:valueTo="M 9 13 L 9 19 L 6 19 L 6 10 L 12 5.5 L 15 7.75 L 18 10 L 18 19 L 15 19 L 15 13 L 9 13 M 4 21 L 4 9 L 12 3 L 20 9 L 20 21 L 4 21 L 4 21"

View File

@@ -19,7 +19,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 9 13 L 9 19 L 6 19 L 6 10 L 12 5.5 L 15 7.75 L 18 10 L 18 19 L 15 19 L 15 13 L 9 13 M 4 21 L 4 9 L 12 3 L 20 9 L 20 21 L 4 21 L 4 21"
android:valueTo="M 9 14 L 9 21 L 4 21 L 4 9 L 12 3 L 12 3 L 20 9 L 20 21 L 15 21 L 15 14 L 9 14 M 12 13.4 L 12 13.4 L 12 13.4 L 12 13.4 L 12 13.4 L 12 13.4 L 12 13.4"

View File

@@ -18,7 +18,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 23 13.5 C 23 14.163 22.736 14.799 22.268 15.268 C 21.799 15.736 21.163 16 20.5 16 C 20 16 19.5 16 19 16 L 19 20 C 19 20.53 18.789 21.039 18.414 21.414 C 18.039 21.789 17.53 22 17 22 L 15.1 22 L 13.2 22 C 13.2 21.5 13.2 21 13.2 20.5 C 13.2 19 12 17.8 10.5 17.8 C 9 17.8 7.8 19 7.8 20.5 L 7.8 22 L 4 22 C 3.47 22 2.961 21.789 2.586 21.414 C 2.211 21.039 2 20.53 2 20 L 2 16.2 L 3.5 16.2 C 5 16.2 6.2 15 6.2 13.5 C 6.2 12 5 10.8 3.5 10.8 L 2 10.8 L 2 7 C 2 6.47 2.211 5.961 2.586 5.586 C 2.961 5.211 3.47 5 4 5 L 8 5 C 8 4.5 8 4 8 3.5 C 8 2.837 8.264 2.201 8.732 1.732 C 9.201 1.264 9.837 1 10.5 1 C 11.163 1 11.799 1.264 12.268 1.732 C 12.736 2.201 13 2.837 13 3.5 C 13 4 13 4.5 13 5 L 17 5 C 17.55 5 18.05 5.223 18.413 5.584 C 18.775 5.945 19 6.445 19 7 L 19 11 C 19.5 11 20 11 20.5 11 C 20.5 11 20.5 11 20.5 11 C 21.163 11 21.799 11.264 22.268 11.732 C 22.736 12.201 23 12.837 23 13.5 M 12 12 L 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12"
android:valueTo="M 22 13.5 C 22 14.087 21.856 14.64 21.6 15.126 C 21.344 15.612 20.978 16.03 20.533 16.347 C 20.089 16.664 19.567 16.88 19 16.96 L 19 20 C 19 20.53 18.789 21.039 18.414 21.414 C 18.039 21.789 17.53 22 17 22 L 13.2 22 L 13.2 21.7 C 13.2 20.984 12.915 20.297 12.409 19.791 C 11.903 19.285 11.216 19 10.5 19 C 9 19 7.8 20.21 7.8 21.7 L 7.8 22 L 4 22 C 3.47 22 2.961 21.789 2.586 21.414 C 2.211 21.039 2 20.53 2 20 L 2 16.2 L 2.3 16.2 C 3.79 16.2 5 15 5 13.5 C 5 12 3.79 10.8 2.3 10.8 L 2 10.8 L 2 7 C 2 6.47 2.211 5.961 2.586 5.586 C 2.961 5.211 3.47 5 4 5 L 7.04 5 C 7.12 4.433 7.336 3.911 7.653 3.467 C 7.97 3.022 8.388 2.656 8.874 2.4 C 9.36 2.144 9.913 2 10.5 2 C 11.087 2 11.64 2.144 12.126 2.4 C 12.612 2.656 13.03 3.022 13.347 3.467 C 13.664 3.911 13.88 4.433 13.96 5 L 17 5 C 17.53 5 18.039 5.211 18.414 5.586 C 18.789 5.961 19 6.47 19 7 L 19 10.04 C 19.425 10.1 19.825 10.236 20.186 10.434 C 20.547 10.633 20.869 10.893 21.137 11.2 C 21.406 11.508 21.622 11.863 21.77 12.251 C 21.919 12.639 22 13.06 22 13.5 M 17 12 L 18.5 12 C 18.898 12 19.279 12.158 19.561 12.439 C 19.842 12.721 20 13.102 20 13.5 C 20 13.898 19.842 14.279 19.561 14.561 C 19.279 14.842 18.898 15 18.5 15 L 17 15 L 17 15 L 17 20 L 14.88 20 C 14.2 18.25 12.5 17 10.5 17 C 8.5 17 6.8 18.25 6.12 20 L 4 20 L 4 17.88 C 5.75 17.2 7 15.5 7 13.5 C 7 11.5 5.76 9.8 4 9.12 L 4 7 L 9 7 L 9 5.5 C 9 5.102 9.158 4.721 9.439 4.439 C 9.721 4.158 10.102 4 10.5 4 C 10.898 4 11.279 4.158 11.561 4.439 C 11.842 4.721 12 5.102 12 5.5 L 12 7 L 17 7 L 17 12"

View File

@@ -18,7 +18,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 22 13.5 C 22 14.087 21.856 14.64 21.6 15.126 C 21.344 15.612 20.978 16.03 20.533 16.347 C 20.089 16.664 19.567 16.88 19 16.96 L 19 20 C 19 20.53 18.789 21.039 18.414 21.414 C 18.039 21.789 17.53 22 17 22 L 13.2 22 L 13.2 21.7 C 13.2 20.984 12.915 20.297 12.409 19.791 C 11.903 19.285 11.216 19 10.5 19 C 9 19 7.8 20.21 7.8 21.7 L 7.8 22 L 4 22 C 3.47 22 2.961 21.789 2.586 21.414 C 2.211 21.039 2 20.53 2 20 L 2 16.2 L 2.3 16.2 C 3.79 16.2 5 15 5 13.5 C 5 12 3.79 10.8 2.3 10.8 L 2 10.8 L 2 7 C 2 6.47 2.211 5.961 2.586 5.586 C 2.961 5.211 3.47 5 4 5 L 7.04 5 C 7.12 4.433 7.336 3.911 7.653 3.467 C 7.97 3.022 8.388 2.656 8.874 2.4 C 9.36 2.144 9.913 2 10.5 2 C 11.087 2 11.64 2.144 12.126 2.4 C 12.612 2.656 13.03 3.022 13.347 3.467 C 13.664 3.911 13.88 4.433 13.96 5 L 17 5 C 17.53 5 18.039 5.211 18.414 5.586 C 18.789 5.961 19 6.47 19 7 L 19 10.04 C 19.425 10.1 19.825 10.236 20.186 10.434 C 20.547 10.633 20.869 10.893 21.137 11.2 C 21.406 11.508 21.622 11.863 21.77 12.251 C 21.919 12.639 22 13.06 22 13.5 M 17 12 L 18.5 12 C 18.898 12 19.279 12.158 19.561 12.439 C 19.842 12.721 20 13.102 20 13.5 C 20 13.898 19.842 14.279 19.561 14.561 C 19.279 14.842 18.898 15 18.5 15 L 17 15 L 17 15 L 17 20 L 14.88 20 C 14.2 18.25 12.5 17 10.5 17 C 8.5 17 6.8 18.25 6.12 20 L 4 20 L 4 17.88 C 5.75 17.2 7 15.5 7 13.5 C 7 11.5 5.76 9.8 4 9.12 L 4 7 L 9 7 L 9 5.5 C 9 5.102 9.158 4.721 9.439 4.439 C 9.721 4.158 10.102 4 10.5 4 C 10.898 4 11.279 4.158 11.561 4.439 C 11.842 4.721 12 5.102 12 5.5 L 12 7 L 17 7 L 17 12"
android:valueTo="M 23 13.5 C 23 14.163 22.736 14.799 22.268 15.268 C 21.799 15.736 21.163 16 20.5 16 C 20 16 19.5 16 19 16 L 19 20 C 19 20.53 18.789 21.039 18.414 21.414 C 18.039 21.789 17.53 22 17 22 L 15.1 22 L 13.2 22 C 13.2 21.5 13.2 21 13.2 20.5 C 13.2 19 12 17.8 10.5 17.8 C 9 17.8 7.8 19 7.8 20.5 L 7.8 22 L 4 22 C 3.47 22 2.961 21.789 2.586 21.414 C 2.211 21.039 2 20.53 2 20 L 2 16.2 L 3.5 16.2 C 5 16.2 6.2 15 6.2 13.5 C 6.2 12 5 10.8 3.5 10.8 L 2 10.8 L 2 7 C 2 6.47 2.211 5.961 2.586 5.586 C 2.961 5.211 3.47 5 4 5 L 8 5 C 8 4.5 8 4 8 3.5 C 8 2.837 8.264 2.201 8.732 1.732 C 9.201 1.264 9.837 1 10.5 1 C 11.163 1 11.799 1.264 12.268 1.732 C 12.736 2.201 13 2.837 13 3.5 C 13 4 13 4.5 13 5 L 17 5 C 17.55 5 18.05 5.223 18.413 5.584 C 18.775 5.945 19 6.445 19 7 L 19 11 C 19.5 11 20 11 20.5 11 C 20.5 11 20.5 11 20.5 11 C 21.163 11 21.799 11.264 22.268 11.732 C 22.736 12.201 23 12.837 23 13.5 M 12 12 L 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12"

View File

@@ -18,7 +18,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 14.87 5.07 L 14.5 2.42 C 14.46 2.18 14.25 2 14 2 L 10 2 C 9.75 2 9.54 2.18 9.5 2.42 L 9.13 5.07 C 8.5 5.32 7.96 5.66 7.44 6.05 L 4.95 5.05 C 4.73 4.96 4.46 5.05 4.34 5.27 L 2.34 8.73 C 2.21 8.95 2.27 9.22 2.46 9.37 L 4.57 11 C 4.53 11.34 4.5 11.67 4.5 12 C 4.5 12.33 4.53 12.65 4.57 12.97 L 2.46 14.63 C 2.27 14.78 2.21 15.05 2.34 15.27 L 4.34 18.73 C 4.46 18.95 4.73 19.03 4.95 18.95 L 7.44 17.94 C 7.96 18.34 8.5 18.68 9.13 18.93 L 9.5 21.58 C 9.54 21.82 9.75 22 10 22 L 14 22 C 14.25 22 14.46 21.82 14.5 21.58 L 14.87 18.93 C 15.5 18.67 16.04 18.34 16.56 17.94 L 19.05 18.95 C 19.27 19.03 19.54 18.95 19.66 18.73 L 21.66 15.27 C 21.78 15.05 21.73 14.78 21.54 14.63 L 19.43 12.97 L 19.43 12.97 C 19.47 12.65 19.5 12.33 19.5 12 C 19.5 11.67 19.47 11.34 19.43 11 L 21.54 9.37 C 21.73 9.22 21.78 8.95 21.66 8.73 L 19.66 5.27 C 19.54 5.05 19.27 4.96 19.05 5.05 L 16.56 6.05 C 16.04 5.66 15.5 5.32 14.87 5.07 M 12 8.5 C 12.614 8.5 13.218 8.662 13.75 8.969 C 14.282 9.276 14.724 9.718 15.031 10.25 C 15.338 10.782 15.5 11.386 15.5 12 C 15.5 12.614 15.338 13.218 15.031 13.75 C 14.724 14.282 14.282 14.724 13.75 15.031 C 13.218 15.338 12.614 15.5 12 15.5 C 11.072 15.5 10.181 15.131 9.525 14.475 C 8.869 13.819 8.5 12.928 8.5 12 C 8.5 11.072 8.869 10.181 9.525 9.525 C 10.181 8.869 11.072 8.5 12 8.5 M 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 M 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12"
android:valueTo="M 14.87 5.07 L 14.5 2.42 C 14.46 2.18 14.25 2 14 2 L 10 2 C 9.75 2 9.54 2.18 9.5 2.42 L 9.13 5.07 C 8.5 5.32 7.96 5.66 7.44 6.05 L 4.95 5.05 C 4.73 4.96 4.46 5.05 4.34 5.27 L 2.34 8.73 C 2.21 8.95 2.27 9.22 2.46 9.37 L 4.57 11 C 4.547 11.333 4.523 11.667 4.5 12 C 4.523 12.323 4.547 12.647 4.57 12.97 L 2.46 14.63 C 2.27 14.78 2.21 15.05 2.34 15.27 L 4.34 18.73 C 4.46 18.95 4.73 19.03 4.95 18.95 L 7.44 17.94 C 7.96 18.34 8.5 18.68 9.13 18.93 L 9.5 21.58 C 9.54 21.82 9.75 22 10 22 L 14 22 C 14.25 22 14.46 21.82 14.5 21.58 L 14.87 18.93 C 15.5 18.68 16.04 18.34 16.56 17.95 L 19.05 18.95 C 19.27 19.04 19.54 18.95 19.66 18.73 L 21.66 15.27 C 21.79 15.05 21.73 14.78 21.54 14.63 L 19.43 13 L 19.465 12.499 C 19.477 12.333 19.488 12.166 19.5 12 C 19.477 11.667 19.453 11.333 19.43 11 L 21.54 9.37 C 21.73 9.22 21.79 8.95 21.66 8.73 L 19.66 5.27 C 19.54 5.05 19.27 4.96 19.05 5.05 L 16.56 6.05 C 16.04 5.66 15.5 5.32 14.87 5.07 M 12 8 C 12.53 8 13.05 8.105 13.531 8.305 C 14.011 8.504 14.454 8.797 14.828 9.172 C 15.578 9.921 16 10.94 16 12 C 16 12.53 15.895 13.05 15.695 13.531 C 15.496 14.011 15.203 14.454 14.828 14.828 C 14.079 15.578 13.06 16 12 16 C 10.94 16 9.921 15.578 9.172 14.828 C 8.422 14.079 8 13.06 8 12 C 8 10.94 8.422 9.921 9.172 9.172 C 9.921 8.422 10.94 8 12 8 M 12 10 C 11.912 10 11.824 10.006 11.737 10.017 C 11.651 10.029 11.565 10.046 11.481 10.069 C 11.397 10.091 11.315 10.119 11.235 10.152 C 11.155 10.186 11.077 10.224 11.001 10.267 C 10.926 10.311 10.854 10.359 10.784 10.412 C 10.715 10.466 10.649 10.524 10.586 10.586 C 10.524 10.649 10.466 10.715 10.412 10.784 C 10.359 10.854 10.311 10.926 10.267 11.001 C 10.224 11.077 10.186 11.155 10.152 11.235 C 10.119 11.315 10.091 11.397 10.069 11.481 C 10.046 11.565 10.029 11.651 10.017 11.737 C 10.006 11.824 10 11.912 10 12 C 10 12.088 10.006 12.176 10.017 12.263 C 10.029 12.349 10.046 12.435 10.069 12.519 C 10.091 12.603 10.119 12.685 10.152 12.765 C 10.186 12.845 10.224 12.923 10.267 12.999 C 10.311 13.074 10.359 13.146 10.412 13.216 C 10.466 13.285 10.524 13.351 10.586 13.414 C 10.649 13.476 10.715 13.534 10.784 13.588 C 10.854 13.641 10.926 13.689 11.001 13.733 C 11.077 13.776 11.155 13.814 11.235 13.848 C 11.315 13.881 11.397 13.909 11.481 13.931 C 11.565 13.954 11.651 13.971 11.737 13.983 C 11.824 13.994 11.912 14 12 14 C 12.53 14 13.039 13.789 13.414 13.414 C 13.468 13.36 13.518 13.304 13.565 13.245 C 13.611 13.187 13.655 13.126 13.694 13.062 C 13.734 12.999 13.77 12.934 13.802 12.867 C 13.834 12.8 13.863 12.731 13.887 12.661 C 13.912 12.591 13.933 12.519 13.949 12.447 C 13.966 12.374 13.979 12.3 13.987 12.226 C 13.996 12.151 14 12.076 14 12 C 14 11.912 13.994 11.824 13.983 11.737 C 13.971 11.651 13.954 11.565 13.931 11.481 C 13.909 11.397 13.881 11.315 13.848 11.235 C 13.814 11.155 13.776 11.077 13.733 11.001 C 13.689 10.926 13.641 10.854 13.588 10.784 C 13.534 10.715 13.476 10.649 13.414 10.586 C 13.039 10.211 12.53 10 12 10 M 11.25 4 L 11.25 4 L 12.75 4 L 13.12 6.62 C 14.32 6.86 15.38 7.5 16.15 8.39 L 18.56 7.35 L 19.31 8.65 L 17.2 10.2 C 17.6 11.37 17.6 12.64 17.2 13.81 L 19.32 15.36 L 18.57 16.66 L 16.14 15.62 C 15.37 16.5 14.32 17.14 13.13 17.39 L 12.76 20 L 11.24 20 L 10.87 17.38 C 9.68 17.14 8.63 16.5 7.86 15.62 L 5.43 16.66 L 4.68 15.36 L 6.8 13.8 C 6.4 12.64 6.4 11.37 6.8 10.2 L 4.69 8.65 L 5.44 7.35 L 7.85 8.39 C 8.62 7.5 9.68 6.86 10.88 6.61 L 11.25 4"

View File

@@ -18,7 +18,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 14.87 5.07 L 14.5 2.42 C 14.46 2.18 14.25 2 14 2 L 10 2 C 9.75 2 9.54 2.18 9.5 2.42 L 9.13 5.07 C 8.5 5.32 7.96 5.66 7.44 6.05 L 4.95 5.05 C 4.73 4.96 4.46 5.05 4.34 5.27 L 2.34 8.73 C 2.21 8.95 2.27 9.22 2.46 9.37 L 4.57 11 C 4.547 11.333 4.523 11.667 4.5 12 C 4.523 12.323 4.547 12.647 4.57 12.97 L 2.46 14.63 C 2.27 14.78 2.21 15.05 2.34 15.27 L 4.34 18.73 C 4.46 18.95 4.73 19.03 4.95 18.95 L 7.44 17.94 C 7.96 18.34 8.5 18.68 9.13 18.93 L 9.5 21.58 C 9.54 21.82 9.75 22 10 22 L 14 22 C 14.25 22 14.46 21.82 14.5 21.58 L 14.87 18.93 C 15.5 18.68 16.04 18.34 16.56 17.95 L 19.05 18.95 C 19.27 19.04 19.54 18.95 19.66 18.73 L 21.66 15.27 C 21.79 15.05 21.73 14.78 21.54 14.63 L 19.43 13 L 19.465 12.499 C 19.477 12.333 19.488 12.166 19.5 12 C 19.477 11.667 19.453 11.333 19.43 11 L 21.54 9.37 C 21.73 9.22 21.79 8.95 21.66 8.73 L 19.66 5.27 C 19.54 5.05 19.27 4.96 19.05 5.05 L 16.56 6.05 C 16.04 5.66 15.5 5.32 14.87 5.07 M 12 8 C 12.53 8 13.05 8.105 13.531 8.305 C 14.011 8.504 14.454 8.797 14.828 9.172 C 15.578 9.921 16 10.94 16 12 C 16 12.53 15.895 13.05 15.695 13.531 C 15.496 14.011 15.203 14.454 14.828 14.828 C 14.079 15.578 13.06 16 12 16 C 10.94 16 9.921 15.578 9.172 14.828 C 8.422 14.079 8 13.06 8 12 C 8 10.94 8.422 9.921 9.172 9.172 C 9.921 8.422 10.94 8 12 8 M 12 10 C 11.912 10 11.824 10.006 11.737 10.017 C 11.651 10.029 11.565 10.046 11.481 10.069 C 11.397 10.091 11.315 10.119 11.235 10.152 C 11.155 10.186 11.077 10.224 11.001 10.267 C 10.926 10.311 10.854 10.359 10.784 10.412 C 10.715 10.466 10.649 10.524 10.586 10.586 C 10.524 10.649 10.466 10.715 10.412 10.784 C 10.359 10.854 10.311 10.926 10.267 11.001 C 10.224 11.077 10.186 11.155 10.152 11.235 C 10.119 11.315 10.091 11.397 10.069 11.481 C 10.046 11.565 10.029 11.651 10.017 11.737 C 10.006 11.824 10 11.912 10 12 C 10 12.088 10.006 12.176 10.017 12.263 C 10.029 12.349 10.046 12.435 10.069 12.519 C 10.091 12.603 10.119 12.685 10.152 12.765 C 10.186 12.845 10.224 12.923 10.267 12.999 C 10.311 13.074 10.359 13.146 10.412 13.216 C 10.466 13.285 10.524 13.351 10.586 13.414 C 10.649 13.476 10.715 13.534 10.784 13.588 C 10.854 13.641 10.926 13.689 11.001 13.733 C 11.077 13.776 11.155 13.814 11.235 13.848 C 11.315 13.881 11.397 13.909 11.481 13.931 C 11.565 13.954 11.651 13.971 11.737 13.983 C 11.824 13.994 11.912 14 12 14 C 12.53 14 13.039 13.789 13.414 13.414 C 13.468 13.36 13.518 13.304 13.565 13.245 C 13.611 13.187 13.655 13.126 13.694 13.062 C 13.734 12.999 13.77 12.934 13.802 12.867 C 13.834 12.8 13.863 12.731 13.887 12.661 C 13.912 12.591 13.933 12.519 13.949 12.447 C 13.966 12.374 13.979 12.3 13.987 12.226 C 13.996 12.151 14 12.076 14 12 C 14 11.912 13.994 11.824 13.983 11.737 C 13.971 11.651 13.954 11.565 13.931 11.481 C 13.909 11.397 13.881 11.315 13.848 11.235 C 13.814 11.155 13.776 11.077 13.733 11.001 C 13.689 10.926 13.641 10.854 13.588 10.784 C 13.534 10.715 13.476 10.649 13.414 10.586 C 13.039 10.211 12.53 10 12 10 M 11.25 4 L 11.25 4 L 12.75 4 L 13.12 6.62 C 14.32 6.86 15.38 7.5 16.15 8.39 L 18.56 7.35 L 19.31 8.65 L 17.2 10.2 C 17.6 11.37 17.6 12.64 17.2 13.81 L 19.32 15.36 L 18.57 16.66 L 16.14 15.62 C 15.37 16.5 14.32 17.14 13.13 17.39 L 12.76 20 L 11.24 20 L 10.87 17.38 C 9.68 17.14 8.63 16.5 7.86 15.62 L 5.43 16.66 L 4.68 15.36 L 6.8 13.8 C 6.4 12.64 6.4 11.37 6.8 10.2 L 4.69 8.65 L 5.44 7.35 L 7.85 8.39 C 8.62 7.5 9.68 6.86 10.88 6.61 L 11.25 4"
android:valueTo="M 14.87 5.07 L 14.5 2.42 C 14.46 2.18 14.25 2 14 2 L 10 2 C 9.75 2 9.54 2.18 9.5 2.42 L 9.13 5.07 C 8.5 5.32 7.96 5.66 7.44 6.05 L 4.95 5.05 C 4.73 4.96 4.46 5.05 4.34 5.27 L 2.34 8.73 C 2.21 8.95 2.27 9.22 2.46 9.37 L 4.57 11 C 4.53 11.34 4.5 11.67 4.5 12 C 4.5 12.33 4.53 12.65 4.57 12.97 L 2.46 14.63 C 2.27 14.78 2.21 15.05 2.34 15.27 L 4.34 18.73 C 4.46 18.95 4.73 19.03 4.95 18.95 L 7.44 17.94 C 7.96 18.34 8.5 18.68 9.13 18.93 L 9.5 21.58 C 9.54 21.82 9.75 22 10 22 L 14 22 C 14.25 22 14.46 21.82 14.5 21.58 L 14.87 18.93 C 15.5 18.67 16.04 18.34 16.56 17.94 L 19.05 18.95 C 19.27 19.03 19.54 18.95 19.66 18.73 L 21.66 15.27 C 21.78 15.05 21.73 14.78 21.54 14.63 L 19.43 12.97 L 19.43 12.97 C 19.47 12.65 19.5 12.33 19.5 12 C 19.5 11.67 19.47 11.34 19.43 11 L 21.54 9.37 C 21.73 9.22 21.78 8.95 21.66 8.73 L 19.66 5.27 C 19.54 5.05 19.27 4.96 19.05 5.05 L 16.56 6.05 C 16.04 5.66 15.5 5.32 14.87 5.07 M 12 8.5 C 12.614 8.5 13.218 8.662 13.75 8.969 C 14.282 9.276 14.724 9.718 15.031 10.25 C 15.338 10.782 15.5 11.386 15.5 12 C 15.5 12.614 15.338 13.218 15.031 13.75 C 14.724 14.282 14.282 14.724 13.75 15.031 C 13.218 15.338 12.614 15.5 12 15.5 C 11.072 15.5 10.181 15.131 9.525 14.475 C 8.869 13.819 8.5 12.928 8.5 12 C 8.5 11.072 8.869 10.181 9.525 9.525 C 10.181 8.869 11.072 8.5 12 8.5 M 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 C 11.982 12 11.982 12 11.982 12 M 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12 L 12 12 L 12 12 C 12 12 12 12 12 12 L 12 12"

View File

@@ -18,7 +18,7 @@
<aapt:attr name="android:animation">
<objectAnimator
android:duration="300"
android:interpolator="@interpolator/fast_out_slow_in"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="M 21 11 C 21 16.55 17.16 21.74 12 23 C 6.84 21.74 3 16.55 3 11 L 3 5 L 12 1 L 12 1 L 21 5 L 21 11 M 12 10.18 L 12 10.18 C 12 10.18 12 10.18 12 10.18 L 12 10.18 L 12 10.18 L 12 10.18 L 12 10.18 C 12 10.18 12 10.18 12 10.18"
android:valueTo="M 21 11 C 21 16.55 17.16 21.74 12 23 C 6.84 21.74 3 16.55 3 11 L 3 5 L 7.5 3 L 12 1 L 21 5 L 21 11 M 12 21 L 12 21 C 8.25 20 5 15.54 5 11.22 L 5 6.3 L 12 3.18 L 19 6.3 L 19 11.22 C 19 15.54 15.75 20 12 21"

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