1
mirror of https://github.com/topjohnwu/Magisk synced 2025-10-30 09:00:52 +01:00

Compare commits

...

192 Commits
v16.7 ... v17.2

Author SHA1 Message Date
topjohnwu
cfe32f1a70 Update Magisk Manager changelogs 2018-09-20 22:34:09 -04:00
Taras
d877f5d5c6 update Ukrainian strings 2018-09-20 16:56:17 -04:00
yuchenlin
0ab6ffefb4 utils/misc.c: prevent file staying opened when function leaving
The utils function may be called in any situation, such as in daemon. We
should guarantee that all the resource got from this function released
normally.

Signed-off-by: yuchenlin <npes87184@gmail.com>
2018-09-20 16:55:48 -04:00
topjohnwu
a292a1d23a Cleanup and add new rules
Close #607
2018-09-20 16:55:16 -04:00
topjohnwu
3f87f6aee3 Fix output in Magisk Manager if no root exists 2018-09-20 16:21:22 -04:00
topjohnwu
04bcd145d3 Add a.a alias to BootSigner 2018-09-20 15:37:59 -04:00
topjohnwu
244e811291 Remove icon padding in preference screen
Courtesy of https://stackoverflow.com/a/51568782
2018-09-19 00:06:14 -04:00
topjohnwu
ac7467fb59 Optimize boot signing to use as little memory as possible 2018-09-18 23:48:21 -04:00
topjohnwu
2c0436216f Prevent null strings in modules/repos
Close #620, close #621
2018-09-18 10:04:12 -04:00
topjohnwu
017fbf267b Fix small theme config issue 2018-09-17 23:29:38 -04:00
topjohnwu
e6afbf2ec0 Force remove busybox from APK 2018-09-17 23:03:37 -04:00
topjohnwu
906b4aad9e New method of communication
Introduce a new communication method between Magisk and Magisk Manager.

Magisk used to hardcode classnames and send broadcast/start activities to
specific components. This new method makes no assumption of any class names,
so Magisk Manager can easily be fully obfuscated.

In addition, the new method connects Magisk and Magisk Manager with random
abstract Linux sockets instead of socket files in filesystems, bypassing
file system complexities (selinux, permissions and such)
2018-09-16 04:16:18 -04:00
topjohnwu
4cf8d41f6a Fix FlashActivity crash 2018-09-16 00:18:34 -04:00
topjohnwu
47c860142e Use ClassMaps to prevent errors 2018-09-16 00:08:13 -04:00
topjohnwu
2fba3f213b Use proper socket address length 2018-09-15 02:49:19 -04:00
topjohnwu
af7c6f9fce Fix FlashActivity crash 2018-09-15 01:45:10 -04:00
topjohnwu
78534deab6 Excessive obfuscation when building in release mode
Close #606
2018-09-14 23:00:39 -04:00
topjohnwu
6710314832 Allow all context to SIGCLD magisk
Fix #596
2018-09-11 11:04:51 -04:00
topjohnwu
0cd4fa6fa0 Simplify SignAPK code 2018-09-11 10:48:36 -04:00
topjohnwu
065949496e Migrate to AndroidX support library 2018-09-10 02:27:45 -04:00
topjohnwu
39c82576ae Prevent warning
Close #524
2018-09-09 12:36:42 -04:00
John Wu
37221a508d Update README.MD 2018-09-09 12:25:22 -04:00
John Wu
6b43a32a10 Delete repo_description.png 2018-09-09 10:41:02 -04:00
ImgBotApp
d7cd1ff142 [ImgBot] optimizes images
*Total -- 990.86kb -> 771.48kb (22.14%)

/docs/images/flashfire.png -- 223.55kb -> 153.39kb (31.39%)
/docs/images/repo_description.png -- 38.55kb -> 27.31kb (29.15%)
/docs/images/manager_reboot.png -- 147.43kb -> 111.50kb (24.37%)
/docs/images/install_inactive_slot.png -- 123.15kb -> 99.79kb (18.97%)
/docs/images/restore_img.png -- 134.17kb -> 109.22kb (18.59%)
/docs/images/disable_auto_ota.png -- 160.04kb -> 132.05kb (17.49%)
/docs/images/ota_done.png -- 163.97kb -> 138.22kb (15.71%)
2018-09-09 10:40:40 -04:00
Sandro Jäckel
659d947863 Updated German translations 2018-09-09 10:40:33 -04:00
Rom
39be7a6288 Update stub French translation 2018-09-09 00:38:47 -04:00
Rom
8ac976c579 Update French translation (#576) 2018-09-09 00:38:33 -04:00
Vladimír Kubala
70fd432c57 Update Slovak translation 2018-09-09 00:38:25 -04:00
Jonas Schubert
00135f2f49 updated full\res\values.de\strings.xml 2018-09-09 00:38:11 -04:00
Albert I
9b944bc29c Update Indonesian translations
Signed-off-by: Albert I <krascgq@outlook.co.id>
2018-09-09 00:38:02 -04:00
topjohnwu
d520b3d2a0 Request storage permission when patching boot images 2018-09-08 23:27:19 -04:00
topjohnwu
6f41d9855b Randomize service names
Fix Aniplex Game detections.
Close #502, close #513
2018-09-08 23:17:00 -04:00
topjohnwu
2d7c1da741 Better support for external config file 2018-09-06 14:25:35 -04:00
topjohnwu
c0f45b6b1e Add resetprop magic 2018-09-06 02:57:02 -04:00
topjohnwu
7a0025673c Use libsystemproperties in resetprop
Upstream to latest Android Pie
2018-09-06 02:57:02 -04:00
topjohnwu
ad7ec79903 Support custom config paths 2018-09-05 14:24:28 -04:00
topjohnwu
0543239cca Do not merge binaries if fake symlink 2018-09-01 11:15:05 -04:00
topjohnwu
ff3dad2457 Prevent upgrading database before upgrading to v17.0 2018-09-01 10:46:13 -04:00
topjohnwu
298d5e197b Update Magisk Manager changelog 2018-09-01 02:37:56 -04:00
Eray Rafet
d73c0a998d Update Bulgarian 2018-09-01 02:15:53 -04:00
topjohnwu
1b79a3ddbf Update OTA tutorial for v17 2018-08-31 21:40:02 -04:00
topjohnwu
a8478ace18 Use macros 2018-08-31 03:51:30 -04:00
topjohnwu
72cf5f3f9f Temporary disable module bootloop prevention
Some devices don't like it, need further tests before pushing to production
2018-08-31 03:23:59 -04:00
vvb2060
6f9d493a18 Update zh-rCN translation 2018-08-31 02:20:52 -04:00
dark-basic
08f7d5ebff Update strings.xml
New Line Added.
2018-08-31 02:20:43 -04:00
Ilya Kushnir
1fe3675403 Update RU strings 2018-08-31 02:20:36 -04:00
Oliver Cervera
a0f956d2c1 Update Italian translation - Twitter string
Added new Twitter string.
2018-08-31 02:20:25 -04:00
topjohnwu
1560f91b4a Move layout from main to full 2018-08-30 05:15:44 -04:00
topjohnwu
c20f362594 Update trad. Chinese translation 2018-08-30 05:09:28 -04:00
topjohnwu
7ae8c26e50 Improve About and Donation page 2018-08-30 05:05:29 -04:00
topjohnwu
adfffe6121 Better back pressing logic 2018-08-30 04:19:08 -04:00
topjohnwu
64601baa76 Update Magisk Manager README 2018-08-30 04:03:14 -04:00
topjohnwu
aa374b51f1 Move fragments to separate package 2018-08-30 03:57:48 -04:00
topjohnwu
5c483745ff Move settings out of separate Activity 2018-08-30 00:52:02 -04:00
topjohnwu
0c247110a0 Also get default flags in non-root environment 2018-08-29 13:31:26 -04:00
Vladimír Kubala
1643638a78 Slovak language
Added Slovak language
2018-08-29 00:41:53 -04:00
Nicholas
4ace228fc2 Update SnackbarMaker.java
Zip downloads don't go into /MagiskManager anymore, they go into /Download instead. Snackbar should be updated accordingly.
2018-08-29 00:41:43 -04:00
Taras
25aa86a0dc update Ukrainian translation 2018-08-29 00:41:18 -04:00
topjohnwu
70d3b24338 Keep dm/avb-verity when device is using system_root_image
Close #512
2018-08-29 00:40:14 -04:00
topjohnwu
8664e9d19b Update scripts 2018-08-28 22:03:12 -04:00
topjohnwu
50d9877446 Sign debug builds with custom keystore if applicable 2018-08-28 12:17:27 -04:00
topjohnwu
fe06352089 Remove unused import 2018-08-27 00:10:43 -04:00
Rom
7b599419b5 Update French translation 2018-08-26 22:50:26 -04:00
Ilya Kushnir
491adf072e Update RU strings 2018-08-26 22:50:18 -04:00
topjohnwu
f6aae2b048 Add hexpatch to remove Samsung defex in kernel
Close #499
2018-08-26 22:38:13 -04:00
Eray Rafet
d2d5c94633 Update Bulgarian 2018-08-25 23:03:06 -04:00
Oliver Cervera
10581f9ef2 Add new fingerprint string
Added new fingerprint string
2018-08-25 23:02:59 -04:00
JoanVC100
c7e0e1c038 Fix ca-strings
Added new line and corrected lines.
2018-08-25 23:02:48 -04:00
vvb2060
a914d701eb Update zh-rCN translation 2018-08-25 23:02:31 -04:00
dark-basic
0f9dee6e9c Update Strings.xml
-New Line added.
------------------------------------------------------------------------------------
Require authentication to toggle fingerprint settings -  Requerir autenticación para alternar configuraciones de huellas dactilares
2018-08-25 23:02:23 -04:00
topjohnwu
aa383e2190 Properly get color from attribute 2018-08-25 23:01:14 -04:00
topjohnwu
9bbfcf326c Do not place files into /sdcard/MagiskManager 2018-08-25 16:00:27 -04:00
topjohnwu
3948e67c8f Require authentication to toggle fingerprint settings
Close #474
2018-08-22 17:49:51 -04:00
topjohnwu
d56e1b2cc5 Move fingerprint settings to global database 2018-08-22 15:05:00 -04:00
topjohnwu
bfac1f1bc2 SN checks is possible after repackage if using new API 2018-08-22 12:32:53 +08:00
topjohnwu
d4a956c355 Fix strings 2018-08-22 12:28:15 +08:00
dark-basic
6c71fefa58 Old Translators removed.
Fisrt of all, I thank you  Gawenda, netizen, Deiki, and Nosi : D
They were the first people to translate Magisk Manager in Spanish.
He had left ther names for their contributions, but I think it´s time to do a cleanup.
-----------------------------------------------------------------------------------
Topjohnwu. Left under your consent to merge or not this modifications.
-----------------------------------------------------------------------------------
My English is a bit of a translator and mine 👍
2018-08-22 00:25:06 -04:00
JoanVC100
ad3003c00a Catalan language for Magisk 2018-08-22 00:24:23 -04:00
Albert I
0ad5dcb258 Update Indonesian translation
Signed-off-by: Albert I <krascgq@outlook.co.id>
2018-08-22 00:23:34 -04:00
Rom
d790309b02 Update French translation
Ready to be merged.

Have a good day!
2018-08-22 00:23:27 -04:00
Oliver Cervera
1072faf309 Update Italian strings
Added latest strings
2018-08-22 00:23:18 -04:00
topjohnwu
d2c196896d Update snet extension 2018-08-22 11:50:21 +08:00
vvb2060
e42b608444 Hide SafetyNet check if no GMS 2018-08-21 23:40:06 -04:00
topjohnwu
89a501a3af Fix build scripts 2018-08-21 00:31:41 +08:00
topjohnwu
c19b78180c Read props directly in Gradle 2018-08-20 12:02:38 +08:00
Taras
c0b750a09a added new lines, translations corrections 2018-08-14 00:21:04 +08:00
topjohnwu
c967e618a1 Adjustment to direct install 2018-08-13 02:57:03 +08:00
topjohnwu
59f78d7dfc Update to BusyBox 1.29.2 2018-08-13 01:30:15 +08:00
topjohnwu
d8405f0d05 Make recovery installed on on system_root devices normal 2018-08-12 00:16:59 +08:00
topjohnwu
0f34f0033c Switch to FrankeNDK for building native 2018-08-11 18:46:55 +08:00
topjohnwu
190646d50c Fix incorrect magisk metadata in ramdisk 2018-08-11 16:31:46 +08:00
topjohnwu
a46c6252c6 Detect insufficient partition size
Close #388
2018-08-11 15:56:12 +08:00
topjohnwu
5c1886c8f5 Update scripts 2018-08-10 18:59:14 +08:00
topjohnwu
afcb3d8f34 Fix XZ decompression in magiskinit 2018-08-10 15:04:32 +08:00
topjohnwu
9fbffafdbf Improve build script 2018-08-10 05:57:12 +08:00
topjohnwu
075f0458f7 Split stub APK to new task 2018-08-10 05:57:12 +08:00
topjohnwu
d4568aa0a7 Compress binaries and use xz-embedded in magiskinit 2018-08-10 05:57:12 +08:00
topjohnwu
97588408a2 Reorganize build script 2018-08-10 05:57:11 +08:00
topjohnwu
1def9b301b Use xz-embedded for b64xz 2018-08-10 05:57:11 +08:00
topjohnwu
5bac442b18 Reorganize sources 2018-08-10 03:49:25 +08:00
topjohnwu
6add682705 Remove high compression mode 2018-08-10 03:49:25 +08:00
topjohnwu
8b50d84a05 Hide unnecessary error log 2018-08-09 15:10:00 +08:00
topjohnwu
d3858b81e2 Add new boot service: boot-complete 2018-08-09 14:52:44 +08:00
topjohnwu
bdff9769be Move remount,ro back to post-fs-data mode 2018-08-09 03:57:29 +08:00
Ilya Kushnir
c61df75e5e Update RU strings 2018-08-09 03:25:32 +08:00
vvb2060
a74bf2cc27 Update zh-rCN translation 2018-08-09 03:25:15 +08:00
topjohnwu
ada0f93686 Apply all sepolicy patches pre-init
Boot services tend to fail in the middle when the kernel loads a sepolicy live.
It seems that moving full patch (allow magisk * * *) to late_start is still not enough to fix service startup failures.
So screw it, apply all patched in magiskinit, which makes sure that all rules are only loaded in a single step.
The only down side is that some OEM with a HUGE set of secontexts (e.g. Samsung) might suffer a slightly longer boot time, which IS the reason why the rules are split to 2 parts in the first place.
2018-08-09 03:20:28 +08:00
topjohnwu
ff36f2ba17 Add 1 more byte to mark
Prevent crashes on higher Android versions
2018-08-09 03:01:33 +08:00
topjohnwu
5164cfd399 Move butterknife config to full only 2018-08-08 23:09:29 +08:00
topjohnwu
5fa021503e Update to libsu 2.0.1 2018-08-08 18:57:55 +08:00
topjohnwu
7b5d79d313 Kill all processes using the same UID of the target
To workaround OOS embryo optimization
2018-08-08 05:47:58 +08:00
topjohnwu
3e3f38500d Only use required memory size 2018-08-08 03:20:37 +08:00
topjohnwu
5109b9abfd Allow modules be managed in core only mode, and add notice in UI 2018-08-07 16:31:00 +08:00
topjohnwu
7fb4777c1c Improve update channel settings
Fix #446
2018-08-07 15:48:43 +08:00
topjohnwu
c38533e0f8 Prevent problematic modules causing device stuck in bootloop
If boot failed after 2 times, it will enable core only mode (which disables all modules)
2018-08-07 04:41:48 +08:00
dark-basic #DarkBasic BasicHD
51ba99d09e Update Strings Spanish
New Line Added.
2018-08-07 02:24:12 +08:00
topjohnwu
9159f86a9e Improvements to system_root devices booting as recovery 2018-08-07 02:20:40 +08:00
topjohnwu
e139f4fc13 Small build script adjustments 2018-08-06 19:32:37 +08:00
tonymanou
2fbfeacb87 Show toast when intent to open a link is not resolved 2018-08-06 18:56:20 +08:00
tonymanou
ebb7a9fcda Open links in a new task 2018-08-06 18:56:20 +08:00
tonymanou
9e72317302 Ensure intent are resolved when opening link 2018-08-06 18:56:20 +08:00
topjohnwu
d764c20c08 Fix crash on boot on Android pre-O
Close #448
2018-08-06 18:52:28 +08:00
topjohnwu
9c17b8a098 Better subprocess support
Close #444
2018-08-06 02:01:04 +08:00
Ilya Kushnir
3084873154 Fix missing RU translate 2018-08-05 23:34:05 +08:00
topjohnwu
32809e56d0 Sign release zips with release-key.jks
Close #408
2018-08-05 02:29:40 +08:00
topjohnwu
9f05b182a2 Verify existing file checksum to prevent needless downloads 2018-08-05 00:37:02 +08:00
vvb2060
525484e834 Update zh-rCN translation 2018-08-03 23:12:16 +08:00
Rom
65a4e69cae Updating French translation
According to commit `20e0fe3`
2018-08-03 23:12:07 +08:00
Ilya Kushnir
e973f8bab9 Update RU strings pt.2 2018-08-03 23:11:54 +08:00
Albert I
92466671ff Update Indonesian translations
Signed-off-by: Albert I <krascgq@outlook.co.id>
2018-08-03 23:09:40 +08:00
Eray Rafet
6d61106070 Update Bulgarian 2018-08-03 23:09:31 +08:00
Ilya Kushnir
ac13749fb8 Update UK strings 2018-08-03 23:09:21 +08:00
Ilya Kushnir
7ec1a9a316 Update RU strings 2018-08-03 23:09:21 +08:00
topjohnwu
cf17e21ad3 Proper callback to trigger UI update 2018-08-03 23:04:35 +08:00
topjohnwu
0e0240c4ab Better download UI 2018-08-03 22:48:44 +08:00
topjohnwu
d1b290b91a Fix install failure 2018-08-03 22:41:53 +08:00
topjohnwu
a63696836c Proper addon.d-v2 support 2018-08-03 22:40:49 +08:00
topjohnwu
46aad00f16 Use buffer on stack 2018-08-03 21:30:44 +08:00
topjohnwu
252afe8932 Use mirror in post-fs-data scripts 2018-08-03 17:09:24 +08:00
topjohnwu
9dd467a613 Update Trad. Chinese translations 2018-08-03 05:29:17 +08:00
topjohnwu
4c14df67cc Add warning before installing to inactive slot 2018-08-03 05:19:46 +08:00
Eray Rafet
20e0fe3ba1 Update Bulgarian 2018-08-03 04:56:29 +08:00
vvb2060
6a005135f2 Update zh-rCN translation 2018-08-03 04:56:21 +08:00
topjohnwu
82e8375957 Respect filesystem type when mounting mirrors
Close #405
2018-08-03 04:45:07 +08:00
topjohnwu
bb25edc09e Use own busybox for get_outfd 2018-08-03 04:25:00 +08:00
topjohnwu
169c0fe4af Stop use clashing names 2018-08-03 03:43:02 +08:00
topjohnwu
cd6918e6eb Stop altering PATH to mirror 2018-08-03 03:38:36 +08:00
topjohnwu
5be035fd44 Try logging a little harder 2018-08-03 01:58:56 +08:00
topjohnwu
f1edc8443c Make root shell always use dev_pts
Close #433
2018-08-02 20:29:18 +08:00
topjohnwu
d9564bd04c Delay full sepolicy patch loading time 2018-08-02 05:35:01 +08:00
topjohnwu
35f1c396f2 Request write external storage permission 2018-08-02 04:27:01 +08:00
topjohnwu
6acb950990 Simplify repo update logic 2018-08-02 01:55:34 +08:00
topjohnwu
27e0d1641a Show proper time of repo updates 2018-08-02 01:55:34 +08:00
topjohnwu
9ac71ff8af Simplify asynchronous tasks 2018-08-02 00:41:10 +08:00
topjohnwu
075737a4ec Fix crash 2018-08-01 18:56:11 +08:00
topjohnwu
6d0e4a6a5e Rename base activity and fragments 2018-08-01 17:57:11 +08:00
topjohnwu
a2544768a0 Remove boilderplate 2018-08-01 14:30:59 +08:00
topjohnwu
8574a14ed2 Improve locale settings 2018-08-01 14:16:44 +08:00
topjohnwu
e90c555c18 Some cleanups 2018-08-01 03:09:44 +08:00
topjohnwu
863b9a410f Rewrite Topics 2018-08-01 00:47:31 +08:00
topjohnwu
23c7bbc7d5 Move Const to upper package 2018-07-31 17:42:35 +08:00
topjohnwu
f900189f90 Rename and move methods 2018-07-31 17:41:54 +08:00
topjohnwu
7c74be2790 Create LocaleManager 2018-07-31 17:35:58 +08:00
topjohnwu
70dd2d4829 More moving 2018-07-31 16:57:52 +08:00
topjohnwu
914b7ee056 Start moving things outside of top Application class 2018-07-31 03:51:11 +08:00
topjohnwu
e39f83edbf Do not unmount database when cleaning up repackaged manager 2018-07-31 01:09:25 +08:00
topjohnwu
52fe0c6abb Fix restore manager on Android P 2018-07-31 01:05:56 +08:00
darken
5cb3e5937f Update policy list when resuming the superuser fragment.
Closes #414
2018-07-30 21:52:36 +08:00
dark-basic #DarkBasic BasicHD
e0cd224831 Update Strings.xml Spanish
New Line added.
2018-07-30 21:51:07 +08:00
Madis
de225ac64a Estonian update
Made all latest strings.xml files evenly translated with English ones
2018-07-30 21:51:07 +08:00
Oliver Cervera
5807808a10 Update Italian Translation
Added and translated new strings after commit b8eaff6
2018-07-30 21:51:07 +08:00
switchtegrax1
362877d18f Update strings.xml
Just Updated the brazilian translation for the Inactive Slot Option
2018-07-30 21:51:07 +08:00
Rom
88b8dd0149 Update French translation 2018-07-30 21:51:07 +08:00
topjohnwu
1552f32e09 Keep the methods in SN check interface
For some reason, Proguard optimization will remove the method
2018-07-30 20:42:42 +08:00
topjohnwu
50b73a6720 Clear up more component in stub APK 2018-07-30 20:37:00 +08:00
topjohnwu
53e51f1735 Allow incomplete update JSONs 2018-07-29 23:36:29 +08:00
topjohnwu
40b63bfebe Don't use DownloadManager for Magisk 2018-07-29 22:58:22 +08:00
topjohnwu
89861eceef Install to Second Slot -> Install to Inactive slot 2018-07-29 15:45:04 +08:00
topjohnwu
b8eaff66fa Shrink snet APK, and prevent crashing 2018-07-28 23:40:41 +08:00
topjohnwu
a747fdd27d Organize dialog code 2018-07-28 22:52:40 +08:00
topjohnwu
27851bdefa Update README.md 2018-07-28 15:10:06 +08:00
topjohnwu
3fdeb40ddf Update SNET extension dialog interface 2018-07-28 14:56:14 +08:00
topjohnwu
546c7cebd3 Fix #411 2018-07-27 22:44:09 +08:00
topjohnwu
473902f5f4 Proper detect MagiskHide status 2018-07-27 22:32:47 +08:00
topjohnwu
41c0721159 Use internal thread pool for update repos 2018-07-27 21:59:30 +08:00
topjohnwu
413d4badfd Strip logging code with Proguard 2018-07-27 21:52:09 +08:00
topjohnwu
c5d67ebf72 Update libsu to 2.0.0 2018-07-27 04:48:32 +08:00
topjohnwu
91818cfa1a Support compiling split cils via magiskpolicy CLI 2018-07-21 05:12:22 +08:00
topjohnwu
6263d684d9 Migrate to JobIntentService to prevent boot notification 2018-07-21 02:59:36 +08:00
topjohnwu
07140d33a7 Bring back installing to second slot after OTA on A/B devices 2018-07-21 01:59:28 +08:00
topjohnwu
4ffc388491 Allow bootctl to run 2018-07-20 22:22:49 +08:00
topjohnwu
0ef026c610 Remove system root when running addon.d 2018-07-20 00:37:38 +08:00
294 changed files with 12830 additions and 7569 deletions

View File

@@ -1,7 +1,7 @@
# Magisk
[XDA Announcement Thread](https://forum.xda-developers.com/apps/magisk/official-magisk-v7-universal-systemless-t3473445)
## Building Environment Requirements
1. Python 3.5+: run `build.py` script
2. Java Development Kit (JDK) 8: Compile Magisk Manager and sign zips
3. Latest Android SDK: set `ANDROID_HOME` environment variable to the path to Android SDK
@@ -9,11 +9,19 @@
5. (Windows Only) Python package Colorama: Install with `pip install colorama`, used for ANSI color codes
## Building Notes and Instructions
1. Building is tested on macOS, Ubuntu, and Windows 10 using the latest stable NDK and NDK r10e. Officially released binaries were built with NDK r10e.
2. Set configurations in `config.prop`. A sample file `config.prop.sample` is provided as an example.
3. Run `build.py` with argument `-h` to see the built-in help message. The `-h` option also works for each supported actions, e.g. `./build.py binary -h`
4. By default, `build.py` build binaries and Magisk Manager in debug mode. If you want to build Magisk Manager in release mode (via the `--release` flag), you need a Java Keystore file `release-key.jks` to sign Magisk Manager's APK. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually).
5. The SafetyNet extension pack requires the full Magisk Manager as a `compileOnly` dependency. Build the **release** APK, convert it back to Java `.class` files (I use [dex2jar](https://github.com/pxb1988/dex2jar)), and place the converted JAR under `snet/libs` before compiling.
1. Clone sources with submodules: `git clone --recurse-submodules https://github.com/topjohnwu/Magisk.git`
2. Building is supported on macOS, Linux, and Windows. Official releases are built and tested with [FrankeNDK](https://github.com/topjohnwu/FrankeNDK); point `ANDROID_NDK_HOME` to FrankeNDK if you want to use it for compiling.
3. Set configurations in `config.prop`. A sample file `config.prop.sample` is provided as an example.
4. Run `build.py` with argument `-h` to see the built-in help message. The `-h` option also works for each supported actions, e.g. `./build.py binary -h`
5. By default, `build.py` build binaries and Magisk Manager in debug mode. If you want to build Magisk Manager in release mode (via the `-r, --release` flag), you need a Java Keystore file `release-key.jks` (only `JKS` format is supported) to sign APKs and zips. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually).
## Bug Reports
**Make sure to install the latest [Canary Build](https://forum.xda-developers.com/apps/magisk/dev-magisk-canary-channel-bleeding-edge-t3839337) before reporting any bugs!** Please **DO NOT** report bugs that is already fixed upstream.
Follow the instructions in the [Canary Channel XDA Thread](https://forum.xda-developers.com/apps/magisk/dev-magisk-canary-channel-bleeding-edge-t3839337), and report a bug either by opening an issue on GitHub or directly in the thread.
## Documentation
[Link to Documentation](docs/README.MD)
## License
@@ -31,44 +39,3 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
```
## Credits
**MagiskManager** (`app`)
* Copyright 2016-2018, John Wu (@topjohnwu)
* All contributors and translators on Github
**MagiskSU** (`native/jni/su`)
* Copyright 2016-2018, John Wu (@topjohnwu)
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
* Copyright 2013, Koushik Dutta (@koush)
* Copyright 2010, Adam Shanks (@ChainsDD)
* Copyright 2008, Zinx Verituse (@zinxv)
**MagiskPolicy** (`native/jni/magiskpolicy`)
* Copyright 2016-2018, John Wu (@topjohnwu)
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
* Copyright 2015, Joshua Brindle (@joshua_brindle)
**MagiskHide** (`native/jni/magiskhide`)
* Copyright 2016-2018, John Wu (@topjohnwu)
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me)
**resetprop** (`native/jni/resetprop`)
* Copyright 2016-2018 John Wu (@topjohnwu)
* Copyright 2016 nkk71 (nkk71x@gmail.com)
**External Dependencies** (`native/jni/external`)
* Makefile for busybox, generated by [ndk-busybox-kitchen](https://github.com/topjohnwu/ndk-busybox-kitchen)
* Each dependencies has its own license/copyright information in each subdirectory.
All of them are either GPL or GPL compatible.
**Others Not Mentioned**
* Copyright 2016-2018, John Wu (@topjohnwu)

View File

@@ -1,7 +1,7 @@
# Magisk Manager
This repo is no longer an independent component. It is a submodule of the [Magisk Project](https://github.com/topjohnwu/Magisk).
This repo is no longer an independent component. It is merged into the [Magisk Project](https://github.com/topjohnwu/Magisk).
# Translations
The default (English) string resources are scattered in these files: `src/full/res/values/strings.xml`, `src/main/res/values/strings.xml`, `src/stub/res/values/strings.xml`.
Place the translated XMLs in the corresponding folder to the locale.
Translations are highly appreciated via pull requests here on Github.
The default (English) strings are mainly in `src/full/res/values/strings.xml`; some are scattered in `src/main/res/values/strings.xml` and `src/stub/res/values/strings.xml`.
Translations are highly appreciated via pull requests here on Github.
Place translated XMLs in the corresponding locale folder.

View File

@@ -1,5 +1,9 @@
apply plugin: 'com.android.application'
def configProps = new Properties()
def configPath = project.hasProperty('configPath') ? project.configPath : rootProject.file('config.prop')
configProps.load(new FileInputStream(configPath))
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
@@ -8,18 +12,28 @@ android {
applicationId "com.topjohnwu.magisk"
minSdkVersion 21
targetSdkVersion rootProject.ext.compileSdkVersion
javaCompileOptions {
annotationProcessorOptions {
argument('butterknife.debuggable', 'false')
}
}
signingConfigs {
config {
storeFile rootProject.file('release-key.jks')
storePassword configProps['keyStorePass']
keyAlias configProps['keyAlias']
keyPassword configProps['keyPass']
}
}
buildTypes {
debug {
// If keystore exists, sign the APK with custom signature
if (signingConfigs.config.storeFile.exists())
signingConfig signingConfigs.config
}
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
@@ -27,8 +41,13 @@ android {
productFlavors {
full {
versionCode 129
versionName "5.8.3"
versionName configProps['appVersion']
versionCode configProps['appVersionCode'] as Integer
javaCompileOptions {
annotationProcessorOptions {
argument('butterknife.debuggable', 'false')
}
}
}
stub {
versionCode 1
@@ -52,14 +71,12 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
fullImplementation project(':utils')
implementation "com.android.support:support-core-utils:${rootProject.ext.supportLibVersion}"
fullImplementation "com.android.support:preference-v7:${rootProject.ext.supportLibVersion}"
fullImplementation "com.android.support:recyclerview-v7:${rootProject.ext.supportLibVersion}"
fullImplementation "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}"
fullImplementation "com.android.support:design:${rootProject.ext.supportLibVersion}"
fullImplementation 'com.github.topjohnwu:libsu:1.3.0'
implementation "androidx.core:core:${rootProject.ext.androidXVersion}"
fullImplementation "androidx.preference:preference:${rootProject.ext.androidXVersion}"
fullImplementation "androidx.recyclerview:recyclerview:${rootProject.ext.androidXVersion}"
fullImplementation "androidx.cardview:cardview:${rootProject.ext.androidXVersion}"
fullImplementation "com.google.android.material:material:${rootProject.ext.androidXVersion}"
fullImplementation 'com.github.topjohnwu:libsu:2.0.2'
fullImplementation 'com.atlassian.commonmark:commonmark:0.11.0'
fullImplementation 'org.kamranzafar:jtar:2.3'
fullImplementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}

View File

@@ -16,14 +16,20 @@
# public *;
#}
# Keep all names, we are open source anyway :)
-keepnames class ** { *; }
# BouncyCastle
-keep class org.bouncycastle.jcajce.provider.asymmetric.rsa.**SHA1** { *; }
-keep class org.bouncycastle.jcajce.provider.asymmetric.RSA** { *; }
-keep class org.bouncycastle.jcajce.provider.digest.SHA1** { *; }
-dontwarn javax.naming.**
# Gson
-keepattributes Signature
# Snet extention
-keepclassmembers class com.topjohnwu.magisk.utils.ISafetyNetHelper { *; }
# Strip logging
-assumenosideeffects class com.topjohnwu.magisk.utils.Logger {
public *** debug(...);
}
# Excessive obfuscation
-repackageclasses 'a'
-allowaccessmodification

View File

@@ -1,21 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.topjohnwu.magisk">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".MagiskManager"
android:theme="@style/AppTheme">
android:name="a.q"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<!-- Activities -->
<activity
android:name=".MainActivity"
android:name="a.b"
android:configChanges="orientation|screenSize"
android:exported="true" />
<activity
android:name=".SplashActivity"
android:name="a.c"
android:configChanges="orientation|screenSize"
android:exported="true"
android:theme="@style/SplashTheme">
@@ -25,57 +30,75 @@
</intent-filter>
</activity>
<activity
android:name=".AboutActivity"
android:name="a.d"
android:theme="@style/AppTheme.StatusBar" />
<activity
android:name=".SettingsActivity"
android:theme="@style/AppTheme.StatusBar" />
android:name="a.e"
android:theme="@style/AppTheme.StatusBar"/>
<activity
android:name=".FlashActivity"
android:name="a.f"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="nosensor"
android:theme="@style/AppTheme.StatusBar" />
<activity
android:name=".NoUIActivity"
android:name="a.g"
android:theme="@style/AppTheme.Translucent" />
<!-- Superuser -->
<activity
android:name=".superuser.RequestActivity"
android:name="a.p"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:taskAffinity="internal.superuser"
android:theme="@style/SuRequest" />
<activity
android:name=".superuser.RequestActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:taskAffinity="internal.superuser"
android:theme="@style/AppTheme.Translucent" />
<receiver android:name=".superuser.SuReceiver" />
<receiver android:name=".receivers.BootReceiver">
<!-- Receiver -->
<receiver android:name="a.h">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.PackageReceiver">
<receiver android:name="a.i">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.ManagerUpdate" />
<receiver android:name=".receivers.RebootReceiver" />
<receiver android:name=".receivers.ShortcutReceiver">
<receiver android:name="a.j" />
<receiver android:name="a.k" />
<receiver android:name="a.l">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
<service android:name=".services.OnBootIntentService" />
<!-- Service -->
<service
android:name=".services.UpdateCheckService"
android:name="a.m"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name="a.n"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- Hardcode GMS version -->
<meta-data
android:name="com.google.android.gms.version"
android:value="7095000" />
android:value="12451000" />
</application>

View File

@@ -0,0 +1,10 @@
package a;
import com.topjohnwu.magisk.utils.BootSigner;
import androidx.annotation.Keep;
@Keep
public class a extends BootSigner {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.MainActivity;
public class b extends MainActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.SplashActivity;
public class c extends SplashActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.AboutActivity;
public class d extends AboutActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.DonationActivity;
public class e extends DonationActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.FlashActivity;
public class f extends FlashActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.BootReceiver;
public class h extends BootReceiver {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.PackageReceiver;
public class i extends PackageReceiver {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.ManagerUpdate;
public class j extends ManagerUpdate {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.RebootReceiver;
public class k extends RebootReceiver {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
public class l extends ShortcutReceiver {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.services.OnBootService;
public class m extends OnBootService {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.services.UpdateCheckService;
public class n extends UpdateCheckService {
/* stub */
}

View File

@@ -0,0 +1,22 @@
package a;
import android.content.Context;
import android.util.AttributeSet;
import com.topjohnwu.magisk.components.AboutCardRow;
public class o extends AboutCardRow {
/* stub */
public o(Context context) {
super(context);
}
public o(Context context, AttributeSet attrs) {
super(context, attrs);
}
public o(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.SuRequestActivity;
public class p extends SuRequestActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.MagiskManager;
public class q extends MagiskManager {
/* stub */
}

View File

@@ -1,33 +1,30 @@
package com.topjohnwu.magisk;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
import com.topjohnwu.magisk.components.AboutCardRow;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.utils.Utils;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
public class AboutActivity extends Activity {
public class AboutActivity extends BaseActivity {
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.app_version_info) AboutCardRow appVersionInfo;
@BindView(R.id.app_changelog) AboutCardRow appChangelog;
@BindView(R.id.app_translators) AboutCardRow appTranslators;
@BindView(R.id.app_source_code) AboutCardRow appSourceCode;
@BindView(R.id.support_thread) AboutCardRow supportThread;
@BindView(R.id.donation) AboutCardRow donation;
Toolbar toolbar;
AboutCardRow appVersionInfo;
AboutCardRow appChangelog;
AboutCardRow appTranslators;
AboutCardRow appSourceCode;
AboutCardRow supportThread;
AboutCardRow twitter;
@Override
public int getDarkTheme() {
@@ -38,7 +35,7 @@ public class AboutActivity extends Activity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
ButterKnife.bind(this);
ViewBinder.bind(this);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish());
@@ -52,7 +49,6 @@ public class AboutActivity extends Activity {
appVersionInfo.setSummary(String.format(Locale.US, "%s (%d) (%s)",
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, getPackageName()));
appChangelog.removeSummary();
appChangelog.setOnClickListener(v -> {
new MarkDownWindow(this, getString(R.string.app_changelog),
getResources().openRawResource(R.raw.changelog)).exec();
@@ -65,14 +61,9 @@ public class AboutActivity extends Activity {
appTranslators.setSummary(translators);
}
appSourceCode.removeSummary();
appSourceCode.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Const.Url.SOURCE_CODE_URL))));
supportThread.removeSummary();
supportThread.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Const.Url.XDA_THREAD))));
donation.removeSummary();
donation.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Const.Url.DONATION_URL))));
appSourceCode.setOnClickListener(v -> Utils.openLink(this, Uri.parse(Const.Url.SOURCE_CODE_URL)));
supportThread.setOnClickListener(v -> Utils.openLink(this, Uri.parse(Const.Url.XDA_THREAD)));
twitter.setOnClickListener(v -> Utils.openLink(this, Uri.parse(Const.Url.TWITTER_URL)));
setFloating();
}

View File

@@ -1,11 +1,7 @@
package com.topjohnwu.magisk.utils;
package com.topjohnwu.magisk;
import android.os.Environment;
import android.os.Process;
import com.topjohnwu.magisk.BuildConfig;
import com.topjohnwu.magisk.MagiskManager;
import java.io.File;
import java.util.Arrays;
import java.util.List;
@@ -34,21 +30,19 @@ public class Const {
public static final String BUSYBOX_PATH = "/sbin/.core/busybox";
public static final String TMP_FOLDER_PATH = "/dev/tmp";
public static final String MAGISK_LOG = "/cache/magisk.log";
public static final File EXTERNAL_PATH = new File(Environment.getExternalStorageDirectory(), "MagiskManager");
public static final String MANAGER_CONFIGS = ".tmp.magisk.config";
// Versions
public static final int UPDATE_SERVICE_VER = 1;
public static final int SNET_VER = 8;
public static int MIN_MODULE_VER() {
return MagiskManager.get().magiskVersionCode >= MAGISK_VER.REMOVE_LEGACY_LINK ? 1500 : 1400;
return Data.magiskVersionCode >= MAGISK_VER.REMOVE_LEGACY_LINK ? 1500 : 1400;
}
/* A list of apps that should not be shown as hide-able */
public static final List<String> HIDE_BLACKLIST = Arrays.asList(
"android",
MagiskManager.get().getPackageName(),
Data.MM().getPackageName(),
"com.google.android.gms"
);
@@ -59,22 +53,22 @@ public class Const {
public static final int FBE_AWARE = 1410;
public static final int RESETPROP_PERSIST = 1436;
public static final int MANAGER_HIDE = 1440;
public static final int DTBO_SUPPORT = 1446;
public static final int HIDDEN_PATH = 1460;
public static final int REMOVE_LEGACY_LINK = 1630;
public static final int SEPOL_REFACTOR = 1640;
public static final int FIX_ENV = 1650;
public static final int DBVER_SIX = 17000;
}
public static class ID {
public static final int UPDATE_SERVICE_ID = 1;
public static final int FETCH_ZIP = 2;
public static final int SELECT_BOOT = 3;
public static final int ONBOOT_SERVICE_ID = 6;
// notifications
public static final int MAGISK_UPDATE_NOTIFICATION_ID = 4;
public static final int APK_UPDATE_NOTIFICATION_ID = 5;
public static final int ONBOOT_NOTIFICATION_ID = 6;
public static final int DTBO_NOTIFICATION_ID = 7;
public static final String NOTIFICATION_CHANNEL = "magisk_notification";
}
@@ -82,11 +76,12 @@ public class Const {
public static class Url {
public static final String STABLE_URL = "https://raw.githubusercontent.com/topjohnwu/magisk_files/master/stable.json";
public static final String BETA_URL = "https://raw.githubusercontent.com/topjohnwu/magisk_files/master/beta.json";
public static final String SNET_URL = "https://github.com/topjohnwu/magisk_files/raw/727aa3a8642bf5f0982e5ea89b3f818bd783d5a2/snet.apk";
public static final String REPO_URL = "https://api.github.com/users/Magisk-Modules-Repo/repos?per_page=100&page=%d";
public static final String REPO_URL = "https://api.github.com/users/Magisk-Modules-Repo/repos?per_page=100&sort=pushed&page=%d";
public static final String FILE_URL = "https://raw.githubusercontent.com/Magisk-Modules-Repo/%s/master/%s";
public static final String ZIP_URL = "https://github.com/Magisk-Modules-Repo/%s/archive/master.zip";
public static final String DONATION_URL = "https://www.paypal.me/topjohnwu";
public static final String PAYPAL_URL = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=CC7FZ7526MNGG";
public static final String PATREON_URL = "https://www.patreon.com/topjohnwu";
public static final String TWITTER_URL = "https://twitter.com/topjohnwu";
public static final String XDA_THREAD = "http://forum.xda-developers.com/showthread.php?t=3432382";
public static final String SOURCE_CODE_URL = "https://github.com/topjohnwu/Magisk";
}
@@ -108,7 +103,6 @@ public class Const {
public static final String OPEN_SECTION = "section";
public static final String INTENT_SET_FILENAME = "filename";
public static final String INTENT_SET_LINK = "link";
public static final String INTENT_PERM = "perm_dialog";
public static final String FLASH_ACTION = "action";
public static final String FLASH_SET_BOOT = "boot";
@@ -147,16 +141,13 @@ public class Const {
public static final int NAMESPACE_MODE_ISOLATE = 2;
public static final int NO_NOTIFICATION = 0;
public static final int NOTIFICATION_TOAST = 1;
public static final int NOTIFY_NORMAL_LOG = 0;
public static final int NOTIFY_USER_TOASTS = 1;
public static final int NOTIFY_USER_TO_OWNER = 2;
public static final int SU_PROMPT = 0;
public static final int SU_AUTO_DENY = 1;
public static final int SU_AUTO_ALLOW = 2;
public static final String FLASH_ZIP = "flash";
public static final String PATCH_BOOT = "patch";
public static final String FLASH_MAGISK = "magisk";
public static final String FLASH_SECOND_SLOT = "slot";
public static final String FLASH_INACTIVE_SLOT = "slot";
public static final String UNINSTALL = "uninstall";
public static final int[] timeoutList = {0, -1, 10, 20, 30, 60};
public static final int ORDER_NAME = 0;

View File

@@ -0,0 +1,218 @@
package com.topjohnwu.magisk;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.util.Xml;
import com.topjohnwu.magisk.components.AboutCardRow;
import com.topjohnwu.magisk.receivers.BootReceiver;
import com.topjohnwu.magisk.receivers.ManagerUpdate;
import com.topjohnwu.magisk.receivers.PackageReceiver;
import com.topjohnwu.magisk.receivers.RebootReceiver;
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
import com.topjohnwu.magisk.services.OnBootService;
import com.topjohnwu.magisk.services.UpdateCheckService;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.io.SuFile;
import com.topjohnwu.superuser.io.SuFileInputStream;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
public class Data {
// Global app instance
public static WeakReference<MagiskManager> weakApp;
public static Handler mainHandler = new Handler(Looper.getMainLooper());
public static Map<Class, Class> classMap = new HashMap<>();
// Current status
public static String magiskVersionString;
public static int magiskVersionCode = -1;
public static boolean magiskHide;
// Update Info
public static String remoteMagiskVersionString;
public static int remoteMagiskVersionCode = -1;
public static String magiskLink;
public static String magiskNoteLink;
public static String magiskMD5;
public static String remoteManagerVersionString;
public static int remoteManagerVersionCode = -1;
public static String managerLink;
public static String managerNoteLink;
public static String uninstallerLink;
public static int snetVersionCode;
public static String snetLink;
// Install flags
public static boolean keepVerity = false;
public static boolean keepEnc = false;
// Configs
public static boolean isDarkTheme;
public static int suRequestTimeout;
public static int suLogTimeout = 14;
public static int suAccessState;
public static boolean suFingerprint;
public static int multiuserMode;
public static int suResponseType;
public static int suNotificationType;
public static int suNamespaceMode;
public static int updateChannel;
public static int repoOrder;
static {
classMap.put(MagiskManager.class, a.q.class);
classMap.put(MainActivity.class, a.b.class);
classMap.put(SplashActivity.class, a.c.class);
classMap.put(AboutActivity.class, a.d.class);
classMap.put(DonationActivity.class, a.e.class);
classMap.put(FlashActivity.class, a.f.class);
classMap.put(NoUIActivity.class, a.g.class);
classMap.put(BootReceiver.class, a.h.class);
classMap.put(PackageReceiver.class, a.i.class);
classMap.put(ManagerUpdate.class, a.j.class);
classMap.put(RebootReceiver.class, a.k.class);
classMap.put(ShortcutReceiver.class, a.l.class);
classMap.put(OnBootService.class, a.m.class);
classMap.put(UpdateCheckService.class, a.n.class);
classMap.put(AboutCardRow.class, a.o.class);
classMap.put(SuRequestActivity.class, a.p.class);
}
public static void loadMagiskInfo() {
try {
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0];
magiskVersionCode = Integer.parseInt(ShellUtils.fastCmd("magisk -V"));
String s = ShellUtils.fastCmd((magiskVersionCode >= Const.MAGISK_VER.RESETPROP_PERSIST ?
"resetprop -p " : "getprop ") + Const.MAGISKHIDE_PROP);
magiskHide = s.isEmpty() || Integer.parseInt(s) != 0;
} catch (NumberFormatException ignored) {}
}
public static MagiskManager MM() {
return weakApp.get();
}
public static void exportPrefs() {
// Flush prefs to disk
MagiskManager mm = MM();
mm.prefs.edit().commit();
File xml = new File(mm.getFilesDir().getParent() + "/shared_prefs",
mm.getPackageName() + "_preferences.xml");
Shell.su(Utils.fmt("for usr in /data/user/*; do cat %s > ${usr}/%s; done", xml, Const.MANAGER_CONFIGS)).exec();
}
public static void importPrefs() {
MagiskManager mm = MM();
SuFile config = new SuFile(Utils.fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS));
if (config.exists()) {
SharedPreferences.Editor editor = mm.prefs.edit();
try {
SuFileInputStream is = new SuFileInputStream(config);
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, "UTF-8");
parser.nextTag();
parser.require(XmlPullParser.START_TAG, null, "map");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG)
continue;
String key = parser.getAttributeValue(null, "name");
String value = parser.getAttributeValue(null, "value");
switch (parser.getName()) {
case "string":
parser.require(XmlPullParser.START_TAG, null, "string");
editor.putString(key, parser.nextText());
parser.require(XmlPullParser.END_TAG, null, "string");
break;
case "boolean":
parser.require(XmlPullParser.START_TAG, null, "boolean");
editor.putBoolean(key, Boolean.parseBoolean(value));
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "boolean");
break;
case "int":
parser.require(XmlPullParser.START_TAG, null, "int");
editor.putInt(key, Integer.parseInt(value));
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "int");
break;
case "long":
parser.require(XmlPullParser.START_TAG, null, "long");
editor.putLong(key, Long.parseLong(value));
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "long");
break;
case "float":
parser.require(XmlPullParser.START_TAG, null, "int");
editor.putFloat(key, Float.parseFloat(value));
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "int");
break;
default:
parser.next();
}
}
} catch (IOException | XmlPullParserException e) {
e.printStackTrace();
}
editor.remove(Const.Key.ETAG_KEY);
editor.apply();
loadConfig();
config.delete();
}
}
public static void loadConfig() {
MagiskManager mm = MM();
// su
suRequestTimeout = Utils.getPrefsInt(mm.prefs, Const.Key.SU_REQUEST_TIMEOUT, Const.Value.timeoutList[2]);
suResponseType = Utils.getPrefsInt(mm.prefs, Const.Key.SU_AUTO_RESPONSE, Const.Value.SU_PROMPT);
suNotificationType = Utils.getPrefsInt(mm.prefs, Const.Key.SU_NOTIFICATION, Const.Value.NOTIFICATION_TOAST);
suAccessState = mm.mDB.getSettings(Const.Key.ROOT_ACCESS, Const.Value.ROOT_ACCESS_APPS_AND_ADB);
multiuserMode = mm.mDB.getSettings(Const.Key.SU_MULTIUSER_MODE, Const.Value.MULTIUSER_MODE_OWNER_ONLY);
suNamespaceMode = mm.mDB.getSettings(Const.Key.SU_MNT_NS, Const.Value.NAMESPACE_MODE_REQUESTER);
suFingerprint = mm.mDB.getSettings(Const.Key.SU_FINGERPRINT, 0) != 0;
if (suFingerprint && !FingerprintHelper.canUseFingerprint()) {
// User revoked the fingerprint
mm.mDB.setSettings(Const.Key.SU_FINGERPRINT, 0);
suFingerprint = false;
}
// config
isDarkTheme = mm.prefs.getBoolean(Const.Key.DARK_THEME, false);
updateChannel = Utils.getPrefsInt(mm.prefs, Const.Key.UPDATE_CHANNEL, Const.Value.STABLE_CHANNEL);
repoOrder = mm.prefs.getInt(Const.Key.REPO_ORDER, Const.Value.ORDER_DATE);
}
public static void writeConfig() {
MM().prefs.edit()
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
.putBoolean(Const.Key.HOSTS, Const.MAGISK_HOST_FILE.exists())
.putBoolean(Const.Key.COREONLY, Const.MAGISK_DISABLE_FILE.exists())
.putBoolean(Const.Key.SU_FINGERPRINT, suFingerprint)
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
.putString(Const.Key.ROOT_ACCESS, String.valueOf(suAccessState))
.putString(Const.Key.SU_MULTIUSER_MODE, String.valueOf(multiuserMode))
.putString(Const.Key.SU_MNT_NS, String.valueOf(suNamespaceMode))
.putString(Const.Key.UPDATE_CHANNEL, String.valueOf(updateChannel))
.putInt(Const.Key.UPDATE_SERVICE_VER, Const.UPDATE_SERVICE_VER)
.putInt(Const.Key.REPO_ORDER, repoOrder)
.apply();
}
}

View File

@@ -0,0 +1,43 @@
package com.topjohnwu.magisk;
import android.net.Uri;
import android.os.Bundle;
import com.topjohnwu.magisk.components.AboutCardRow;
import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.utils.Utils;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
public class DonationActivity extends BaseActivity {
Toolbar toolbar;
AboutCardRow paypal;
AboutCardRow patreon;
@Override
public int getDarkTheme() {
return R.style.AppTheme_StatusBar_Dark;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_donation);
ViewBinder.bind(this);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish());
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setTitle(R.string.donation);
ab.setDisplayHomeAsUpEnabled(true);
}
paypal.setOnClickListener(v -> Utils.openLink(this, Uri.parse(Const.Url.PAYPAL_URL)));
patreon.setOnClickListener(v -> Utils.openLink(this, Uri.parse(Const.Url.PATREON_URL)));
}
}

View File

@@ -1,11 +1,9 @@
package com.topjohnwu.magisk;
import android.Manifest;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
@@ -16,9 +14,10 @@ import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.FlashZip;
import com.topjohnwu.magisk.asyncs.InstallMagisk;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.utils.Download;
import com.topjohnwu.magisk.utils.RootUtils;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.CallbackList;
import com.topjohnwu.superuser.Shell;
@@ -30,51 +29,48 @@ import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
public class FlashActivity extends Activity {
public class FlashActivity extends BaseActivity {
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.txtLog) TextView flashLogs;
@BindView(R.id.button_panel) public LinearLayout buttonPanel;
@BindView(R.id.reboot) public Button reboot;
@BindView(R.id.scrollView) ScrollView sv;
Toolbar toolbar;
TextView flashLogs;
public LinearLayout buttonPanel;
public Button reboot;
ScrollView sv;
private List<String> logs;
@OnClick(R.id.no_thanks)
void dismiss() {
finish();
}
@OnClick(R.id.reboot)
void reboot() {
Shell.Async.su("/system/bin/reboot");
Shell.su("/system/bin/reboot").submit();
}
@OnClick(R.id.save_logs)
void saveLogs() {
Calendar now = Calendar.getInstance();
String filename = String.format(Locale.US,
"install_log_%04d%02d%02d_%02d%02d%02d.log",
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
runWithPermission(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, () -> {
Calendar now = Calendar.getInstance();
String filename = String.format(Locale.US,
"magisk_install_log_%04d%02d%02d_%02d%02d%02d.log",
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
File logFile = new File(Const.EXTERNAL_PATH + "/logs", filename);
logFile.getParentFile().mkdirs();
try (FileWriter writer = new FileWriter(logFile)) {
for (String s : logs) {
writer.write(s);
writer.write('\n');
File logFile = new File(Download.EXTERNAL_PATH, filename);
try (FileWriter writer = new FileWriter(logFile)) {
for (String s : logs) {
writer.write(s);
writer.write('\n');
}
} catch (IOException e) {
e.printStackTrace();
return;
}
} catch (IOException e) {
e.printStackTrace();
return;
}
MagiskManager.toast(logFile.getPath(), Toast.LENGTH_LONG);
Utils.toast(logFile.getPath(), Toast.LENGTH_LONG);
});
}
@Override
@@ -86,7 +82,7 @@ public class FlashActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flash);
ButterKnife.bind(this);
ViewBinder.bind(this);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
if (ab != null) {
@@ -99,11 +95,23 @@ public class FlashActivity extends Activity {
logs = new ArrayList<>();
CallbackList<String> console = new CallbackList<String>(new ArrayList<>()) {
private void updateUI() {
flashLogs.setText(TextUtils.join("\n", this));
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);
}
@Override
public void onAddElement(String s) {
logs.add(s);
flashLogs.setText(TextUtils.join("\n", this));
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);
updateUI();
}
@Override
public String set(int i, String s) {
String ret = super.set(i, s);
Data.mainHandler.post(this::updateUI);
return ret;
}
};
@@ -119,14 +127,15 @@ public class FlashActivity extends Activity {
new UninstallMagisk(this, uri, console, logs).exec();
break;
case Const.Value.FLASH_MAGISK:
new InstallMagisk(this, console, logs, uri, InstallMagisk.DIRECT_MODE).exec();
new InstallMagisk(this, console, logs, InstallMagisk.DIRECT_MODE).exec();
break;
case Const.Value.FLASH_SECOND_SLOT:
new InstallMagisk(this, console, logs, uri, InstallMagisk.SECOND_SLOT_MODE).exec();
case Const.Value.FLASH_INACTIVE_SLOT:
new InstallMagisk(this, console, logs, InstallMagisk.SECOND_SLOT_MODE).exec();
break;
case Const.Value.PATCH_BOOT:
new InstallMagisk(this, console, logs, uri,
intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)).exec();
runWithPermission(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
() -> new InstallMagisk(this, console, logs,
intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)).exec());
break;
}
}
@@ -138,14 +147,14 @@ public class FlashActivity extends Activity {
private static class UninstallMagisk extends FlashZip {
private UninstallMagisk(Activity context, Uri uri, List<String> console, List<String> logs) {
private UninstallMagisk(BaseActivity context, Uri uri, List<String> console, List<String> logs) {
super(context, uri, console, logs);
}
@Override
protected void onPostExecute(Integer result) {
if (result == 1) {
new Handler().postDelayed(() ->
Data.mainHandler.postDelayed(() ->
RootUtils.uninstallPkg(getActivity().getPackageName()), 3000);
} else {
super.onPostExecute(result);

File diff suppressed because it is too large Load Diff

View File

@@ -3,37 +3,40 @@ package com.topjohnwu.magisk;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
import com.google.android.material.navigation.NavigationView;
import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.fragments.LogFragment;
import com.topjohnwu.magisk.fragments.MagiskFragment;
import com.topjohnwu.magisk.fragments.MagiskHideFragment;
import com.topjohnwu.magisk.fragments.ModulesFragment;
import com.topjohnwu.magisk.fragments.ReposFragment;
import com.topjohnwu.magisk.fragments.SettingsFragment;
import com.topjohnwu.magisk.fragments.SuperuserFragment;
import com.topjohnwu.magisk.utils.Download;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import butterknife.BindView;
import butterknife.ButterKnife;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends Activity
public class MainActivity extends BaseActivity
implements NavigationView.OnNavigationItemSelectedListener, Topic.Subscriber {
private final Handler mDrawerHandler = new Handler();
private int mDrawerItem;
private boolean fromShortcut = true;
private static boolean fromShortcut = false;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.drawer_layout) DrawerLayout drawer;
@BindView(R.id.nav_view) public NavigationView navigationView;
public Toolbar toolbar;
DrawerLayout drawer;
NavigationView navigationView;
private float toolbarElevation;
@@ -44,27 +47,14 @@ public class MainActivity extends Activity
@Override
protected void onCreate(final Bundle savedInstanceState) {
MagiskManager mm = getMagiskManager();
if (!mm.hasInit) {
Intent intent = new Intent(this, SplashActivity.class);
String section = getIntent().getStringExtra(Const.Key.OPEN_SECTION);
if (section != null) {
intent.putExtra(Const.Key.OPEN_SECTION, section);
}
startActivity(intent);
startActivity(new Intent(this, Data.classMap.get(SplashActivity.class)));
finish();
}
String perm = getIntent().getStringExtra(Const.Key.INTENT_PERM);
if (perm != null) {
ActivityCompat.requestPermissions(this, new String[] { perm }, 0);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
ViewBinder.bind(this);
setSupportActionBar(toolbar);
@@ -86,8 +76,11 @@ public class MainActivity extends Activity
drawer.addDrawerListener(toggle);
toggle.syncState();
if (savedInstanceState == null)
navigate(getIntent().getStringExtra(Const.Key.OPEN_SECTION));
if (savedInstanceState == null) {
String section = getIntent().getStringExtra(Const.Key.OPEN_SECTION);
fromShortcut = section != null;
navigate(section);
}
navigationView.setNavigationItemSelectedListener(this);
}
@@ -118,28 +111,21 @@ public class MainActivity extends Activity
}
@Override
public void onTopicPublished(Topic topic) {
public void onPublish(int topic, Object[] result) {
recreate();
}
@Override
public Topic[] getSubscription() {
return new Topic[] { getMagiskManager().reloadActivity };
}
public void checkHideSection() {
MagiskManager mm = getMagiskManager();
Menu menu = navigationView.getMenu();
menu.findItem(R.id.magiskhide).setVisible(
Shell.rootAccess() && mm.magiskVersionCode >= Const.MAGISK_VER.UNIFIED
&& mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false));
menu.findItem(R.id.modules).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false) &&
Shell.rootAccess() && mm.magiskVersionCode >= 0);
menu.findItem(R.id.downloads).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false)
&& Utils.checkNetworkStatus() && Shell.rootAccess() && mm.magiskVersionCode >= 0);
menu.findItem(R.id.magiskhide).setVisible(Shell.rootAccess() &&
Data.magiskVersionCode >= Const.MAGISK_VER.UNIFIED &&
mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false));
menu.findItem(R.id.modules).setVisible(Shell.rootAccess() && Data.magiskVersionCode >= 0);
menu.findItem(R.id.downloads).setVisible(Download.checkNetworkStatus(this)
&& Shell.rootAccess() && Data.magiskVersionCode >= 0);
menu.findItem(R.id.log).setVisible(Shell.rootAccess());
menu.findItem(R.id.superuser).setVisible(Shell.rootAccess() &&
!(Const.USER_ID > 0 && mm.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED));
!(Const.USER_ID > 0 && Data.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED));
}
public void navigate(String item) {
@@ -167,6 +153,9 @@ public class MainActivity extends Activity
case "about":
itemId = R.id.app_about;
break;
case "donation":
itemId = R.id.donation;
break;
}
}
navigate(itemId);
@@ -197,11 +186,14 @@ public class MainActivity extends Activity
displayFragment(new LogFragment(), false);
break;
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class));
mDrawerItem = bak;
displayFragment(new SettingsFragment(), true);
break;
case R.id.app_about:
startActivity(new Intent(this, AboutActivity.class));
startActivity(new Intent(this, Data.classMap.get(AboutActivity.class)));
mDrawerItem = bak;
break;
case R.id.donation:
startActivity(new Intent(this, Data.classMap.get(DonationActivity.class)));
mDrawerItem = bak;
break;
}

View File

@@ -1,23 +1,10 @@
package com.topjohnwu.magisk;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const;
public class NoUIActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] perms = getIntent().getStringArrayExtra(Const.Key.INTENT_PERM);
if (perms != null) {
ActivityCompat.requestPermissions(this, perms, 0);
}
}
import androidx.annotation.NonNull;
public class NoUIActivity extends BaseActivity {
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);

View File

@@ -1,126 +0,0 @@
package com.topjohnwu.magisk;
import android.app.AlertDialog;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SearchView;
import android.widget.TextView;
import com.topjohnwu.magisk.adapters.ReposAdapter;
import com.topjohnwu.magisk.asyncs.UpdateRepos;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Topic;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class ReposFragment extends Fragment implements Topic.Subscriber {
private Unbinder unbinder;
private MagiskManager mm;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyRv;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
public static ReposAdapter adapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_repos, container, false);
unbinder = ButterKnife.bind(this, view);
mm = getApplication();
mSwipeRefreshLayout.setRefreshing(mm.repoLoadDone.isPending());
mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.VISIBLE);
emptyRv.setVisibility(View.GONE);
new UpdateRepos(true).exec();
});
getActivity().setTitle(R.string.downloads);
return view;
}
@Override
public void onResume() {
adapter = new ReposAdapter(mm.repoDB, mm.moduleMap);
recyclerView.setAdapter(adapter);
super.onResume();
}
@Override
public void onPause() {
super.onPause();
adapter = null;
}
@Override
public void onTopicPublished(Topic topic) {
mSwipeRefreshLayout.setRefreshing(false);
recyclerView.setVisibility(adapter.getItemCount() == 0 ? View.GONE : View.VISIBLE);
emptyRv.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
@Override
public Topic[] getSubscription() {
return new Topic[] { mm.repoLoadDone };
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_repo, menu);
SearchView search = (SearchView) menu.findItem(R.id.repo_search).getActionView();
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.filter(newText);
return false;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.repo_sort) {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.sorting_order)
.setSingleChoiceItems(R.array.sorting_orders, mm.repoOrder, (d, which) -> {
mm.repoOrder = which;
mm.prefs.edit().putInt(Const.Key.REPO_ORDER, mm.repoOrder).apply();
adapter.notifyDBChanged();
d.dismiss();
}).show();
}
return true;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,33 +7,34 @@ import android.os.Build;
import android.os.Bundle;
import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.asyncs.LoadModules;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.asyncs.UpdateRepos;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.RootUtils;
import com.topjohnwu.magisk.utils.Download;
import com.topjohnwu.magisk.utils.LocaleManager;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
public class SplashActivity extends Activity {
public class SplashActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RootUtils.init();
MagiskManager mm = getMagiskManager();
// Magisk working as expected
if (Shell.rootAccess() && Data.magiskVersionCode > 0) {
// Update check service
Utils.setupUpdateCheck();
// Load modules
Utils.loadModules();
}
mm.repoDB = new RepoDatabaseHelper(this);
mm.loadMagiskInfo();
mm.getDefaultInstallFlags();
mm.loadPrefs();
Data.importPrefs();
// Dynamic detect all locales
new LoadLocale().exec();
LocaleManager.loadAvailableLocales();
// Create notification channel on Android O
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -43,46 +44,24 @@ public class SplashActivity extends Activity {
}
// Setup shortcuts
sendBroadcast(new Intent(this, ShortcutReceiver.class));
sendBroadcast(new Intent(this, Data.classMap.get(ShortcutReceiver.class)));
LoadModules loadModuleTask = new LoadModules();
if (Utils.checkNetworkStatus()) {
if (Download.checkNetworkStatus(this)) {
// Fire update check
new CheckUpdates().exec();
// Add repo update check
loadModuleTask.setCallBack(() -> new UpdateRepos(false).exec());
}
// Magisk working as expected
if (Shell.rootAccess() && mm.magiskVersionCode > 0) {
// Update check service
mm.setupUpdateCheck();
// Fire asynctasks
loadModuleTask.exec();
CheckUpdates.check();
// Repo update check
new UpdateRepos().exec();
}
// Write back default values
mm.writeConfig();
Data.writeConfig();
mm.hasInit = true;
Intent intent = new Intent(this, MainActivity.class);
Intent intent = new Intent(this, Data.classMap.get(MainActivity.class));
intent.putExtra(Const.Key.OPEN_SECTION, getIntent().getStringExtra(Const.Key.OPEN_SECTION));
intent.putExtra(Const.Key.INTENT_PERM, getIntent().getStringExtra(Const.Key.INTENT_PERM));
intent.putExtra(BaseActivity.INTENT_PERM, getIntent().getStringExtra(BaseActivity.INTENT_PERM));
startActivity(intent);
finish();
}
static class LoadLocale extends ParallelTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
MagiskManager.get().locales = Utils.getAvailableLocale();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
MagiskManager.get().localeDone.publish();
}
}
}

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