1
mirror of https://github.com/topjohnwu/Magisk synced 2025-10-27 04:02:14 +01:00

Compare commits

...

345 Commits

Author SHA1 Message Date
topjohnwu
1adf331268 Bump version 2017-12-29 04:03:05 +08:00
topjohnwu
349b3e961b More robust sudb handling 2017-12-29 04:01:39 +08:00
topjohnwu
96650c06f0 Fix the issue that installation configs won't stick 2017-12-29 03:21:51 +08:00
dark-basic #DarkBasic BasicHD
26038a0a07 Update strings.xml 2017-12-29 01:44:36 +08:00
topjohnwu
6a148b5dd9 Add sorting repo by update time 2017-12-27 01:07:33 +08:00
topjohnwu
0e109ef979 Remove snet version checkpoint, always check by code 2017-12-26 18:24:43 +08:00
topjohnwu
de2285d5e9 Bump version 2017-12-26 03:59:28 +08:00
topjohnwu
b2483ba437 Add version check within binary 2017-12-26 03:59:28 +08:00
topjohnwu
a82a5e5a49 Update snet.apk 2017-12-26 03:57:22 +08:00
topjohnwu
d161a02e71 Fix bug in sudb init 2017-12-25 01:38:38 +08:00
Ilya Kushnir
d2b6a700b1 Update RU strings 2017-12-25 01:37:05 +08:00
Matthias Urhahn
af203cef24 Update strings.xml
Improved german translation.
2017-12-25 01:36:52 +08:00
Madis
673e917e76 et: Missing strings and improvements 2017-12-25 01:36:38 +08:00
RoySchutte
a3bd41db54 Update strings.xml 2017-12-25 01:36:20 +08:00
topjohnwu
0d9527921a Fix su time limits 2017-12-22 06:43:55 +08:00
topjohnwu
f0e4aec0af Bump version 2017-12-22 02:36:26 +08:00
topjohnwu
b0d65b5edd Improve compatibility 2017-12-22 02:36:26 +08:00
topjohnwu
75532ef591 Add recommended KEEPVERITY and KEEPFORCEENCRYPT flags 2017-12-22 02:36:20 +08:00
topjohnwu
9a6d1bd700 Add self package into blacklist 2017-12-22 02:36:20 +08:00
topjohnwu
a7ed6c15d3 More precise sudb management 2017-12-22 02:36:15 +08:00
vvb2060
5ee49ba065 Update zh-rCN translation 2017-12-22 00:40:38 +08:00
topjohnwu
d34bd47bea Read full css into memory for MarkdownWindow 2017-12-20 00:40:19 +08:00
topjohnwu
f17792380b Update Trad. Chinese translation 2017-12-19 23:07:33 +08:00
topjohnwu
c11920110e Update German Translation
Credit: @GuepardoApps
2017-12-19 23:03:09 +08:00
Oliver Cervera
ec5a993fea Update Italian strings
* 2 new strings have been added
2017-12-19 23:01:17 +08:00
linar10
d250c2cc89 Update strings.xml 2017-12-19 23:01:01 +08:00
Grammatopoulos Apostolos
767e73f40c Greek translation updates 2017-12-19 23:00:44 +08:00
Small_Ku
3f699c9d2f Fix a minor translation mistake 2017-12-19 22:59:54 +08:00
dark-basic #DarkBasic BasicHD
50dbd9befd Update Strings.xml 2017-12-19 22:59:16 +08:00
Matthias Sweertvaegher
760e01bf92 request focus for grant button to enable dpad nav
if no buttons have focus, it is impossible to use
on android tv without hooking up a mouse
2017-12-19 22:56:10 +08:00
topjohnwu
543f435b1e Massive improvement of Magisk Manager repackaging 2017-12-19 20:59:59 +08:00
topjohnwu
91337218b3 Update snet configs 2017-12-19 15:46:54 +08:00
topjohnwu
afff3c0a49 Update snet.apk 2017-12-19 15:44:39 +08:00
topjohnwu
a1871e4bc3 Fix install commands 2017-12-18 03:02:19 +08:00
topjohnwu
3aa0294cd4 Fix strings.xml 2017-12-16 23:15:01 +08:00
topjohnwu
310b266251 Fix installation on FBE devices 2017-12-16 04:31:31 +08:00
Grammatopoulos Apostolos
21b1b5098e Greek translation update and fixes 2017-12-16 03:38:41 +08:00
dark-basic #DarkBasic BasicHD
a3a4a5d8a5 Update Strings.xml
It has been compared with strings.xml in English and I have updated based on the new restructuring of the project
2017-12-16 03:38:29 +08:00
Oliver Cervera
270536f33c Update Italian strings
- Now based on new project restructure
- New strings have been added and translated
- Some strings have been revised and updated based on feedback
2017-12-16 03:37:21 +08:00
linar10
66bb433cc6 Update strings.xml 2017-12-16 03:36:58 +08:00
Fatih Fırıncı
bd4ef1a03a Update strings.xml 2017-12-16 03:36:42 +08:00
topjohnwu
aa2d9a3bf1 Support installing to new path 2017-12-16 02:01:04 +08:00
topjohnwu
fd6cbb138c Change new magisk database 2017-12-12 02:35:00 +08:00
topjohnwu
aa75c8e5e4 Fix issues of repackaging with multiuser 2017-12-08 23:38:03 +08:00
topjohnwu
c461fc6daa Adapt with new Magisk installation 2017-12-07 04:20:15 +08:00
topjohnwu
96eaa833f5 Update README.md 2017-12-04 22:59:06 +08:00
topjohnwu
863b13a694 Massive project restructure 2017-12-04 14:21:55 +08:00
Igor Sorocean
e6fea4e6dd Update romanian translation 2017-12-04 13:45:47 +08:00
vvb2060
83bfc13056 Update zh-rCN translation 2017-12-04 13:45:18 +08:00
dark-basic #DarkBasic BasicHD
bc4f09209b Update strings.xml
New Lines Added. --> Add reboot menu
Updated Translations --> Add Changelogs
New Line Added ---> Cleanup prefs
2017-12-04 13:45:05 +08:00
topjohnwu
967ca17238 Fix custom channel dialog 2017-12-03 15:43:07 +08:00
topjohnwu
595c72147c Add dark theme to superuser request 2017-12-03 15:15:00 +08:00
topjohnwu
f3c3b5a649 Cleanup prefs 2017-12-03 04:18:22 +08:00
topjohnwu
1cd2c5e653 Add changelogs 2017-12-03 04:18:22 +08:00
topjohnwu
b2873dd44b Add reboot menu 2017-12-02 22:50:59 +08:00
topjohnwu
bb80ab4026 Support migrating settings after repackage 2017-12-02 02:35:07 +08:00
topjohnwu
80cabb338b Java has native inputstream wrapper 2017-12-01 11:42:05 +08:00
topjohnwu
2c69e2c151 Update SignAPK to use less memory 2017-12-01 11:19:38 +08:00
linar10
c1dd23f5e0 Update strings.xml 2017-11-30 00:08:14 +08:00
Jonas Schubert
f93624a41c updated german translation 2017-11-30 00:08:04 +08:00
Albert I
9f4559a059 Initial Indonesian translations
This brings Indonesian language support to Magisk Manager.

Signed-off-by: Albert I <krascgq@outlook.co.id>
2017-11-30 00:07:52 +08:00
Igor Sorocean
fd05cad303 Update romanian translation 2017-11-30 00:07:37 +08:00
Madis
d58b06e493 Estonian update
New strings and better wording
2017-11-30 00:07:22 +08:00
Mevlüt TOPÇU
2f0b549027 Update strings.xml 2017-11-25 00:31:58 +08:00
Ilya Kushnir
87dbd7e541 Update RU strings 2017-11-25 00:31:50 +08:00
topjohnwu
96e5da36be Update snet.apk link 2017-11-24 22:25:42 +08:00
topjohnwu
43745edac0 Fix crashes when Google Play Service require update 2017-11-24 22:15:46 +08:00
topjohnwu
f5ceee547c Bump version 2017-11-23 23:34:46 +08:00
topjohnwu
b612bce779 Add FLAG_ACTIVITY_NEW_TASK flag for updates 2017-11-23 23:26:06 +08:00
topjohnwu
2e88e5e9c7 Fix strings 2017-11-23 23:19:31 +08:00
Primokorn
9a7aa25c90 Update FR strings.xml 2017-11-23 23:18:13 +08:00
uvera
c4420fe932 Create values-sr
Serbian translation
2017-11-23 23:18:04 +08:00
Oliver Cervera
a5260f3a95 Update Italian strings 2017-11-23 23:17:47 +08:00
topjohnwu
47ccf4b1f5 Bump version 2017-11-23 01:06:19 +08:00
topjohnwu
a356b21895 Prevent hiding Magisk Manager on old Magisk versions 2017-11-23 01:06:18 +08:00
dark-basic #DarkBasic BasicHD
614a36c888 Update strings.xml
New Lines added.
2017-11-23 00:12:23 +08:00
topjohnwu
f520fe36bd Update to use new paths 2017-11-22 14:03:15 +08:00
vvb2060
7273a1c34d Update zh-rCN translation 2017-11-21 21:49:40 +08:00
Oliver Cervera
dc45cbce37 Update Italians strings
All new strings translated + clean-up!
2017-11-21 21:49:28 +08:00
topjohnwu
708d8f75c0 Notify su db corruption 2017-11-21 02:21:37 +08:00
dark-basic #DarkBasic BasicHD
bd37d90228 Update strings.xml 2017-11-21 02:15:14 +08:00
topjohnwu
b1ad691464 Several small fixes 2017-11-21 02:15:13 +08:00
topjohnwu
f4e7baf31e Update snet.apk link 2017-11-21 00:43:13 +08:00
topjohnwu
c0e60c41f2 Update snet extension pack 2017-11-21 00:40:05 +08:00
topjohnwu
c8dad43e00 Fix boot patching 2017-11-21 00:34:25 +08:00
topjohnwu
a8f124704d Allow custom update channels 2017-11-20 03:09:08 +08:00
vvb2060
eed2816491 Update zh-rCN translation 2017-11-19 22:48:29 +08:00
linar10
a6334b3e35 Update strings.xml 2017-11-19 22:48:20 +08:00
topjohnwu
334beebfeb Not all devices work well with streaming 2017-11-19 06:17:31 +08:00
topjohnwu
13dad848bd Fix download progress bug for modules larger than 20MB 2017-11-18 14:17:26 +08:00
topjohnwu
e518f4cef8 Crash proof database: reset if error occurs 2017-11-18 05:17:06 +08:00
topjohnwu
c8fd5da2da Remove unused strings 2017-11-18 05:17:06 +08:00
topjohnwu
3a74729ecc Add saving logs feature for installation 2017-11-18 05:17:06 +08:00
topjohnwu
49c672ac4d Add STDERR support 2017-11-18 05:17:06 +08:00
topjohnwu
b570cb5b77 Extract external path 2017-11-18 05:17:06 +08:00
topjohnwu
97bf388471 Support new module specification 2017-11-18 05:17:05 +08:00
topjohnwu
1a32aaea6f Drawer rearrangement 2017-11-18 05:17:05 +08:00
topjohnwu
4635883dec Update to use adaptive icons 2017-11-18 03:56:34 +08:00
topjohnwu
3ba6db4a50 Update Trad. Chinese translation 2017-11-17 02:28:51 +08:00
Xorok
2f1de25747 Fix color of LogFragment menu items when using dark theme
I set the color directly in the ic_*.xml files instead of using android:iconTint in menu_log.xml (as seen in fragment_magisk.xml) because iconTint is API26+.
2017-11-17 02:14:13 +08:00
daveyannihilation
f60fd42ac0 Expose Flashing colours for themes 2017-11-17 02:03:35 +08:00
RoySchutte
ecc8f9c792 Update strings.xml 2017-11-17 01:45:05 +08:00
dark-basic #DarkBasic BasicHD
e295dfdcf7 Update strings.xml 2017-11-17 01:44:56 +08:00
Oliver Cervera
fc42c25390 Update IT translation for new strings
Updating Italian translation for new strings that have just been pushed.
2017-11-17 01:44:47 +08:00
topjohnwu
27d5858e06 Fix file selection for module install 2017-11-17 01:39:34 +08:00
Generator
e1ef732b60 update pt_PT translation 2017-11-15 05:44:13 +08:00
RoySchutte
9840b95c21 Update strings.xml 2017-11-15 05:44:05 +08:00
linar10
a6f8446d81 Update strings.xml 2017-11-15 05:43:56 +08:00
Oliver Cervera
c1c844c830 Update strings Italian
Urgent correction!
Many strings contain the following character
'
It needs a backslash \ typed in front, otherwise sentences are cut!
2017-11-15 05:43:46 +08:00
topjohnwu
389299afd1 Remove apps from hidelist if uninstalled 2017-11-15 05:36:57 +08:00
topjohnwu
826543a291 Fully support dtbo.img patching 2017-11-15 05:36:57 +08:00
topjohnwu
4ac83cfded Small UI improvement 2017-11-15 00:38:38 +08:00
topjohnwu
64c363ce53 Update repo download progress report 2017-11-09 02:12:55 +08:00
topjohnwu
cca4347bf9 Use handler instead of weird callbacks 2017-11-09 01:43:29 +08:00
topjohnwu
3ae3d4926a Small adjustments to UI 2017-11-09 01:11:50 +08:00
topjohnwu
36025d6d9f Use direct path 2017-11-09 00:03:37 +08:00
topjohnwu
e171362e3e Improve snet.apk downloading 2017-11-07 00:39:48 +08:00
topjohnwu
3e0bf2ae15 Bump version 2017-11-06 23:21:05 +08:00
dark-basic #DarkBasic BasicHD
07aa9f4b8b Update strings.xml
new lines added
2017-11-06 23:04:59 +08:00
Oliver Cervera
b2d9f3fc64 Update Italian IT strings 2017-11-06 23:04:46 +08:00
Taras Korzhak
5fb3e9167e Updated Ukrainian translation 2017-11-06 23:04:28 +08:00
topjohnwu
99c74b31be Improve dynamic permissions 2017-11-06 05:40:41 +08:00
topjohnwu
ce5b13824e Organize application initialization 2017-11-06 04:47:24 +08:00
topjohnwu
c39170c42e Organize constants 2017-11-06 04:41:23 +08:00
topjohnwu
fd19fbf300 Improve Magisk direct install 2017-11-04 04:01:58 +08:00
topjohnwu
166469827f Support new sha1 location 2017-11-03 05:02:14 +08:00
topjohnwu
a34ed538b6 Fix potential bug 2017-11-03 02:25:42 +08:00
topjohnwu
5f22d3e055 Support new xml binary format 2017-10-31 22:48:48 +08:00
topjohnwu
fdd700f3e5 Update boot signing in InstallMagisk 2017-10-31 16:31:58 +08:00
topjohnwu
adf930f126 Finalize bootsigner commandline 2017-10-31 02:55:50 +08:00
topjohnwu
05f41928cd Add boot signing 2017-10-30 03:45:22 +08:00
topjohnwu
2ee0829871 Fix strings.xml 2017-10-30 03:44:03 +08:00
Dmitry Val'd
743560825d Update RU translation
Added new lines from original + corrected mistakes of the previous version of translation
2017-10-29 19:05:22 +08:00
Antoine
e3d84ac349 Update french translation 2017-10-29 19:05:12 +08:00
Dino Dugandžija
266c832b30 Created Croatian translation
I've translated the Magisk Manager app strings.xml to Croatian language. If anything else is needed, please let me know.
2017-10-29 19:04:55 +08:00
topjohnwu
f5374a024e Improve dynamic loading snet package 2017-10-29 14:43:43 +08:00
topjohnwu
4956d826fb Fix UID stored in multiuser mode 2017-10-28 16:19:53 +08:00
topjohnwu
f5cc2af5d0 Repackage Magisk Manager for hiding 2017-10-28 16:19:53 +08:00
topjohnwu
5880d4a6ec Use global su database 2017-10-28 15:50:17 +08:00
topjohnwu
ae05dce958 Improve Shell and logging 2017-10-21 02:28:44 +08:00
topjohnwu
9ebe372a9a Simplify flash log screen 2017-10-21 02:28:44 +08:00
topjohnwu
e6e04cc5b3 Add reference ASAP 2017-10-16 11:51:34 +08:00
topjohnwu
12352510fd Fix strings 2017-10-16 11:47:07 +08:00
vvb2060
2b3d927937 Update zh-rCN translation 2017-10-16 11:11:27 +08:00
Madis
a8890740f5 Created Estonian translation
I translated Magisk Manager to Estonian with the help of an app called Stringlate.
2017-10-16 11:11:19 +08:00
dark-basic #DarkBasic BasicHD
f60d7ee54b Fix Strings.xml
Translation Mistakes corrected.
2017-10-16 11:11:10 +08:00
topjohnwu
896ca2ef6b Cleanup contexts 2017-10-16 00:54:48 +08:00
topjohnwu
c036f6d529 Cleanup Utils 2017-10-15 23:54:34 +08:00
topjohnwu
6f457c0c59 Refactor shell (again) 2017-10-15 23:02:44 +08:00
Dmitry Val'd
13bf1b27b4 Update strings.xml
Added new lines from original
2017-10-15 03:15:39 +08:00
topjohnwu
f742bb1c47 Hot fix for detecting MagiskHide 2017-10-15 03:12:13 +08:00
topjohnwu
aa0b9e2db2 Bump version 2017-10-14 04:18:14 +08:00
topjohnwu
c10076f7ed Remove debug logs 2017-10-14 04:05:41 +08:00
topjohnwu
bcd92499f2 Massive improvement on Online Repo fetching 2017-10-14 04:05:41 +08:00
topjohnwu
b2bb0d4f72 Fix some external storage permission issues 2017-10-14 00:36:10 +08:00
topjohnwu
e140481f14 Wrap wrapper with buffer 2017-10-13 20:47:14 +08:00
topjohnwu
186bd11463 Reconnect until we got content length 2017-10-13 03:25:56 +08:00
topjohnwu
a0490d6687 Update Trad. Chinese translation 2017-10-13 03:10:35 +08:00
killer7mod
beef740ade update strings.xml for PT-BR 2017-10-13 02:45:02 +08:00
Frieder Bluemle
2ac7786a90 Update commonmark to 0.10.0 2017-10-13 02:44:42 +08:00
Frieder Bluemle
a3fb5e910f Update bouncycastle libs to 1.58 2017-10-13 02:44:42 +08:00
Frieder Bluemle
319afe86b5 Update Gradle wrapper to 4.2.1 2017-10-13 02:44:42 +08:00
Frieder Bluemle
762ab66b86 Fix Lint errors 2017-10-13 02:44:42 +08:00
topjohnwu
0c239a42de Allow secondary users to control Superuser settings except multiuser options 2017-10-13 02:41:43 +08:00
dark-basic #DarkBasic BasicHD
e9322fba26 Update strings.xml
New Lines Added
2017-10-07 23:44:10 +08:00
RoySchutte
39b6df27b3 Update strings.xml 2017-10-07 20:55:00 +08:00
topjohnwu
b1ee284e7f Rename resource -> common 2017-10-07 20:48:45 +08:00
topjohnwu
e986332bf2 Several small snet fixes 2017-10-07 20:47:44 +08:00
topjohnwu
48f9b27381 Seperate JarSigner and add task for host 2017-10-07 20:31:49 +08:00
topjohnwu
42a6e0dd10 Seperate Google proprietary code 2017-10-07 17:12:36 +08:00
topjohnwu
d4798b02ac Move functions 2017-10-04 22:27:14 +08:00
topjohnwu
963edfe8ab Add InputStream mode for signing zips 2017-10-04 22:09:59 +08:00
topjohnwu
53237f3ae0 Update Android Studio and Proguard configs 2017-10-04 15:23:08 +08:00
topjohnwu
64da9281a4 Show progress while downloading modules 2017-10-01 02:38:25 +08:00
topjohnwu
ab7fd9799d Remove cache module exception 2017-10-01 01:38:25 +08:00
topjohnwu
f6bcc84251 Improve repo fetching 2017-10-01 01:28:50 +08:00
topjohnwu
35dc3d9df9 Update WebService 2017-10-01 01:12:45 +08:00
topjohnwu
566714a75d Use override functions 2017-09-30 03:25:50 +08:00
topjohnwu
c92f30b122 Re-organize classes 2017-09-30 03:04:23 +08:00
topjohnwu
294ad094c4 Show repo loading progress by showing repos already loaded 2017-09-30 01:15:34 +08:00
topjohnwu
c1a0f520f9 Prevent flash screen close when tapping outside 2017-09-29 13:20:34 +08:00
topjohnwu
773c24b7fc Bump version 2017-09-28 03:55:53 +08:00
topjohnwu
8f926c7ca9 Load scripts in memory 2017-09-28 03:33:56 +08:00
topjohnwu
c562cbc2bb Update zip and magisk installation 2017-09-26 20:46:58 +08:00
topjohnwu
3fbbb0865a Update trad. Chinese 2017-09-26 02:13:39 +08:00
Naboleo
7d5f612a48 Update strings.xml 2017-09-26 03:07:55 +09:00
linar10
4a5a36440b Update strings.xml 2017-09-26 03:07:41 +09:00
Dmitry Val'd
43dd5cfea1 Update RU translation
Added new or missing lines
2017-09-26 03:07:33 +09:00
dark-basic #DarkBasic BasicHD
7b5fec1842 Update strings.xml 2017-09-26 03:07:20 +09:00
topjohnwu
5762ded601 Properly detect hosts file 2017-09-25 17:55:40 +08:00
topjohnwu
a3abb86daa Only place files in de on FDE enabled devices 2017-09-24 21:29:01 +08:00
topjohnwu
4f5c656b05 Update uninstall method 2017-09-16 03:53:13 +08:00
topjohnwu
a31cddbe7b Prevent NPE 2017-09-16 02:41:24 +08:00
topjohnwu
b4ecd93f1c Proper FBE support: place files in DE 2017-09-15 18:03:25 +08:00
topjohnwu
0acc23e058 Allow dialog to popup 2017-09-15 13:55:36 +08:00
topjohnwu
cdd5f9b628 Fix busybox installation 2017-09-15 13:34:53 +08:00
topjohnwu
4c9f5f4655 Support patching second slot 2017-09-15 13:03:10 +08:00
topjohnwu
b80ba13cb4 Fix strings 2017-09-15 03:47:18 +08:00
Santiago Pintos
8260bdc09c Update translations into spanish
Add two strings: "zip_download_title" and "zip_download_msg"
2017-09-13 10:12:13 -05:00
RoySchutte
24f856e02b Update strings.xml 2017-09-13 10:12:03 -05:00
Mevlüt TOPÇU
3aa619b928 Update
Merge please

Thank you
2017-09-13 10:11:53 -05:00
Taras Korzhak
4cb5e98d94 Update Ukrainian translation 2017-09-13 10:11:25 -05:00
Primokorn
272910575e Update FR strings.xml
Stupid typo
Unhide Magisk Manager should not be translated
2017-09-13 10:09:37 -05:00
topjohnwu
a15a62f4bc Move logic to external script file 2017-09-13 23:07:59 +08:00
topjohnwu
53cf11db8c Fix failure if MagiskManager folder doesn't exist 2017-09-13 23:07:59 +08:00
Dmitry Val'd
01052fbe47 Update strings.xml 2017-09-07 10:45:27 +08:00
dark-basic #DarkBasic BasicHD
a5e1e075c7 Update Strings (6-9-17)
Small Update
New Line Added.
2017-09-07 10:45:12 +08:00
c727
6be32ac688 update german strings
small improvements for new strings
also unified some strings

@topjohnwu:
what do you thing about calling the hidden Magsik Manager also "Magisk Manager" instead of "Unhide Magisk Manager"
The hidden status could be symbolized by an incognito style version of the app icon
advantages:
-same position in app drawer
-no need to translate it
2017-09-07 10:45:02 +08:00
topjohnwu
b362c0ef38 Bump version 2017-09-06 23:06:18 +08:00
topjohnwu
bba9969e31 Fix install button hiding 2017-09-06 23:05:51 +08:00
Primokorn
007ba24809 Update FR strings.xml 2017-09-06 22:33:04 +08:00
topjohnwu
df21539311 Some versioning fixes 2017-09-06 22:32:40 +08:00
topjohnwu
2592cb6019 Show Install button after update check done 2017-09-06 16:28:24 +08:00
topjohnwu
f7df17a7ed Small fix 2017-09-06 15:42:45 +08:00
dark-basic #DarkBasic BasicHD
62f42b72f8 Update Strings.xml (05-09-17)
New lines added.
2017-09-06 14:42:22 +08:00
topjohnwu
a1ba4fda6f Improve install Magisk 2017-09-06 14:41:59 +08:00
topjohnwu
1c06b04c45 Use GNU tar format 2017-09-06 13:39:29 +08:00
topjohnwu
2ee22fd374 Add restore stock image feature 2017-09-05 17:43:13 +08:00
topjohnwu
4c230d9e61 Root shell workaround 2017-09-05 13:46:54 +08:00
topjohnwu
727294fbbe Disable D8, dex not compatible with Android 5.0 2017-09-05 02:57:30 +08:00
Dmitry Val'd
478c43969b Update strings.xml
Added missing/new lines
2017-09-05 02:50:36 +08:00
Jens Lody
79b5303350 Update german translation 2017-09-05 02:50:20 +08:00
topjohnwu
ce4b742b25 Support .img.tar as input 2017-09-04 01:57:45 +08:00
topjohnwu
a9dc15bda5 Update TW translations 2017-09-04 01:14:38 +08:00
topjohnwu
ba6387ff5c Resource cleanup! 2017-09-04 00:58:39 +08:00
linar10
8fa98508b7 Update strings.xml 2017-09-03 23:18:12 +08:00
Dmitry Val'd
decdbaecf9 Update strings.xml
Added missing lines
2017-09-03 23:18:02 +08:00
gh2923
6d87cf9be0 Update Simplified Chinese Translation 2017-09-03 23:17:53 +08:00
Leonidas P
94f434c4a6 Translate Update Channel Strings 2017-09-03 23:17:36 +08:00
dark-basic #DarkBasic BasicHD
7ba867c30b Update Strings - (New Update 03-09-17) 2017-09-03 23:17:18 +08:00
topjohnwu
3424395e10 Calculate offset for unhide 2017-09-03 23:00:54 +08:00
topjohnwu
926c7359a2 Merge download and process repo modules 2017-09-03 22:10:54 +08:00
topjohnwu
ec0af99a2e Fix locale settings 2017-09-03 21:12:09 +08:00
topjohnwu
b4d948886c Fix unzip issues 2017-09-03 21:05:57 +08:00
topjohnwu
4d8d79372a Update strings 2017-09-03 18:28:46 +08:00
topjohnwu
04a589722c Support .img.tar format for ODIN 2017-09-03 17:46:00 +08:00
topjohnwu
d4a10e2873 Various adjustments 2017-09-03 17:46:00 +08:00
topjohnwu
4998ad6c7e Show Manager updates in dialogs 2017-09-03 14:58:21 +08:00
topjohnwu
a07ca5ff50 Slightly change busybox handling 2017-09-03 03:26:01 +08:00
topjohnwu
f07e7571ab Change block detection method 2017-09-03 02:45:43 +08:00
topjohnwu
834c16485c Reduce unnecessary code 2017-09-03 02:34:23 +08:00
topjohnwu
04a4265ef3 Show correct message 2017-09-03 00:17:42 +08:00
topjohnwu
0ec473195d Update install Magisk method 2017-09-03 00:10:14 +08:00
topjohnwu
0bf09256b0 Update Android Studio and Gradle 2017-09-02 19:12:03 +08:00
topjohnwu
db8fd2c913 Add boot image file patch 2017-08-31 03:07:33 +08:00
topjohnwu
dbe6e5b3d7 Simplify app startup 2017-08-30 02:28:24 +08:00
topjohnwu
cc81cd446b Extract ExpandableView code into interface 2017-08-29 04:10:04 +08:00
topjohnwu
439c7118f1 Proper runtime permission implementation 2017-08-29 03:08:09 +08:00
topjohnwu
d8154a5815 Update deprecate code 2017-08-29 01:56:43 +08:00
topjohnwu
4e3787bc0d Add beta update channel 2017-08-29 01:34:42 +08:00
topjohnwu
02e0955924 Fix settings crash 2017-08-29 00:37:52 +08:00
topjohnwu
a78950e822 Reduce boilerplate 2017-08-28 00:27:10 +08:00
topjohnwu
1ce1a94a35 Update translations 2017-08-27 01:38:05 +08:00
gh2923
977b6d9f67 Update Simplified Chinese Translation 2017-08-27 01:09:49 +08:00
Igor Sorocean
b5e6dbd797 update romanian translation 2017-08-27 01:09:41 +08:00
Taras
833e6688f1 Added Ukrainian translation 2017-08-27 01:09:33 +08:00
Dmitry Val'd
bc22c9f84f Update strings.xml
Added missing strings
2017-08-27 01:08:25 +08:00
Mevlüt TOPÇU
2149a7d116 Update
Merge please
2017-08-27 01:08:14 +08:00
dark-basic #DarkBasic BasicHD
29175d2c17 Update Strings.xml 2017-08-27 01:07:45 +08:00
Leonidas P
803454d5c8 Update Greek Strings 2017-08-27 01:07:26 +08:00
topjohnwu
36cf32dc42 Change unhide app temp location 2017-08-27 01:04:55 +08:00
topjohnwu
657f4ab303 Add hide Magisk Manager feature 2017-08-22 03:01:54 +08:00
topjohnwu
ea6552615d Bump version 2017-08-13 01:50:20 +08:00
Generator
4bf3287fce update pt_PT 2017-08-13 01:20:04 +08:00
Mevlüt TOPÇU
832c2034c2 Update
Hi,

Update, translations and typo fix

Merge please

Thank you
2017-08-13 01:19:48 +08:00
RJ Trujillo
b0aa26e1f1 More string updates
* A few grammatical corrections were made
* Everything looks cleaner now
2017-08-13 01:19:27 +08:00
dark-basic #DarkBasic BasicHD
e52baeb967 Update Strings.xml 2017-08-13 01:19:15 +08:00
Leonidas P
8268eb9a83 Update strings.xml 2017-08-13 01:18:55 +08:00
topjohnwu
3cc458abd9 Always use global mount namespace 2017-08-12 17:07:28 +08:00
topjohnwu
337b4c4268 Upgrade Android Studio 2017-08-12 15:54:14 +08:00
topjohnwu
001f8657f6 Use global Magisk native busybox for Magisk Manager 2017-08-12 02:25:55 +08:00
topjohnwu
ea884e7fa1 Re-organize application startup 2017-08-12 01:31:34 +08:00
topjohnwu
1b1394cf5d Improve Markdown support
Close #259
2017-08-08 16:12:49 +08:00
topjohnwu
1eef930dbb Move OnClickListener to Butterknife 2017-08-08 16:09:45 +08:00
topjohnwu
1e175e74ed Prevent crashes 2017-08-07 00:15:46 +08:00
John Wu
75a46c365e Update README.md 2017-08-04 00:23:14 +08:00
topjohnwu
8e7b8825f5 Rename callbackevents to topic/subscribers 2017-08-04 00:17:31 +08:00
topjohnwu
2ecbca303b Update Shell 2017-08-03 23:33:08 +08:00
topjohnwu
8195a4d616 Don't ignore libbusybox.so, we want it removed 2017-08-01 23:54:45 +08:00
topjohnwu
7ba40f925f Remove busybox in APK, download from internet 2017-08-01 23:52:39 +08:00
topjohnwu
345cd1795f Update WebService 2017-08-01 23:08:34 +08:00
topjohnwu
959aaee045 Fix FlashZip crash when fails 2017-07-31 01:19:43 +08:00
topjohnwu
53477f0f59 Improve locale settings 2017-07-31 00:44:38 +08:00
topjohnwu
5716218f41 Update busybox version and bug fixes 2017-07-31 00:21:18 +08:00
topjohnwu
9df6b9d5c0 Remove external files from git
These files should be copied to the correct place by Magisk's build script
2017-07-30 23:17:39 +08:00
topjohnwu
ec46031d36 Update Android Studio 2017-07-30 14:41:22 +08:00
RJ Trujillo
55b84d166a Improve dialog strings
* A space should never follow a question mark or any form of punctuation
* Multiple exclamation marks are not needed
2017-07-30 01:36:25 -05:00
Silvered99
34ae8bacec Update strings.xml 2017-07-30 01:36:16 -05:00
RoySchutte
cb4e5ca0f7 Update strings.xml 2017-07-30 01:36:07 -05:00
Leonidas P
0ba45468c4 Fix typos
these pesky little buggers, you never find them...
2017-07-30 01:35:57 -05:00
Frieder Bluemle
710502784e Update Gradle wrapper to 4.1-rc-1 2017-07-30 01:35:46 -05:00
topjohnwu
0275a8558d Fix locale settings duplicate 2017-07-24 18:37:13 +08:00
topjohnwu
58acc75cf6 Fix SuLog UI 2017-07-24 13:15:05 +08:00
topjohnwu
874ababb9f Fix strings.xml 2017-07-24 02:08:58 +08:00
gh2923
3771e6b0cd Update Simplified Chinese Translation 2017-07-24 01:38:55 +08:00
Sopor
33eaefa966 Add Swedish translation 2017-07-24 01:38:43 +08:00
RoySchutte
cd7e236d57 Update strings.xml 2017-07-24 01:38:18 +08:00
Andrei Conache
54c0b7c7d5 update italian translation 2017-07-24 01:38:02 +08:00
zertyuiop
a2177daec2 Update strings.xml 2017-07-24 01:37:42 +08:00
dark-basic #DarkBasic BasicHD
628386b453 Update Spanish strings.xml 2017-07-24 01:37:23 +08:00
Leonidas P
b222bfb3e0 Update Greek translation 2017-07-24 01:36:09 +08:00
topjohnwu
ab199d883d Change su logs time granularity 2017-07-24 01:26:56 +08:00
topjohnwu
356065d1ee Rewrite SuLogAdapter 2017-07-24 01:26:56 +08:00
topjohnwu
76e7c5623d Simplify ApplicationAdapter filter 2017-07-24 01:26:56 +08:00
topjohnwu
085fba050a Introduce self-written SectionedAdapter 2017-07-24 01:26:45 +08:00
topjohnwu
295334d3ac Preserve toolbar elevation when restart activity 2017-07-23 00:47:54 +08:00
topjohnwu
36124ddca4 Update CallbackEvents 2017-07-23 00:39:38 +08:00
topjohnwu
bd6585765e Add locale settings 2017-07-23 00:33:24 +08:00
topjohnwu
c325deb4ed Random changes 2017-07-22 17:39:34 +08:00
topjohnwu
73bb0b10ee Prevent memory leak in CallbackEvent 2017-07-21 05:18:24 +08:00
topjohnwu
72820b162c Code cleanups 2017-07-21 05:08:39 +08:00
topjohnwu
89e5b8d057 Switch to official BouncyCastle 2017-07-21 03:56:48 +08:00
topjohnwu
da4f53ebbb Don't store multiple repo copies in memory 2017-07-21 02:46:19 +08:00
topjohnwu
8458553b74 Update database helper 2017-07-21 02:10:00 +08:00
topjohnwu
55ecc41d06 Bump version 2017-07-20 03:20:17 +08:00
#DarkBasic - BasicHD
28fcdf2cbb Update strings.xml
Delele Translate "Magisk Modo Sólo Núcleo". (After several hours (Days :v ). I thought it was best left in its original form .Magisk Hide, should also be translated if it were the case, it was better to leave it that way so as not to confuse the users.)
Fix translation error
Translations Updates and added new line
2017-07-20 03:19:58 +08:00
topjohnwu
24087679a8 Update uninstaller 2017-07-20 02:56:36 +08:00
topjohnwu
5ac6a8cb4a Small minor updates 2017-07-20 02:54:34 +08:00
topjohnwu
668d85d14e Improve notification support 2017-07-20 01:44:32 +08:00
topjohnwu
c11a3dc95c Fix Magisk Manager freezing issue 2017-07-20 00:51:30 +08:00
topjohnwu
56f57c20a2 Update AsyncTasks to prevent memory leak 2017-07-19 18:01:22 +08:00
topjohnwu
240d14779a Minor cleanup in check updates 2017-07-19 16:10:17 +08:00
topjohnwu
3550d1e61c Bump version 2017-07-19 00:38:25 +08:00
topjohnwu
6513ad249c Fix string.xml 2017-07-19 00:36:54 +08:00
killer7mod
50297b1880 update strings.xml portuguese brazil 2017-07-19 00:25:36 +08:00
#DarkBasic - BasicHD
f189b78b9e #DBC01 - Translation update 2017-07-19 00:25:23 +08:00
zertyuiop
5c0250f495 Fix too long string
checking_safetyNet_status string is too long.
2017-07-19 00:24:47 +08:00
pavlaras
2093f726e9 Update strings.xml
corrected Greek translation
2017-07-19 00:24:36 +08:00
topjohnwu
10efe3859d Update repo fragment and adapter 2017-07-18 23:18:57 +08:00
topjohnwu
6933bcf7bb Merge shells 2017-07-18 17:14:42 +08:00
topjohnwu
2ea046cd80 Add flashing screen 2017-07-18 17:14:42 +08:00
topjohnwu
f4097a372b Root shell with no outputs 2017-07-18 01:06:05 +08:00
topjohnwu
87ea2a2bef Rewrite root shell 2017-07-16 03:00:01 +08:00
JpegXguy
cc14a1c361 Fix untranslated strings 2017-07-15 01:23:59 +08:00
topjohnwu
bcdface60d Fix crashing when installing modules 2017-07-15 01:22:00 +08:00
topjohnwu
4dc9419d2e Bump version 2017-07-14 02:31:29 +08:00
topjohnwu
d2bcac813e Fix update notifications on Android O 2017-07-14 02:27:02 +08:00
topjohnwu
080c37a7f6 Remove busybox from strings 2017-07-14 01:18:20 +08:00
topjohnwu
f9a3838db6 Fix strings 2017-07-13 15:37:00 +08:00
JpegXguy
1e61db104b Added Greek Language 2017-07-13 15:22:53 +08:00
Generator
30a9c7718d Added (European) Portuguese
Split Portuguese into pt_BR and pt_PT
2017-07-13 15:22:40 +08:00
Dmitry Val'd
34b052b5d3 Update strings.xml
Full and correct translation to russian language
2017-07-13 15:21:27 +08:00
topjohnwu
aaa12853ad Prevent crashing when requesting SN check while checking
Fixed #208, fixed #212
2017-07-13 15:12:43 +08:00
topjohnwu
b0ab55b0bf Only show one notification at a time 2017-07-13 14:51:12 +08:00
topjohnwu
d2f8496f4e Update dependency 2017-07-13 14:47:47 +08:00
259 changed files with 9339 additions and 7867 deletions

6
.gitignore vendored
View File

@@ -5,4 +5,8 @@
/build
app/release
*.hprof
app/.externalNativeBuild/
.externalNativeBuild/
*.sh
public.certificate.x509.pem
private.key.pk8
*.apk

View File

@@ -1,6 +1,2 @@
# Magisk Manager
You need to install CMake and NDK to build the zipadjust library for zip preprocessing
## Pre-built Binaries
Busybox (arm and x86) compiled by osm0sis (`libbusybox.so` under `app\src\main\jniLibs`)
Source and more info: [osm0sis' Odds and Ends](https://forum.xda-developers.com/showthread.php?t=2239421)
# Magisk Manager
This repo is no longer an independent component. It is a submodule of the [Magisk Project](https://github.com/topjohnwu/Magisk).

1
app/.gitignore vendored
View File

@@ -1 +0,0 @@
/build

View File

@@ -1,63 +0,0 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
applicationId "com.topjohnwu.magisk"
minSdkVersion 21
targetSdkVersion 26
versionCode 44
versionName "5.0.4"
ndk {
moduleName 'zipadjust'
abiFilters 'x86', 'armeabi-v7a'
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dexOptions {
preDexLibraries true
javaMaxHeapSize "2g"
}
externalNativeBuild {
cmake {
path 'src/main/jni/CMakeLists.txt'
}
}
lintOptions {
disable 'MissingTranslation'
}
}
repositories {
jcenter()
maven { url "https://jitpack.io" }
maven { url "https://maven.google.com" }
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:recyclerview-v7:26.0.0-beta2'
implementation 'com.android.support:cardview-v7:26.0.0-beta2'
implementation 'com.android.support:design:26.0.0-beta2'
implementation 'com.android.support:support-v4:26.0.0-beta2'
implementation 'com.jakewharton:butterknife:8.6.0'
implementation 'com.thoughtbot:expandablerecyclerview:1.4'
implementation 'us.feras.mdv:markdownview:1.1.0'
implementation 'com.madgag.spongycastle:core:1.54.0.0'
implementation 'com.madgag.spongycastle:prov:1.54.0.0'
implementation 'com.madgag.spongycastle:pkix:1.54.0.0'
implementation 'com.google.android.gms:play-services-safetynet:9.0.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
}

View File

@@ -1,137 +0,0 @@
#!/system/bin/sh
##########################################################################################
#
# Magisk Uninstaller
# by topjohnwu
#
# This script can be placed in /cache/magisk_uninstaller.sh
# The Magisk main binary will pick up the script, and uninstall itself, following a reboot
# This script can also be used in flashable zip with the uninstaller_loader.sh
#
# This script will try to do restoration with the following:
# 1-1. Find and restore the original stock boot image dump (OTA proof)
# 1-2. If 1-1 fails, restore ramdisk from the internal backup
# (ramdisk fully restored, not OTA friendly)
# 1-3. If 1-2 fails, it will remove added files in ramdisk, however modified files
# are remained modified, because we have no backups. By doing so, Magisk will
# not be started at boot, but this isn't actually 100% cleaned up
# 2. Remove all Magisk related files
# (The list is LARGE, most likely due to bad decision in early versions
# the latest versions has much less bloat to cleanup)
#
##########################################################################################
# Call ui_print_wrap if exists, or else simply use echo
# Useful when wrapped in flashable zip
ui_print_wrap() {
type ui_print >/dev/null 2>&1 && ui_print "$1" || echo "$1"
}
# Call abort if exists, or else show error message and exit
# Essential when wrapped in flashable zip
abort_wrap() {
type abort >/dev/null 2>&1
if [ $? -ne 0 ]; then
ui_print_wrap "$1"
exit 1
else
abort "$1"
fi
}
if [ ! -d $MAGISKBIN -o ! -f $MAGISKBIN/magiskboot -o ! -f $MAGISKBIN/util_functions.sh ]; then
ui_print_wrap "! Cannot find $MAGISKBIN"
exit 1
fi
[ -z $BOOTMODE ] && BOOTMODE=false
MAGISKBIN=/data/magisk
CHROMEDIR=$MAGISKBIN/chromeos
# Default permissions
umask 022
# Load utility functions
. $MAGISKBIN/util_functions.sh
# Find the boot image
find_boot_image
[ -z $BOOTIMAGE ] && abort "! Unable to detect boot image"
ui_print_wrap "- Found Boot Image: $BOOTIMAGE"
cd $MAGISKBIN
ui_print_wrap "- Unpacking boot image"
./magiskboot --unpack "$BOOTIMAGE"
[ $? -ne 0 ] && abort_wrap "! Unable to unpack boot image"
# Update our previous backup to new format if exists
if [ -f /data/stock_boot.img ]; then
SHA1=`./magiskboot --sha1 /data/stock_boot.img | tail -n 1`
STOCKDUMP=/data/stock_boot_${SHA1}.img
mv /data/stock_boot.img $STOCKDUMP
./magiskboot --compress $STOCKDUMP
fi
# Detect boot image state
./magiskboot --cpio-test ramdisk.cpio
case $? in
0 ) # Stock boot
ui_print_wrap "- Stock boot image detected!"
ui_print_wrap "! Magisk is not installed!"
exit
;;
1 ) # Magisk patched
ui_print_wrap "- Magisk patched image detected!"
# Find SHA1 of stock boot image
if [ -z $SHA1 ]; then
./magiskboot --cpio-extract ramdisk.cpio init.magisk.rc init.magisk.rc.old
SHA1=`grep_prop "# STOCKSHA1" init.magisk.rc.old`
rm -f init.magisk.rc.old
fi
[ ! -z $SHA1 ] && STOCKDUMP=/data/stock_boot_${SHA1}.img
if [ -f ${STOCKDUMP}.gz ]; then
ui_print_wrap "- Boot image backup found!"
./magiskboot --decompress ${STOCKDUMP}.gz stock_boot.img
else
ui_print_wrap "! Boot image backup unavailable"
ui_print_wrap "- Restoring ramdisk with backup"
./magiskboot --cpio-restore ramdisk.cpio
./magiskboot --repack $BOOTIMAGE stock_boot.img
fi
;;
2 ) # Other patched
ui_print_wrap "! Boot image patched by other programs!"
abort_wrap "! Cannot uninstall with this uninstaller"
;;
esac
# Sign chromeos boot
if [ -f chromeos ]; then
echo > empty
LD_LIBRARY_PATH=$SYSTEMLIB $CHROMEDIR/futility vbutil_kernel --pack stock_boot.img.signed \
--keyblock $CHROMEDIR/kernel.keyblock --signprivate $CHROMEDIR/kernel_data_key.vbprivk \
--version 1 --vmlinuz stock_boot.img --config empty --arch arm --bootloader empty --flags 0x1
rm -f empty stock_boot.img
mv stock_boot.img.signed stock_boot.img
fi
ui_print_wrap "- Flashing stock/reverted image"
if [ -L "$BOOTIMAGE" ]; then
dd if=stock_boot.img of="$BOOTIMAGE" bs=4096
else
cat stock_boot.img /dev/zero | dd of="$BOOTIMAGE" bs=4096 >/dev/null 2>&1
fi
rm -f stock_boot.img
ui_print_wrap "- Removing Magisk files"
rm -rf /cache/magisk.log /cache/last_magisk.log /cache/magiskhide.log /cache/.disable_magisk \
/cache/magisk /cache/magisk_merge /cache/magisk_mount /cache/unblock /cache/magisk_uninstaller.sh \
/data/Magisk.apk /data/magisk.apk /data/magisk.img /data/magisk_merge.img /data/magisk_debug.log \
/data/busybox /data/magisk /data/custom_ramdisk_patch.sh 2>/dev/null
$BOOTMODE && reboot

Binary file not shown.

View File

@@ -1,27 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEqDCCA5CgAwIBAgIJAJNurL4H8gHfMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
Fw0wODAyMjkwMTMzNDZaFw0zNTA3MTcwMTMzNDZaMIGUMQswCQYDVQQGEwJVUzET
MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
hvcNAQEBBQADggENADCCAQgCggEBANaTGQTexgskse3HYuDZ2CU+Ps1s6x3i/waM
qOi8qM1r03hupwqnbOYOuw+ZNVn/2T53qUPn6D1LZLjk/qLT5lbx4meoG7+yMLV4
wgRDvkxyGLhG9SEVhvA4oU6Jwr44f46+z4/Kw9oe4zDJ6pPQp8PcSvNQIg1QCAcy
4ICXF+5qBTNZ5qaU7Cyz8oSgpGbIepTYOzEJOmc3Li9kEsBubULxWBjf/gOBzAzU
RNps3cO4JFgZSAGzJWQTT7/emMkod0jb9WdqVA2BVMi7yge54kdVMxHEa5r3b97s
zI5p58ii0I54JiCUP5lyfTwE/nKZHZnfm644oLIXf6MdW2r+6R8CAQOjgfwwgfkw
HQYDVR0OBBYEFEhZAFY9JyxGrhGGBaR0GawJyowRMIHJBgNVHSMEgcEwgb6AFEhZ
AFY9JyxGrhGGBaR0GawJyowRoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJAJNurL4H8gHfMAwGA1Ud
EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHqvlozrUMRBBVEY0NqrrwFbinZa
J6cVosK0TyIUFf/azgMJWr+kLfcHCHJsIGnlw27drgQAvilFLAhLwn62oX6snb4Y
LCBOsVMR9FXYJLZW2+TcIkCRLXWG/oiVHQGo/rWuWkJgU134NDEFJCJGjDbiLCpe
+ZTWHdcwauTJ9pUbo8EvHRkU3cYfGmLaLfgn9gP+pWA7LFQNvXwBnDa6sppCccEX
31I828XzgXpJ4O+mDL1/dBd+ek8ZPUP0IgdyZm5MTYPhvVqGCHzzTy3sIeJFymwr
sBbmg2OAUNLEMO6nwmocSdN2ClirfxqCzJOLSDE4QyS9BAH6EhY6UFcOaE0=
-----END CERTIFICATE-----

View File

@@ -1,192 +0,0 @@
##########################################################################################
#
# Magisk General Utility Functions
# by topjohnwu
#
# Used in flash_script.sh, addon.d.sh, magisk module installers, and uninstaller
#
##########################################################################################
get_outfd() {
readlink /proc/$$/fd/$OUTFD 2>/dev/null | grep /tmp >/dev/null
if [ "$?" -eq "0" ]; then
OUTFD=0
for FD in `ls /proc/$$/fd`; do
readlink /proc/$$/fd/$FD 2>/dev/null | grep pipe >/dev/null
if [ "$?" -eq "0" ]; then
ps | grep " 3 $FD " | grep -v grep >/dev/null
if [ "$?" -eq "0" ]; then
OUTFD=$FD
break
fi
fi
done
fi
}
ui_print() {
if $BOOTMODE; then
echo "$1"
else
echo -n -e "ui_print $1\n" >> /proc/self/fd/$OUTFD
echo -n -e "ui_print\n" >> /proc/self/fd/$OUTFD
fi
}
getvar() {
local VARNAME=$1
local VALUE=$(eval echo \$"$VARNAME");
for FILE in /dev/.magisk /data/.magisk /cache/.magisk /system/.magisk; do
if [ -z "$VALUE" ]; then
LINE=$(cat $FILE 2>/dev/null | grep "$VARNAME=")
if [ ! -z "$LINE" ]; then
VALUE=${LINE#*=}
fi
fi
done
eval $VARNAME=\$VALUE
}
find_boot_image() {
if [ -z "$BOOTIMAGE" ]; then
for BLOCK in boot_a BOOT_A kern-a KERN-A android_boot ANDROID_BOOT kernel KERNEL boot BOOT lnx LNX; do
BOOTIMAGE=`ls /dev/block/by-name/$BLOCK || ls /dev/block/platform/*/by-name/$BLOCK || ls /dev/block/platform/*/*/by-name/$BLOCK` 2>/dev/null
[ ! -z $BOOTIMAGE ] && break
done
fi
# Recovery fallback
if [ -z "$BOOTIMAGE" ]; then
for FSTAB in /etc/*fstab*; do
BOOTIMAGE=`grep -E '\b/boot\b' $FSTAB | grep -v "#" | grep -oE '/dev/[a-zA-Z0-9_./-]*'`
[ ! -z $BOOTIMAGE ] && break
done
fi
[ -L "$BOOTIMAGE" ] && BOOTIMAGE=`readlink $BOOTIMAGE`
}
is_mounted() {
if [ ! -z "$2" ]; then
cat /proc/mounts | grep $1 | grep $2, >/dev/null
else
cat /proc/mounts | grep $1 >/dev/null
fi
return $?
}
grep_prop() {
REGEX="s/^$1=//p"
shift
FILES=$@
if [ -z "$FILES" ]; then
FILES='/system/build.prop'
fi
cat $FILES 2>/dev/null | sed -n "$REGEX" | head -n 1
}
remove_system_su() {
if [ -f /system/bin/su -o -f /system/xbin/su ] && [ ! -f /su/bin/su ]; then
ui_print "! System installed root detected, mount rw :("
mount -o rw,remount /system
# SuperSU
if [ -e /system/bin/.ext/.su ]; then
mv -f /system/bin/app_process32_original /system/bin/app_process32 2>/dev/null
mv -f /system/bin/app_process64_original /system/bin/app_process64 2>/dev/null
mv -f /system/bin/install-recovery_original.sh /system/bin/install-recovery.sh 2>/dev/null
cd /system/bin
if [ -e app_process64 ]; then
ln -sf app_process64 app_process
else
ln -sf app_process32 app_process
fi
fi
rm -rf /system/.pin /system/bin/.ext /system/etc/.installed_su_daemon /system/etc/.has_su_daemon \
/system/xbin/daemonsu /system/xbin/su /system/xbin/sugote /system/xbin/sugote-mksh /system/xbin/supolicy \
/system/bin/app_process_init /system/bin/su /cache/su /system/lib/libsupol.so /system/lib64/libsupol.so \
/system/su.d /system/etc/install-recovery.sh /system/etc/init.d/99SuperSUDaemon /cache/install-recovery.sh \
/system/.supersu /cache/.supersu /data/.supersu \
/system/app/Superuser.apk /system/app/SuperSU /cache/Superuser.apk 2>/dev/null
fi
}
api_level_arch_detect() {
API=`grep_prop ro.build.version.sdk`
ABI=`grep_prop ro.product.cpu.abi | cut -c-3`
ABI2=`grep_prop ro.product.cpu.abi2 | cut -c-3`
ABILONG=`grep_prop ro.product.cpu.abi`
ARCH=arm
IS64BIT=false
if [ "$ABI" = "x86" ]; then ARCH=x86; fi;
if [ "$ABI2" = "x86" ]; then ARCH=x86; fi;
if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; IS64BIT=true; fi;
if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; IS64BIT=true; fi;
}
recovery_actions() {
# TWRP bug fix
mount -o bind /dev/urandom /dev/random
# Temporarily block out all custom recovery binaries/libs
mv /sbin /sbin_tmp
# Add all possible library paths
OLD_LD_PATH=$LD_LIBRARY_PATH
$IS64BIT && export LD_LIBRARY_PATH=/system/lib64:/system/vendor/lib64 || export LD_LIBRARY_PATH=/system/lib:/system/vendor/lib
}
recovery_cleanup() {
mv /sbin_tmp /sbin
# Clear LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$OLD_LD_PATH
ui_print "- Unmounting partitions"
umount -l /system
umount -l /vendor 2>/dev/null
umount -l /dev/random
}
abort() {
ui_print "$1"
mv /sbin_tmp /sbin 2>/dev/null
exit 1
}
set_perm() {
chown $2:$3 $1 || exit 1
chmod $4 $1 || exit 1
if [ ! -z $5 ]; then
chcon $5 $1 2>/dev/null
else
chcon 'u:object_r:system_file:s0' $1 2>/dev/null
fi
}
set_perm_recursive() {
find $1 -type d 2>/dev/null | while read dir; do
set_perm $dir $2 $3 $4 $6
done
find $1 -type f 2>/dev/null | while read file; do
set_perm $file $2 $3 $5 $6
done
}
mktouch() {
mkdir -p ${1%/*}
if [ -z "$2" ]; then
touch $1
else
echo $2 > $1
fi
chmod 644 $1
}
request_size_check() {
reqSizeM=`du -s $1 | cut -f1`
reqSizeM=$((reqSizeM / 1024 + 1))
}
image_size_check() {
SIZE="`$MAGISKBIN/magisk --imgsize $IMG`"
curUsedM=`echo "$SIZE" | cut -d" " -f1`
curSizeM=`echo "$SIZE" | cut -d" " -f2`
curFreeM=$((curSizeM - curUsedM))
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@@ -1,133 +0,0 @@
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.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.TextView;
import com.topjohnwu.magisk.components.AboutCardRow;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import java.io.IOException;
import java.io.InputStream;
import butterknife.BindView;
import butterknife.ButterKnife;
public class AboutActivity extends Activity {
private static final String DONATION_URL = "https://www.paypal.me/topjohnwu";
private static final String XDA_THREAD = "http://forum.xda-developers.com/showthread.php?t=3432382";
private static final String SOURCE_CODE_URL = "https://github.com/topjohnwu/MagiskManager";
@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_developers) AboutCardRow appDevelopers;
@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;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getApplicationContext().isDarkTheme) {
setTheme(R.style.AppTheme_Transparent_Dark);
}
setContentView(R.layout.activity_about);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish());
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setTitle(R.string.about);
ab.setDisplayHomeAsUpEnabled(true);
}
appVersionInfo.setSummary(BuildConfig.VERSION_NAME);
String changes = null;
try (InputStream is = getAssets().open("changelog.html")) {
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
changes = new String(buffer);
} catch (IOException ignored) {
}
appChangelog.removeSummary();
if (changes == null) {
appChangelog.setVisibility(View.GONE);
} else {
Spanned result;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
result = Html.fromHtml(changes, Html.TO_HTML_PARAGRAPH_LINES_CONSECUTIVE);
} else {
result = Html.fromHtml(changes);
}
appChangelog.setOnClickListener(v -> {
AlertDialog d = new AlertDialogBuilder(this)
.setTitle(R.string.app_changelog)
.setMessage(result)
.setPositiveButton(android.R.string.ok, null)
.show();
//noinspection ConstantConditions
((TextView) d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
});
}
appDevelopers.removeSummary();
appDevelopers.setOnClickListener(view -> {
Spanned result;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
result = Html.fromHtml(getString(R.string.app_developers_), Html.TO_HTML_PARAGRAPH_LINES_CONSECUTIVE);
} else {
result = Html.fromHtml(getString(R.string.app_developers_));
}
AlertDialog d = new AlertDialogBuilder(this)
.setTitle(R.string.app_developers)
.setMessage(result)
.setPositiveButton(android.R.string.ok, null)
.create();
d.show();
//noinspection ConstantConditions
((TextView) d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
});
String translators = getString(R.string.translators);
if (TextUtils.isEmpty(translators)) {
appTranslators.setVisibility(View.GONE);
} else {
appTranslators.setSummary(translators);
}
appSourceCode.removeSummary();
appSourceCode.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(SOURCE_CODE_URL))));
supportThread.removeSummary();
supportThread.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(XDA_THREAD))));
donation.removeSummary();
donation.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(DONATION_URL))));
setFloating();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,207 +0,0 @@
package com.topjohnwu.magisk;
import android.app.Application;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.widget.Toast;
import com.topjohnwu.magisk.database.SuDatabaseHelper;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.module.Repo;
import com.topjohnwu.magisk.utils.CallbackEvent;
import com.topjohnwu.magisk.utils.SafetyNetHelper;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ValueSortedMap;
import java.io.File;
import java.util.List;
public class MagiskManager extends Application {
public static final String MAGISK_DISABLE_FILE = "/cache/.disable_magisk";
public static final String TMP_FOLDER_PATH = "/dev/tmp";
public static final String MAGISK_PATH = "/magisk";
public static final String UNINSTALLER = "magisk_uninstaller.sh";
public static final String UTIL_FUNCTIONS= "util_functions.sh";
public static final String INTENT_SECTION = "section";
public static final String BUSYBOX_VERSION = "1.26.2";
public static final String MAGISKHIDE_PROP = "persist.magisk.hide";
public static final String DISABLE_INDICATION_PROP = "ro.magisk.disable";
// Events
public final CallbackEvent<Void> blockDetectionDone = new CallbackEvent<>();
public final CallbackEvent<Void> magiskHideDone = new CallbackEvent<>();
public final CallbackEvent<Void> reloadMainActivity = new CallbackEvent<>();
public final CallbackEvent<Void> moduleLoadDone = new CallbackEvent<>();
public final CallbackEvent<Void> repoLoadDone = new CallbackEvent<>();
public final CallbackEvent<Void> updateCheckDone = new CallbackEvent<>();
public final CallbackEvent<Void> safetyNetDone = new CallbackEvent<>();
// Info
public String magiskVersionString;
public int magiskVersionCode = -1;
public String remoteMagiskVersionString;
public int remoteMagiskVersionCode = -1;
public String magiskLink;
public String releaseNoteLink;
public String remoteManagerVersionString;
public int remoteManagerVersionCode = -1;
public String managerLink;
public SafetyNetHelper.Result SNCheckResult;
public String bootBlock = null;
public boolean isSuClient = false;
public String suVersion = null;
public boolean disabled;
// Data
public ValueSortedMap<String, Repo> repoMap;
public ValueSortedMap<String, Module> moduleMap;
public List<String> blockList;
public List<ApplicationInfo> appList;
public List<String> magiskHideList;
// Configurations
public static boolean shellLogging;
public static boolean devLogging;
public boolean magiskHide;
public boolean isDarkTheme;
public boolean updateNotification;
public boolean suReauth;
public int suRequestTimeout;
public int suLogTimeout = 14;
public int suAccessState;
public int multiuserMode;
public int suResponseType;
public int suNotificationType;
public int suNamespaceMode;
// Global resources
public SharedPreferences prefs;
public SuDatabaseHelper suDB;
private static Handler mHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
prefs = PreferenceManager.getDefaultSharedPreferences(this);
}
public void toast(String msg, int duration) {
mHandler.post(() -> Toast.makeText(this, msg, duration).show());
}
public void toast(int resId, int duration) {
mHandler.post(() -> Toast.makeText(this, resId, duration).show());
}
public void init() {
isDarkTheme = prefs.getBoolean("dark_theme", false);
if (BuildConfig.DEBUG) {
devLogging = prefs.getBoolean("developer_logging", false);
shellLogging = prefs.getBoolean("shell_logging", false);
} else {
devLogging = false;
shellLogging = false;
}
magiskHide = prefs.getBoolean("magiskhide", true);
updateNotification = prefs.getBoolean("notification", true);
initSU();
// Always start a new root shell manually, just for safety
Shell.init();
updateMagiskInfo();
// Initialize busybox
File busybox = new File(getApplicationInfo().dataDir + "/busybox/busybox");
if (!busybox.exists() || !TextUtils.equals(prefs.getString("busybox_version", ""), BUSYBOX_VERSION)) {
busybox.getParentFile().mkdirs();
Shell.su(
"cp -f " + new File(getApplicationInfo().nativeLibraryDir, "libbusybox.so") + " " + busybox,
"chmod -R 755 " + busybox.getParent(),
busybox + " --install -s " + busybox.getParent()
);
}
// Initialize prefs
prefs.edit()
.putBoolean("dark_theme", isDarkTheme)
.putBoolean("magiskhide", magiskHide)
.putBoolean("notification", updateNotification)
.putBoolean("hosts", new File("/magisk/.core/hosts").exists())
.putBoolean("disable", Utils.itemExist(MAGISK_DISABLE_FILE))
.putBoolean("su_reauth", suReauth)
.putString("su_request_timeout", String.valueOf(suRequestTimeout))
.putString("su_auto_response", String.valueOf(suResponseType))
.putString("su_notification", String.valueOf(suNotificationType))
.putString("su_access", String.valueOf(suAccessState))
.putString("multiuser_mode", String.valueOf(multiuserMode))
.putString("mnt_ns", String.valueOf(suNamespaceMode))
.putString("busybox_version", BUSYBOX_VERSION)
.apply();
// Add busybox to PATH
Shell.su("PATH=$PATH:" + busybox.getParent());
}
public void initSUConfig() {
suDB = new SuDatabaseHelper(this);
suRequestTimeout = Utils.getPrefsInt(prefs, "su_request_timeout", 10);
suResponseType = Utils.getPrefsInt(prefs, "su_auto_response", 0);
suNotificationType = Utils.getPrefsInt(prefs, "su_notification", 1);
suReauth = prefs.getBoolean("su_reauth", false);
}
public void initSU() {
// Create the app data directory, so su binary can work properly
new File(getApplicationInfo().dataDir).mkdirs();
initSUConfig();
List<String> ret = Shell.sh("su -v");
if (Utils.isValidShellResponse(ret)) {
suVersion = ret.get(0);
isSuClient = suVersion.toUpperCase().contains("MAGISK");
}
if (isSuClient) {
suAccessState = suDB.getSettings(SuDatabaseHelper.ROOT_ACCESS, 3);
multiuserMode = suDB.getSettings(SuDatabaseHelper.MULTIUSER_MODE, 0);
suNamespaceMode = suDB.getSettings(SuDatabaseHelper.MNT_NS, 1);
}
}
public void updateMagiskInfo() {
List<String> ret;
ret = Shell.sh("magisk -v");
if (!Utils.isValidShellResponse(ret)) {
ret = Shell.sh("getprop magisk.version");
if (Utils.isValidShellResponse(ret)) {
try {
magiskVersionString = ret.get(0);
magiskVersionCode = (int) Double.parseDouble(ret.get(0)) * 10;
} catch (NumberFormatException ignored) {}
}
} else {
magiskVersionString = ret.get(0).split(":")[0];
ret = Shell.sh("magisk -V");
try {
magiskVersionCode = Integer.parseInt(ret.get(0));
} catch (NumberFormatException ignored) {}
}
ret = Shell.sh("getprop " + DISABLE_INDICATION_PROP);
try {
disabled = Utils.isValidShellResponse(ret) && Integer.parseInt(ret.get(0)) != 0;
} catch (NumberFormatException e) {
disabled = false;
}
ret = Shell.sh("getprop " + MAGISKHIDE_PROP);
try {
magiskHide = !Utils.isValidShellResponse(ret) || Integer.parseInt(ret.get(0)) != 0;
} catch (NumberFormatException e) {
magiskHide = true;
}
}
}

View File

@@ -1,216 +0,0 @@
package com.topjohnwu.magisk;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.MenuItemCompat;
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.View;
import android.view.ViewGroup;
import android.widget.SearchView;
import android.widget.TextView;
import com.topjohnwu.magisk.adapters.ReposAdapter;
import com.topjohnwu.magisk.adapters.SimpleSectionedRecyclerViewAdapter;
import com.topjohnwu.magisk.asyncs.LoadRepos;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.module.Repo;
import com.topjohnwu.magisk.utils.CallbackEvent;
import com.topjohnwu.magisk.utils.Logger;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class ReposFragment extends Fragment implements CallbackEvent.Listener<Void> {
private Unbinder unbinder;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyRv;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
private List<Repo> mUpdateRepos = new ArrayList<>();
private List<Repo> mInstalledRepos = new ArrayList<>();
private List<Repo> mOthersRepos = new ArrayList<>();
private List<Repo> fUpdateRepos = new ArrayList<>();
private List<Repo> fInstalledRepos = new ArrayList<>();
private List<Repo> fOthersRepos = new ArrayList<>();
private SimpleSectionedRecyclerViewAdapter mSectionedAdapter;
private SearchView.OnQueryTextListener searchListener;
@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);
mSectionedAdapter = new SimpleSectionedRecyclerViewAdapter(R.layout.section,
R.id.section_text, new ReposAdapter(fUpdateRepos, fInstalledRepos, fOthersRepos));
recyclerView.setAdapter(mSectionedAdapter);
mSwipeRefreshLayout.setRefreshing(true);
mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.GONE);
new LoadRepos(getActivity()).exec();
});
if (getApplication().repoLoadDone.isTriggered) {
reloadRepos();
updateUI();
}
searchListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
new FilterApps().exec(newText);
return false;
}
};
return view;
}
@Override
public void onTrigger(CallbackEvent<Void> event) {
Logger.dev("ReposFragment: UI refresh triggered");
reloadRepos();
updateUI();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_repo, menu);
SearchView search = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.repo_search));
search.setOnQueryTextListener(searchListener);
}
@Override
public void onStart() {
super.onStart();
getApplication().repoLoadDone.register(this);
getActivity().setTitle(R.string.downloads);
}
@Override
public void onStop() {
getApplication().repoLoadDone.unRegister(this);
super.onStop();
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
private void reloadRepos() {
mUpdateRepos.clear();
mInstalledRepos.clear();
mOthersRepos.clear();
for (Repo repo : getApplication().repoMap.values()) {
Module module = getApplication().moduleMap.get(repo.getId());
if (module != null) {
if (repo.getVersionCode() > module.getVersionCode()) {
mUpdateRepos.add(repo);
} else {
mInstalledRepos.add(repo);
}
} else {
mOthersRepos.add(repo);
}
}
fUpdateRepos.clear();
fInstalledRepos.clear();
fOthersRepos.clear();
fUpdateRepos.addAll(mUpdateRepos);
fInstalledRepos.addAll(mInstalledRepos);
fOthersRepos.addAll(mOthersRepos);
}
private void updateUI() {
if (fUpdateRepos.size() + fInstalledRepos.size() + fOthersRepos.size() == 0) {
emptyRv.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
List<SimpleSectionedRecyclerViewAdapter.Section> sections = new ArrayList<>();
if (!fUpdateRepos.isEmpty()) {
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(0, getString(R.string.update_available)));
}
if (!fInstalledRepos.isEmpty()) {
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(fUpdateRepos.size(), getString(R.string.installed)));
}
if (!fOthersRepos.isEmpty()) {
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(fUpdateRepos.size() + fInstalledRepos.size(), getString(R.string.not_installed)));
}
SimpleSectionedRecyclerViewAdapter.Section[] array = sections.toArray(new SimpleSectionedRecyclerViewAdapter.Section[sections.size()]);
mSectionedAdapter.setSections(array);
emptyRv.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
mSwipeRefreshLayout.setRefreshing(false);
}
private class FilterApps extends ParallelTask<String, Void, Void> {
@Override
protected Void doInBackground(String... strings) {
String newText = strings[0];
fUpdateRepos.clear();
fInstalledRepos.clear();
fOthersRepos.clear();
for (Repo repo: mUpdateRepos) {
if (repo.getName().toLowerCase().contains(newText.toLowerCase())
|| repo.getAuthor().toLowerCase().contains(newText.toLowerCase())
|| repo.getDescription().toLowerCase().contains(newText.toLowerCase())
) {
fUpdateRepos.add(repo);
}
}
for (Repo repo: mInstalledRepos) {
if (repo.getName().toLowerCase().contains(newText.toLowerCase())
|| repo.getAuthor().toLowerCase().contains(newText.toLowerCase())
|| repo.getDescription().toLowerCase().contains(newText.toLowerCase())
) {
fInstalledRepos.add(repo);
}
}
for (Repo repo: mOthersRepos) {
if (repo.getName().toLowerCase().contains(newText.toLowerCase())
|| repo.getAuthor().toLowerCase().contains(newText.toLowerCase())
|| repo.getDescription().toLowerCase().contains(newText.toLowerCase())
) {
fOthersRepos.add(repo);
}
}
return null;
}
@Override
protected void onPostExecute(Void v) {
updateUI();
}
}
}

View File

@@ -1,234 +0,0 @@
package com.topjohnwu.magisk;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.MagiskHide;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.database.SuDatabaseHelper;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import butterknife.BindView;
import butterknife.ButterKnife;
public class SettingsActivity extends Activity {
@BindView(R.id.toolbar) Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getApplicationContext().isDarkTheme) {
setTheme(R.style.AppTheme_Transparent_Dark);
}
setContentView(R.layout.activity_settings);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish());
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setTitle(R.string.settings);
ab.setDisplayHomeAsUpEnabled(true);
}
setFloating();
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.container, new SettingsFragment()).commit();
}
}
public static class SettingsFragment extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences prefs;
private PreferenceScreen prefScreen;
private ListPreference suAccess, autoRes, suNotification, requestTimeout, multiuserMode, namespaceMode;
private MagiskManager magiskManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.app_settings);
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
prefScreen = getPreferenceScreen();
magiskManager = Utils.getMagiskManager(getActivity());
PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk");
PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser");
PreferenceCategory developer = (PreferenceCategory) findPreference("developer");
suAccess = (ListPreference) findPreference("su_access");
autoRes = (ListPreference) findPreference("su_auto_response");
requestTimeout = (ListPreference) findPreference("su_request_timeout");
suNotification = (ListPreference) findPreference("su_notification");
multiuserMode = (ListPreference) findPreference("multiuser_mode");
namespaceMode = (ListPreference) findPreference("mnt_ns");
SwitchPreference reauth = (SwitchPreference) findPreference("su_reauth");
setSummary();
// Disable dangerous settings in user mode if selected owner manage
if (getActivity().getApplicationInfo().uid > 99999) {
prefScreen.removePreference(magiskCategory);
prefScreen.removePreference(suCategory);
}
// Remove re-authentication option on Android O, it will not work
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
suCategory.removePreference(reauth);
}
findPreference("clear").setOnPreferenceClickListener((pref) -> {
Utils.clearRepoCache(getActivity());
return true;
});
if (!BuildConfig.DEBUG) {
prefScreen.removePreference(developer);
}
if (!Shell.rootAccess()) {
prefScreen.removePreference(magiskCategory);
prefScreen.removePreference(suCategory);
} else {
if (!magiskManager.isSuClient) {
prefScreen.removePreference(suCategory);
}
if (magiskManager.magiskVersionCode < 1300) {
prefScreen.removePreference(magiskCategory);
}
}
}
@Override
public void onResume() {
super.onResume();
prefs.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
prefs.unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
Logger.dev("Settings: Prefs change " + key);
boolean enabled;
switch (key) {
case "dark_theme":
enabled = prefs.getBoolean("dark_theme", false);
if (magiskManager.isDarkTheme != enabled) {
magiskManager.isDarkTheme = enabled;
magiskManager.reloadMainActivity.trigger();
getActivity().recreate();
}
break;
case "disable":
enabled = prefs.getBoolean("disable", false);
if (enabled) {
Utils.createFile(MagiskManager.MAGISK_DISABLE_FILE);
} else {
Utils.removeItem(MagiskManager.MAGISK_DISABLE_FILE);
}
Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show();
break;
case "magiskhide":
enabled = prefs.getBoolean("magiskhide", false);
if (enabled) {
if (!magiskManager.isSuClient) {
new AlertDialogBuilder(getActivity())
.setTitle(R.string.no_magisksu_title)
.setMessage(R.string.no_magisksu_msg)
.setPositiveButton(R.string.understand, (dialog, which) -> new MagiskHide().enable())
.setCancelable(false)
.show();
} else {
new MagiskHide().enable();
}
} else {
new MagiskHide().disable();
}
break;
case "hosts":
enabled = prefs.getBoolean("hosts", false);
if (enabled) {
Shell.su_async(null,
"cp -af /system/etc/hosts /magisk/.core/hosts",
"mount -o bind /magisk/.core/hosts /system/etc/hosts");
} else {
Shell.su_async(null,
"umount -l /system/etc/hosts",
"rm -f /magisk/.core/hosts");
}
break;
case "su_access":
magiskManager.suAccessState = Utils.getPrefsInt(prefs, "su_access", 3);
magiskManager.suDB.setSettings(SuDatabaseHelper.ROOT_ACCESS, magiskManager.suAccessState);
break;
case "multiuser_mode":
magiskManager.multiuserMode = Utils.getPrefsInt(prefs, "multiuser_mode", 0);
magiskManager.suDB.setSettings(SuDatabaseHelper.MULTIUSER_MODE, magiskManager.multiuserMode);
break;
case "mnt_ns":
magiskManager.suNamespaceMode = Utils.getPrefsInt(prefs, "mnt_ns", 1);
magiskManager.suDB.setSettings(SuDatabaseHelper.MNT_NS, magiskManager.suNamespaceMode);
break;
case "su_request_timeout":
magiskManager.suRequestTimeout = Utils.getPrefsInt(prefs, "su_request_timeout", 10);
break;
case "su_auto_response":
magiskManager.suResponseType = Utils.getPrefsInt(prefs, "su_auto_response", 0);
break;
case "su_notification":
magiskManager.suNotificationType = Utils.getPrefsInt(prefs, "su_notification", 1);
break;
case "developer_logging":
MagiskManager.devLogging = prefs.getBoolean("developer_logging", false);
break;
case "shell_logging":
MagiskManager.shellLogging = prefs.getBoolean("shell_logging", false);
break;
}
setSummary();
}
private void setSummary() {
suAccess.setSummary(getResources()
.getStringArray(R.array.su_access)[magiskManager.suAccessState]);
autoRes.setSummary(getResources()
.getStringArray(R.array.auto_response)[magiskManager.suResponseType]);
suNotification.setSummary(getResources()
.getStringArray(R.array.su_notification)[magiskManager.suNotificationType]);
requestTimeout.setSummary(
getString(R.string.request_timeout_summary, prefs.getString("su_request_timeout", "10")));
multiuserMode.setSummary(getResources()
.getStringArray(R.array.multiuser_summary)[magiskManager.multiuserMode]);
namespaceMode.setSummary(getResources()
.getStringArray(R.array.namespace_summary)[magiskManager.suNamespaceMode]);
}
}
}

View File

@@ -1,58 +0,0 @@
package com.topjohnwu.magisk;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import com.topjohnwu.magisk.asyncs.GetBootBlocks;
import com.topjohnwu.magisk.asyncs.LoadApps;
import com.topjohnwu.magisk.asyncs.LoadModules;
import com.topjohnwu.magisk.asyncs.LoadRepos;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.services.UpdateCheckService;
import com.topjohnwu.magisk.utils.Utils;
public class SplashActivity extends Activity{
private static final int UPDATE_SERVICE_ID = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Init the info and configs and root shell
getApplicationContext().init();
// Now fire all async tasks
new GetBootBlocks(this).exec();
new LoadModules(this).setCallBack(() -> new LoadRepos(this).exec()).exec();
new LoadApps(this).exec();
if (Utils.checkNetworkStatus(this)) {
// Initialize the update check service, notify every 8 hours
if (!TextUtils.equals("install", getIntent().getStringExtra(MagiskManager.INTENT_SECTION))) {
ComponentName service = new ComponentName(this, UpdateCheckService.class);
JobInfo jobInfo = new JobInfo.Builder(UPDATE_SERVICE_ID, service)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.setPeriodic(8 * 60 * 60 * 1000)
.build();
JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
scheduler.schedule(jobInfo);
}
}
Intent intent = new Intent(this, MainActivity.class);
String section = getIntent().getStringExtra(MagiskManager.INTENT_SECTION);
if (section != null) {
intent.putExtra(MagiskManager.INTENT_SECTION, section);
}
startActivity(intent);
finish();
}
}

View File

@@ -1,125 +0,0 @@
package com.topjohnwu.magisk.adapters;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.ProcessRepoZip;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.components.MarkDownWindow;
import com.topjohnwu.magisk.module.Repo;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import com.topjohnwu.magisk.utils.Utils;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder> {
private List<Repo> mUpdateRepos, mInstalledRepos, mOthersRepos;
private Context mContext;
public ReposAdapter(List<Repo> update, List<Repo> installed, List<Repo> others) {
mUpdateRepos = update;
mInstalledRepos = installed;
mOthersRepos = others;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mContext = parent.getContext();
View v = LayoutInflater.from(mContext).inflate(R.layout.list_item_repo, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Repo repo = getItem(position);
holder.title.setText(repo.getName());
holder.versionName.setText(repo.getVersion());
String author = repo.getAuthor();
holder.author.setText(TextUtils.isEmpty(author) ? null : mContext.getString(R.string.author, author));
holder.description.setText(repo.getDescription());
holder.infoLayout.setOnClickListener(v -> new MarkDownWindow(null, repo.getDetailUrl(), mContext));
holder.downloadImage.setOnClickListener(v -> {
String filename = repo.getName() + "-" + repo.getVersion() + ".zip";
new AlertDialogBuilder(mContext)
.setTitle(mContext.getString(R.string.repo_install_title, repo.getName()))
.setMessage(mContext.getString(R.string.repo_install_msg, filename))
.setCancelable(true)
.setPositiveButton(R.string.install, (d, i) -> Utils.dlAndReceive(
mContext,
new DownloadReceiver() {
@Override
public void onDownloadDone(Uri uri) {
Activity activity = (Activity) mContext;
new ProcessRepoZip(activity, uri, true).exec();
}
},
repo.getZipUrl(),
Utils.getLegalFilename(filename)))
.setNeutralButton(R.string.download, (d, i) -> Utils.dlAndReceive(
mContext,
new DownloadReceiver() {
@Override
public void onDownloadDone(Uri uri) {
Activity activity = (Activity) mContext;
new ProcessRepoZip(activity, uri, false).exec();
}
},
repo.getZipUrl(),
Utils.getLegalFilename(filename)))
.setNegativeButton(R.string.no_thanks, null)
.show();
});
}
@Override
public int getItemCount() {
return mUpdateRepos.size() + mInstalledRepos.size() + mOthersRepos.size();
}
private Repo getItem(int position) {
if (position >= mUpdateRepos.size()) {
position -= mUpdateRepos.size();
if (position >= mInstalledRepos.size()) {
position -= mInstalledRepos.size();
return mOthersRepos.get(position);
} else {
return mInstalledRepos.get(position);
}
} else {
return mUpdateRepos.get(position);
}
}
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.title) TextView title;
@BindView(R.id.version_name) TextView versionName;
@BindView(R.id.description) TextView description;
@BindView(R.id.author) TextView author;
@BindView(R.id.info_layout) LinearLayout infoLayout;
@BindView(R.id.download) ImageView downloadImage;
ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}

View File

@@ -1,178 +0,0 @@
package com.topjohnwu.magisk.adapters;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.Arrays;
import java.util.Comparator;
public class SimpleSectionedRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int SECTION_TYPE = 0;
private boolean mValid = true;
private int mSectionResourceId;
private int mTextResourceId;
private RecyclerView.Adapter mBaseAdapter;
private SparseArray<Section> mSections = new SparseArray<Section>();
public SimpleSectionedRecyclerViewAdapter(int sectionResourceId, int textResourceId,
RecyclerView.Adapter baseAdapter) {
mSectionResourceId = sectionResourceId;
mTextResourceId = textResourceId;
mBaseAdapter = baseAdapter;
mBaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
mValid = mBaseAdapter.getItemCount()>0;
notifyDataSetChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
mValid = mBaseAdapter.getItemCount()>0;
notifyItemRangeChanged(positionStart, itemCount);
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
mValid = mBaseAdapter.getItemCount()>0;
notifyItemRangeInserted(positionStart, itemCount);
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
mValid = mBaseAdapter.getItemCount()>0;
notifyItemRangeRemoved(positionStart, itemCount);
}
});
}
public static class SectionViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public SectionViewHolder(View view, int mTextResourceid) {
super(view);
title = (TextView) view.findViewById(mTextResourceid);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int typeView) {
if (typeView == SECTION_TYPE) {
View view = LayoutInflater.from(parent.getContext()).inflate(mSectionResourceId, parent, false);
return new SectionViewHolder(view,mTextResourceId);
}else{
return mBaseAdapter.onCreateViewHolder(parent, typeView -1);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder sectionViewHolder, int position) {
if (isSectionHeaderPosition(position)) {
((SectionViewHolder)sectionViewHolder).title.setText(mSections.get(position).title);
}else{
mBaseAdapter.onBindViewHolder(sectionViewHolder,sectionedPositionToPosition(position));
}
}
@Override
public int getItemViewType(int position) {
return isSectionHeaderPosition(position)
? SECTION_TYPE
: mBaseAdapter.getItemViewType(sectionedPositionToPosition(position)) +1 ;
}
public static class Section {
int firstPosition;
int sectionedPosition;
CharSequence title;
public Section(int firstPosition, CharSequence title) {
this.firstPosition = firstPosition;
this.title = title;
}
public CharSequence getTitle() {
return title;
}
}
public void setSections(Section[] sections) {
mSections.clear();
Arrays.sort(sections, new Comparator<Section>() {
@Override
public int compare(Section o, Section o1) {
return (o.firstPosition == o1.firstPosition)
? 0
: ((o.firstPosition < o1.firstPosition) ? -1 : 1);
}
});
int offset = 0; // offset positions for the headers we're adding
for (Section section : sections) {
section.sectionedPosition = section.firstPosition + offset;
mSections.append(section.sectionedPosition, section);
++offset;
}
notifyDataSetChanged();
}
public int positionToSectionedPosition(int position) {
int offset = 0;
for (int i = 0; i < mSections.size(); i++) {
if (mSections.valueAt(i).firstPosition > position) {
break;
}
++offset;
}
return position + offset;
}
public int sectionedPositionToPosition(int sectionedPosition) {
if (isSectionHeaderPosition(sectionedPosition)) {
return RecyclerView.NO_POSITION;
}
int offset = 0;
for (int i = 0; i < mSections.size(); i++) {
if (mSections.valueAt(i).sectionedPosition > sectionedPosition) {
break;
}
--offset;
}
return sectionedPosition + offset;
}
public boolean isSectionHeaderPosition(int position) {
return mSections.get(position) != null;
}
@Override
public long getItemId(int position) {
return isSectionHeaderPosition(position)
? Integer.MAX_VALUE - mSections.indexOfKey(position)
: mBaseAdapter.getItemId(sectionedPositionToPosition(position));
}
@Override
public int getItemCount() {
return (mValid ? mBaseAdapter.getItemCount() + mSections.size() : 0);
}
}

View File

@@ -1,197 +0,0 @@
package com.topjohnwu.magisk.adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter;
import com.thoughtbot.expandablerecyclerview.models.ExpandableGroup;
import com.thoughtbot.expandablerecyclerview.viewholders.ChildViewHolder;
import com.thoughtbot.expandablerecyclerview.viewholders.GroupViewHolder;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.ExpandableViewHolder;
import com.topjohnwu.magisk.superuser.SuLogEntry;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import butterknife.BindView;
import butterknife.ButterKnife;
public class SuLogAdapter {
private ExpandableAdapter adapter;
private Set<SuLogEntry> expandList = new HashSet<>();
public SuLogAdapter(List<SuLogEntry> list) {
// Separate the logs with date
Map<String, List<SuLogEntry>> logEntryMap = new LinkedHashMap<>();
List<SuLogEntry> group;
for (SuLogEntry log : list) {
String date = log.getDateString();
group = logEntryMap.get(date);
if (group == null) {
group = new ArrayList<>();
logEntryMap.put(date, group);
}
group.add(log);
}
// Then format them into expandable groups
List<LogGroup> logEntryGroups = new ArrayList<>();
for (Map.Entry<String, List<SuLogEntry>> entry : logEntryMap.entrySet()) {
logEntryGroups.add(new LogGroup(entry.getKey(), entry.getValue()));
}
adapter = new ExpandableAdapter(logEntryGroups);
}
public RecyclerView.Adapter getAdapter() {
return adapter;
}
private class ExpandableAdapter
extends ExpandableRecyclerViewAdapter<LogGroupViewHolder, LogViewHolder> {
ExpandableAdapter(List<? extends ExpandableGroup> groups) {
super(groups);
expandableList.expandedGroupIndexes[0] = true;
}
@Override
public LogGroupViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_sulog_group, parent, false);
return new LogGroupViewHolder(v);
}
@Override
public LogViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_sulog, parent, false);
return new LogViewHolder(v);
}
@Override
public void onBindChildViewHolder(LogViewHolder holder, int flatPosition, ExpandableGroup group, int childIndex) {
Context context = holder.itemView.getContext();
SuLogEntry logEntry = (SuLogEntry) group.getItems().get(childIndex);
holder.setExpanded(expandList.contains(logEntry));
holder.itemView.setOnClickListener(view -> {
if (holder.getExpanded()) {
holder.collapse();
expandList.remove(logEntry);
} else {
holder.expand();
expandList.add(logEntry);
}
});
holder.appName.setText(logEntry.appName);
holder.action.setText(context.getString(logEntry.action ? R.string.grant : R.string.deny));
holder.command.setText(logEntry.command);
holder.fromPid.setText(String.valueOf(logEntry.fromPid));
holder.toUid.setText(String.valueOf(logEntry.toUid));
holder.time.setText(logEntry.getTimeString());
}
@Override
public void onBindGroupViewHolder(LogGroupViewHolder holder, int flatPosition, ExpandableGroup group) {
holder.date.setText(group.getTitle());
if (isGroupExpanded(flatPosition)) {
holder.expand();
}
}
}
private class LogGroup extends ExpandableGroup<SuLogEntry> {
LogGroup(String title, List<SuLogEntry> items) {
super(title, items);
}
}
static class LogGroupViewHolder extends GroupViewHolder {
@BindView(R.id.date) TextView date;
@BindView(R.id.arrow) ImageView arrow;
public LogGroupViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
@Override
public void expand() {
RotateAnimation rotate =
new RotateAnimation(360, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(300);
rotate.setFillAfter(true);
arrow.setAnimation(rotate);
}
@Override
public void collapse() {
RotateAnimation rotate =
new RotateAnimation(180, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(300);
rotate.setFillAfter(true);
arrow.setAnimation(rotate);
}
}
// Wrapper class
static class LogViewHolder extends ChildViewHolder {
private InternalViewHolder expandableViewHolder;
@BindView(R.id.app_name) TextView appName;
@BindView(R.id.action) TextView action;
@BindView(R.id.time) TextView time;
@BindView(R.id.fromPid) TextView fromPid;
@BindView(R.id.toUid) TextView toUid;
@BindView(R.id.command) TextView command;
LogViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
expandableViewHolder = new InternalViewHolder(itemView);
}
private class InternalViewHolder extends ExpandableViewHolder {
InternalViewHolder(View itemView) {
super(itemView);
}
@Override
public void setExpandLayout(View itemView) {
expandLayout = itemView.findViewById(R.id.expand_layout);
}
}
private boolean getExpanded() {
return expandableViewHolder.mExpanded;
}
private void setExpanded(boolean expanded) {
expandableViewHolder.setExpanded(expanded);
}
private void expand() {
expandableViewHolder.expand();
}
private void collapse() {
expandableViewHolder.collapse();
}
}
}

View File

@@ -1,59 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.content.Context;
import com.topjohnwu.magisk.BuildConfig;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebService;
import org.json.JSONException;
import org.json.JSONObject;
public class CheckUpdates extends ParallelTask<Void, Void, Void> {
private static final String UPDATE_JSON = "https://raw.githubusercontent.com/topjohnwu/MagiskManager/update/magisk_update.json";
private boolean showNotification = false;
public CheckUpdates(Context context, boolean b) {
this(context);
showNotification = b;
}
public CheckUpdates(Context context) {
magiskManager = Utils.getMagiskManager(context);
}
@Override
protected Void doInBackground(Void... voids) {
String jsonStr = WebService.request(UPDATE_JSON, WebService.GET);
try {
JSONObject json = new JSONObject(jsonStr);
JSONObject magisk = json.getJSONObject("magisk");
magiskManager.remoteMagiskVersionString = magisk.getString("version");
magiskManager.remoteMagiskVersionCode = magisk.getInt("versionCode");
magiskManager.magiskLink = magisk.getString("link");
magiskManager.releaseNoteLink = magisk.getString("note");
JSONObject manager = json.getJSONObject("app");
magiskManager.remoteManagerVersionString = manager.getString("version");
magiskManager.remoteManagerVersionCode = manager.getInt("versionCode");
magiskManager.managerLink = manager.getString("link");
} catch (JSONException ignored) {}
return null;
}
@Override
protected void onPostExecute(Void v) {
if (showNotification && magiskManager.updateNotification) {
if (magiskManager.magiskVersionCode < magiskManager.remoteMagiskVersionCode) {
Utils.showMagiskUpdate(magiskManager);
}
if (BuildConfig.VERSION_CODE < magiskManager.remoteManagerVersionCode) {
Utils.showManagerUpdate(magiskManager);
}
}
magiskManager.updateCheckDone.trigger();
super.onPostExecute(v);
}
}

View File

@@ -1,154 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.app.ProgressDialog;
import android.net.Uri;
import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ZipUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
public class FlashZip extends RootTask<Void, String, Integer> {
private Uri mUri;
private File mCachedFile, mScriptFile, mCheckFile;
private String mFilename;
private ProgressDialog progress;
public FlashZip(Activity context, Uri uri) {
super(context);
mUri = uri;
mCachedFile = new File(magiskManager.getCacheDir(), "install.zip");
mScriptFile = new File(magiskManager.getCacheDir(), "/META-INF/com/google/android/update-binary");
mCheckFile = new File(mScriptFile.getParent(), "updater-script");
// Try to get the filename ourselves
mFilename = Utils.getNameFromUri(magiskManager, mUri);
}
private void copyToCache() throws Throwable {
publishProgress(magiskManager.getString(R.string.copying_msg));
if (mCachedFile.exists() && !mCachedFile.delete()) {
Logger.error("FlashZip: Error while deleting already existing file");
throw new IOException();
}
try (
InputStream in = magiskManager.getContentResolver().openInputStream(mUri);
OutputStream outputStream = new FileOutputStream(mCachedFile)
) {
byte buffer[] = new byte[1024];
int length;
if (in == null) throw new FileNotFoundException();
while ((length = in.read(buffer)) > 0)
outputStream.write(buffer, 0, length);
Logger.dev("FlashZip: File created successfully - " + mCachedFile.getPath());
} catch (FileNotFoundException e) {
Logger.error("FlashZip: Invalid Uri");
throw e;
} catch (IOException e) {
Logger.error("FlashZip: Error in creating file");
throw e;
}
}
private boolean unzipAndCheck() throws Exception {
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android");
List<String> ret;
ret = Utils.readFile(mCheckFile.getPath());
return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK");
}
private int cleanup(int ret) {
Shell.su(
"rm -rf " + mCachedFile.getParent() + "/*",
"rm -rf " + MagiskManager.TMP_FOLDER_PATH
);
return ret;
}
@Override
protected void onPreExecute() {
progress = new ProgressDialog(activity);
progress.setTitle(R.string.zip_install_progress_title);
progress.show();
}
@Override
protected void onProgressUpdate(String... values) {
progress.setMessage(values[0]);
}
@Override
protected Integer doInRoot(Void... voids) {
Logger.dev("FlashZip Running... " + mFilename);
List<String> ret;
try {
copyToCache();
if (!unzipAndCheck()) return cleanup(0);
publishProgress(magiskManager.getString(R.string.zip_install_progress_msg, mFilename));
ret = Shell.su(
"BOOTMODE=true sh " + mScriptFile + " dummy 1 " + mCachedFile,
"if [ $? -eq 0 ]; then echo true; else echo false; fi"
);
if (!Utils.isValidShellResponse(ret)) return -1;
Logger.dev("FlashZip: Console log:");
for (String line : ret) {
Logger.dev(line);
}
if (Boolean.parseBoolean(ret.get(ret.size() - 1)))
return cleanup(1);
} catch (Throwable e) {
e.printStackTrace();
}
return cleanup(-1);
}
// -1 = error, manual install; 0 = invalid zip; 1 = success
@Override
protected void onPostExecute(Integer result) {
progress.dismiss();
switch (result) {
case -1:
Toast.makeText(magiskManager, magiskManager.getString(R.string.install_error), Toast.LENGTH_LONG).show();
Utils.showUriSnack(activity, mUri);
break;
case 0:
Toast.makeText(magiskManager, magiskManager.getString(R.string.invalid_zip), Toast.LENGTH_LONG).show();
break;
case 1:
onSuccess();
break;
}
super.onPostExecute(result);
}
protected void onSuccess() {
magiskManager.updateCheckDone.trigger();
new LoadModules(activity).exec();
new AlertDialogBuilder(activity)
.setTitle(R.string.reboot_title)
.setMessage(R.string.reboot_msg)
.setPositiveButton(R.string.reboot, (dialogInterface, i) -> Shell.su(true, "reboot"))
.setNegativeButton(R.string.no_thanks, null)
.show();
}
}

View File

@@ -1,30 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
public class GetBootBlocks extends RootTask<Void, Void, Void> {
public GetBootBlocks(Activity context) {
super(context);
}
@Override
protected Void doInRoot(Void... params) {
magiskManager.blockList = Shell.su(
"find /dev/block -type b -maxdepth 1 | grep -v -E \"loop|ram|dm-0\""
);
if (magiskManager.bootBlock == null) {
magiskManager.bootBlock = Utils.detectBootImage();
}
return null;
}
@Override
protected void onPostExecute(Void v) {
magiskManager.blockDetectionDone.trigger();
super.onPostExecute(v);
}
}

View File

@@ -1,39 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import com.topjohnwu.magisk.adapters.ApplicationAdapter;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class LoadApps extends ParallelTask<Void, Void, Void> {
public LoadApps(Activity context) {
super(context);
}
@Override
protected Void doInBackground(Void... voids) {
PackageManager pm = magiskManager.getPackageManager();
List<ApplicationInfo> list = pm.getInstalledApplications(0);
for (Iterator<ApplicationInfo> i = list.iterator(); i.hasNext(); ) {
ApplicationInfo info = i.next();
if (ApplicationAdapter.BLACKLIST.contains(info.packageName) || !info.enabled) {
i.remove();
}
}
Collections.sort(list, (a, b) -> a.loadLabel(pm).toString().toLowerCase()
.compareTo(b.loadLabel(pm).toString().toLowerCase()));
magiskManager.appList = Collections.unmodifiableList(list);
return null;
}
@Override
protected void onPostExecute(Void v) {
new MagiskHide(activity).list();
}
}

View File

@@ -1,42 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.module.BaseModule;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ValueSortedMap;
public class LoadModules extends RootTask<Void, Void, Void> {
public LoadModules(Activity context) {
super(context);
}
@Override
protected Void doInRoot(Void... voids) {
Logger.dev("LoadModules: Loading modules");
magiskManager.moduleMap = new ValueSortedMap<>();
for (String path : Utils.getModList(MagiskManager.MAGISK_PATH)) {
Logger.dev("LoadModules: Adding modules from " + path);
Module module;
try {
module = new Module(path);
magiskManager.moduleMap.put(module.getId(), module);
} catch (BaseModule.CacheModException ignored) {}
}
Logger.dev("LoadModules: Data load done");
return null;
}
@Override
protected void onPostExecute(Void v) {
magiskManager.moduleLoadDone.trigger();
super.onPostExecute(v);
}
}

View File

@@ -1,189 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.content.SharedPreferences;
import android.text.TextUtils;
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
import com.topjohnwu.magisk.module.BaseModule;
import com.topjohnwu.magisk.module.Repo;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.ValueSortedMap;
import com.topjohnwu.magisk.utils.WebService;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class LoadRepos extends ParallelTask<Void, Void, Void> {
public static final String ETAG_KEY = "ETag";
private static final String REPO_URL = "https://api.github.com/users/Magisk-Modules-Repo/repos?per_page=100&page=%d";
private static final String IF_NONE_MATCH = "If-None-Match";
private static final String LINK_KEY = "Link";
private static final int CHECK_ETAG = 0;
private static final int LOAD_NEXT = 1;
private static final int LOAD_PREV = 2;
private List<String> etags;
private ValueSortedMap<String, Repo> cached, fetched;
private RepoDatabaseHelper repoDB;
private SharedPreferences prefs;
public LoadRepos(Activity context) {
super(context);
prefs = magiskManager.prefs;
String prefsPath = context.getApplicationInfo().dataDir + "/shared_prefs";
repoDB = new RepoDatabaseHelper(magiskManager);
// Legacy data cleanup
File old = new File(prefsPath, "RepoMap.xml");
if (old.exists() || !prefs.getString("repomap", "empty").equals("empty")) {
old.delete();
prefs.edit().remove("version").remove("repomap").remove(ETAG_KEY).apply();
repoDB.clearRepo();
}
etags = new ArrayList<>(
Arrays.asList(magiskManager.prefs.getString(ETAG_KEY, "").split(",")));
}
private void loadJSON(String jsonString) throws Exception {
JSONArray jsonArray = new JSONArray(jsonString);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonobject = jsonArray.getJSONObject(i);
String id = jsonobject.getString("description");
String name = jsonobject.getString("name");
String lastUpdate = jsonobject.getString("pushed_at");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
Date updatedDate = format.parse(lastUpdate);
Repo repo = cached.get(id);
try {
if (repo == null) {
Logger.dev("LoadRepos: Create new repo " + id);
repo = new Repo(name, updatedDate);
} else {
// Popout from cached
cached.remove(id);
repo.update(updatedDate);
}
if (repo.getId() != null) {
fetched.put(id, repo);
}
} catch (BaseModule.CacheModException ignored) {}
}
}
private boolean loadPage(int page, String url, int mode) {
Logger.dev("LoadRepos: Loading page: " + (page + 1));
Map<String, String> header = new HashMap<>();
if (mode == CHECK_ETAG && page < etags.size() && !TextUtils.isEmpty(etags.get(page))) {
Logger.dev("ETAG: " + etags.get(page));
header.put(IF_NONE_MATCH, etags.get(page));
}
if (url == null) {
url = String.format(Locale.US, REPO_URL, page + 1);
}
String jsonString = WebService.request(url, WebService.GET, header, true);
if (TextUtils.isEmpty(jsonString)) {
// At least check the pages we know
return page + 1 < etags.size() && loadPage(page + 1, null, CHECK_ETAG);
}
// The request succeed, parse the new stuffs
try {
loadJSON(jsonString);
} catch (Exception e) {
e.printStackTrace();
return false;
}
// Update the ETAG
String newEtag = header.get(ETAG_KEY);
newEtag = newEtag.substring(newEtag.indexOf('\"'), newEtag.lastIndexOf('\"') + 1);
Logger.dev("New ETAG: " + newEtag);
if (page < etags.size()) {
etags.set(page, newEtag);
} else {
etags.add(newEtag);
}
String links = header.get(LINK_KEY);
if (links != null) {
if (mode == CHECK_ETAG || mode == LOAD_NEXT) {
// Try to check next page URL
url = null;
for (String s : links.split(", ")) {
if (s.contains("next")) {
url = s.substring(s.indexOf("<") + 1, s.indexOf(">; "));
break;
}
}
if (url != null) {
loadPage(page + 1, url, LOAD_NEXT);
}
}
if (mode == CHECK_ETAG || mode == LOAD_PREV) {
// Try to check prev page URL
url = null;
for (String s : links.split(", ")) {
if (s.contains("prev")) {
url = s.substring(s.indexOf("<") + 1, s.indexOf(">; "));
break;
}
}
if (url != null) {
loadPage(page - 1, url, LOAD_PREV);
}
}
}
return true;
}
@Override
protected Void doInBackground(Void... voids) {
Logger.dev("LoadRepos: Loading repos");
cached = repoDB.getRepoMap(false);
fetched = new ValueSortedMap<>();
if (!loadPage(0, null, CHECK_ETAG)) {
magiskManager.repoMap = repoDB.getRepoMap();
Logger.dev("LoadRepos: No updates, use DB");
return null;
}
repoDB.addRepoMap(fetched);
repoDB.removeRepo(cached);
// Update ETag
StringBuilder etagBuilder = new StringBuilder();
for (int i = 0; i < etags.size(); ++i) {
if (i != 0) etagBuilder.append(",");
etagBuilder.append(etags.get(i));
}
prefs.edit().putString(ETAG_KEY, etagBuilder.toString()).apply();
magiskManager.repoMap = repoDB.getRepoMap();
Logger.dev("LoadRepos: Done");
return null;
}
@Override
protected void onPostExecute(Void v) {
magiskManager.repoLoadDone.trigger();
super.onPostExecute(v);
}
}

View File

@@ -1,59 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import com.topjohnwu.magisk.utils.Shell;
import java.util.List;
public class MagiskHide extends RootTask<Object, Void, Void> {
private boolean isList = false;
public MagiskHide() {}
public MagiskHide(Activity context) {
super(context);
}
@Override
protected Void doInRoot(Object... params) {
String command = (String) params[0];
List<String> ret = Shell.su("magiskhide --" + command);
if (isList) {
magiskManager.magiskHideList = ret;
}
return null;
}
@Override
protected void onPostExecute(Void v) {
if (isList) {
magiskManager.magiskHideDone.trigger();
}
super.onPostExecute(v);
}
public void add(CharSequence packageName) {
exec("add " + packageName);
}
public void rm(CharSequence packageName) {
exec("rm " + packageName);
}
public void enable() {
exec("enable");
}
public void disable() {
exec("disable");
}
public void list() {
isList = true;
if (magiskManager == null) return;
exec("ls");
}
}

View File

@@ -1,58 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.app.ProgressDialog;
import android.net.Uri;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
public class ProcessMagiskZip extends ParallelTask<Void, Void, Boolean> {
private Uri mUri;
private ProgressDialog progressDialog;
private String mBoot;
private boolean mEnc, mVerity;
public ProcessMagiskZip(Activity context, Uri uri, String boot, boolean enc, boolean verity) {
super(context);
mUri = uri;
mBoot = boot;
mEnc = enc;
mVerity = verity;
}
@Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(activity,
activity.getString(R.string.zip_process_title),
activity.getString(R.string.zip_unzip_msg));
}
@Override
protected Boolean doInBackground(Void... params) {
if (Shell.rootAccess()) {
synchronized (Shell.lock) {
Shell.su("rm -f /dev/.magisk",
(mBoot != null) ? "echo \"BOOTIMAGE=" + mBoot + "\" >> /dev/.magisk" : "",
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(mEnc) + "\" >> /dev/.magisk",
"echo \"KEEPVERITY=" + String.valueOf(mVerity) + "\" >> /dev/.magisk"
);
}
return true;
}
return false;
}
@Override
protected void onPostExecute(Boolean result) {
progressDialog.dismiss();
if (result) {
new FlashZip(activity, mUri).exec();
} else {
Utils.showUriSnack(activity, mUri);
}
super.onPostExecute(result);
}
}

View File

@@ -1,97 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.app.ProgressDialog;
import android.net.Uri;
import android.widget.Toast;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ZipUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.OutputStream;
public class ProcessRepoZip extends ParallelTask<Void, Void, Boolean> {
private Uri mUri;
private ProgressDialog progressDialog;
private boolean mInstall;
public ProcessRepoZip(Activity context, Uri uri, boolean install) {
super(context);
mUri = uri;
mInstall = install;
}
@Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(activity,
activity.getString(R.string.zip_process_title),
activity.getString(R.string.zip_process_msg));
}
@Override
protected Boolean doInBackground(Void... params) {
try {
// Create temp file
File temp1 = new File(magiskManager.getCacheDir(), "1.zip");
File temp2 = new File(magiskManager.getCacheDir(), "2.zip");
magiskManager.getCacheDir().mkdirs();
temp1.createNewFile();
temp2.createNewFile();
// First remove top folder in Github source zip, Uri -> temp1
ZipUtils.removeTopFolder(activity.getContentResolver().openInputStream(mUri), temp1);
// Then sign the zip for the first time, temp1 -> temp2
ZipUtils.signZip(activity, temp1, temp2, false);
// Adjust the zip to prevent unzip issues, temp2 -> temp1
ZipUtils.zipAdjust(temp2.getPath(), temp1.getPath());
// Finally, sign the whole zip file again, temp1 -> temp2
ZipUtils.signZip(activity, temp1, temp2, true);
// Write it back to the downloaded zip, temp2 -> Uri
FileInputStream in = new FileInputStream(temp2);
try (OutputStream target = activity.getContentResolver().openOutputStream(mUri)) {
byte[] buffer = new byte[4096];
int length;
if (target == null) throw new FileNotFoundException();
while ((length = in.read(buffer)) > 0)
target.write(buffer, 0, length);
}
// Delete the temp file
temp1.delete();
temp2.delete();
return true;
} catch (Exception e) {
Logger.error("ProcessRepoZip: Error!");
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
progressDialog.dismiss();
if (result) {
if (Shell.rootAccess() && mInstall) {
new FlashZip(activity, mUri).exec();
} else {
Utils.showUriSnack(activity, mUri);
}
} else {
Toast.makeText(activity, R.string.process_error, Toast.LENGTH_LONG).show();
}
}
}

View File

@@ -1,33 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import com.topjohnwu.magisk.utils.Shell;
public abstract class RootTask <Params, Progress, Result> extends ParallelTask<Params, Progress, Result> {
public RootTask() {}
public RootTask(Activity context) {
super(context);
}
@SafeVarargs
@Override
final protected Result doInBackground(Params... params) {
synchronized (Shell.lock) {
return doInRoot(params);
}
}
@SuppressWarnings("unchecked")
abstract protected Result doInRoot(Params... params);
@SuppressWarnings("unchecked")
@Override
public void exec(Params... params) {
if (Shell.rootAccess()) {
super.exec(params);
}
}
}

View File

@@ -1,30 +0,0 @@
package com.topjohnwu.magisk.components;
import android.support.v7.app.AppCompatActivity;
import android.view.WindowManager;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
public class Activity extends AppCompatActivity {
@Override
public MagiskManager getApplicationContext() {
return (MagiskManager) super.getApplicationContext();
}
protected void setFloating() {
boolean isTablet = getResources().getBoolean(R.bool.isTablet);
if (isTablet) {
WindowManager.LayoutParams params = getWindow().getAttributes();
params.height = getResources().getDimensionPixelSize(R.dimen.floating_height);
params.width = getResources().getDimensionPixelSize(R.dimen.floating_width);
params.alpha = 1.0f;
params.dimAmount = 0.6f;
params.flags |= 2;
getWindow().setAttributes(params);
setFinishOnTouchOutside(true);
}
}
}

View File

@@ -1,77 +0,0 @@
package com.topjohnwu.magisk.components;
import android.animation.ValueAnimator;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
public abstract class ExpandableViewHolder extends RecyclerView.ViewHolder {
protected ViewGroup expandLayout;
private ValueAnimator expandAnimator, collapseAnimator;
private static int expandHeight = 0;
public boolean mExpanded = false;
public ExpandableViewHolder(View itemView) {
super(itemView);
setExpandLayout(itemView);
expandLayout.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (expandHeight == 0) {
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
expandLayout.measure(widthSpec, heightSpec);
expandHeight = expandLayout.getMeasuredHeight();
}
expandLayout.getViewTreeObserver().removeOnPreDrawListener(this);
expandLayout.setVisibility(View.GONE);
expandAnimator = slideAnimator(0, expandHeight);
collapseAnimator = slideAnimator(expandHeight, 0);
return true;
}
});
}
public void setExpanded(boolean expanded) {
mExpanded = expanded;
ViewGroup.LayoutParams layoutParams = expandLayout.getLayoutParams();
layoutParams.height = expanded ? expandHeight : 0;
expandLayout.setLayoutParams(layoutParams);
expandLayout.setVisibility(expanded ? View.VISIBLE : View.GONE);
}
public void expand() {
if (mExpanded) return;
expandLayout.setVisibility(View.VISIBLE);
expandAnimator.start();
mExpanded = true;
}
public void collapse() {
if (!mExpanded) return;
collapseAnimator.start();
mExpanded = false;
}
public abstract void setExpandLayout(View itemView);
private ValueAnimator slideAnimator(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(valueAnimator -> {
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = expandLayout.getLayoutParams();
layoutParams.height = value;
expandLayout.setLayoutParams(layoutParams);
});
return animator;
}
}

View File

@@ -1,12 +0,0 @@
package com.topjohnwu.magisk.components;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Utils;
public class Fragment extends android.support.v4.app.Fragment {
public MagiskManager getApplication() {
return Utils.getMagiskManager(getActivity());
}
}

View File

@@ -1,31 +0,0 @@
package com.topjohnwu.magisk.components;
import android.content.Context;
import android.support.v7.app.AlertDialog;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils;
import us.feras.mdv.MarkdownView;
public class MarkDownWindow {
public MarkDownWindow(String title, String url, Context context) {
MagiskManager magiskManager = Utils.getMagiskManager(context);
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle(title);
Logger.dev("WebView: URL = " + url);
MarkdownView md = new MarkdownView(context);
md.loadMarkdownFile(url, "file:///android_asset/" +
(magiskManager.isDarkTheme ? "dark" : "light") + ".css");
alert.setView(md);
alert.setNegativeButton(R.string.close, (dialog, id) -> dialog.dismiss());
alert.show();
}
}

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