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

Compare commits

..

49 Commits
v17.2 ... v17.3

Author SHA1 Message Date
topjohnwu
018c0064cd Make sure boot_img is initialized correctly 2018-10-22 01:58:50 -04:00
topjohnwu
c2b016370b Make a copy of logcat and use that instead
When Magisk is magic mounting /system/bin, there is a chance that logcat would be temporarily unavailable. Leave a copy and use that for magisklogd
2018-10-20 21:46:12 -04:00
daveyannihilation
fc791b4371 Fix Dark theme to display cards as slightly lighter than background as per Material Design standards. Also redirect colors to app as opposed to calling on framework 2018-10-20 21:13:13 -04:00
topjohnwu
f76bb009f4 Update changelogs 2018-10-20 20:11:09 -04:00
topjohnwu
8a1292b295 Ask permissions to read internal storage 2018-10-20 19:42:46 -04:00
topjohnwu
d7d80d3fc1 Update encryption detection for determining default flags 2018-10-20 17:10:35 -04:00
topjohnwu
41b01003fd Always ACK before doing anything 2018-10-20 16:12:08 -04:00
topjohnwu
6557070ae1 Try to flush database before uninstalling 2018-10-20 15:31:41 -04:00
topjohnwu
e7e580e177 Remove support for Magisk lower than 1500 2018-10-20 15:04:15 -04:00
topjohnwu
dd9ddd2019 Remove unnecessary instruction from Defex hexpatch
Close #489
2018-10-20 00:28:09 -04:00
topjohnwu
74aae523ba Properly support boot image header v1
Close #695
2018-10-20 00:27:56 -04:00
topjohnwu
48c40f9516 Prevent Resources
Fix #619
2018-10-17 19:44:48 -04:00
topjohnwu
e0e7674715 Fix close button in FlashActivity 2018-10-17 15:36:09 -04:00
topjohnwu
e1a65276b9 Switch to general Samsung defex patch
Should be future proof unless code changes
2018-10-17 03:17:24 -04:00
muhammeteminturgut
469adc85ad Update Turkish translations 2018-10-16 21:11:43 -04:00
vvb2060
e1b181ca4e Hide system in MagiskHide list 2018-10-16 21:09:18 -04:00
topjohnwu
a4f0fbf8b7 Switch to butterknife
Finally support AndroidX and obfuscation
2018-10-16 21:00:01 -04:00
topjohnwu
190cdaddf8 Update README 2018-10-16 02:06:07 -04:00
topjohnwu
5c4ba13839 Add installation details 2018-10-16 01:55:28 -04:00
topjohnwu
e62630cf3e Add MagiskHide tutorials 2018-10-15 18:04:51 -04:00
topjohnwu
36fe7846c0 Update documentations
Still WIP
2018-10-15 04:33:42 -04:00
topjohnwu
8d150dd67a Update documentation
Still WIP
2018-10-15 00:46:37 -04:00
topjohnwu
506df00d81 Upgrade AGP 2018-10-12 21:51:58 -04:00
topjohnwu
a9121fa28f Reorganize libutils and cleanups 2018-10-12 21:46:09 -04:00
topjohnwu
d5a56d9e85 Fix bootloop for some devices with two /data
Close #654
2018-10-12 00:54:55 -04:00
topjohnwu
acf7c0c665 Minor reorganization of daemons 2018-10-12 00:50:47 -04:00
topjohnwu
619d48c97a Remove doc changelogs 2018-10-05 17:55:06 -04:00
topjohnwu
2cb198c38c Update README 2018-10-05 17:52:40 -04:00
topjohnwu
e8e39e0f3c Use poll instead of select
Close #637
2018-10-04 15:06:13 -04:00
topjohnwu
37860181d4 Finish su implementation 2018-10-04 14:41:48 -04:00
topjohnwu
d119dd9a0c Rewrite su daemon and client 2018-10-04 04:59:51 -04:00
topjohnwu
09ef19f7ec Code cleanups 2018-10-04 01:49:52 -04:00
topjohnwu
6a06c92fa6 Simplify su_info caches
No more lists. 99.999% it will only handle a single excessive requestor anyways.
2018-10-03 23:31:15 -04:00
topjohnwu
58ae596b0f Require fp auth when toggling su permission if required
Close #656
2018-09-29 02:21:14 -04:00
topjohnwu
f1ca21678d Set boolean when toggling 2018-09-29 02:02:41 -04:00
topjohnwu
d7eeef2c8a Separate fingerprint authentication dialog code 2018-09-29 01:57:51 -04:00
topjohnwu
4f626897f2 Cleanup 2018-09-29 00:28:12 -04:00
topjohnwu
b127e01845 Simplify debug flag propagation 2018-09-28 02:05:55 -04:00
topjohnwu
2118beeb23 Magisk-Modules-Repo now names repo with ID, simplify logic here 2018-09-28 01:58:28 -04:00
topjohnwu
5020cd1bbf Small cleanup 2018-09-28 01:25:43 -04:00
topjohnwu
cce636224c Reorganization 2018-09-27 18:26:41 -04:00
topjohnwu
60b3b8ddce Better incremental builds 2018-09-27 03:56:56 -04:00
topjohnwu
41446ec9ba Separate libutils and libsystemproperties 2018-09-27 03:30:16 -04:00
topjohnwu
df8b047bca Generalize logging interface 2018-09-27 03:11:10 -04:00
topjohnwu
12ced52012 Remove unused flag 2018-09-27 00:30:10 -04:00
topjohnwu
1d53335ae5 Dynamic load libselinux 2018-09-27 00:09:59 -04:00
topjohnwu
971a50d290 Update to Android Studio 3.2 2018-09-25 00:39:49 -04:00
topjohnwu
36dd9106a8 Stable AndroidX 2018-09-21 21:46:09 -04:00
John Wu
0a4ee3ffc7 Update README.MD 2018-09-21 12:01:59 -04:00
141 changed files with 2806 additions and 2702 deletions

View File

@@ -1,5 +1,13 @@
# Magisk
[XDA Announcement Thread](https://forum.xda-developers.com/apps/magisk/official-magisk-v7-universal-systemless-t3473445)
[Downloads](https://github.com/topjohnwu/Magisk/releases) | [Documentation](https://topjohnwu.github.io/Magisk/) | [XDA Thread](https://forum.xda-developers.com/apps/magisk/official-magisk-v7-universal-systemless-t3473445)
## Introduction
Magisk is a suite of open source tools for customizing Android, supporting devices higher than Android 5.0 (API 21). It covers the fundamental parts for Android customization: root, boot scripts, SELinux patches, AVB2.0 / dm-verity / forceencrypt removals etc.
Furthermore, Magisk provides a **Systemless Interface** to alter the system (or vendor) arbitrarily while the actual partitions stay completely intact. With its systemless nature along with several other hacks, Magisk can hide modifications from nearly any system integrity verifications used in banking apps, corporation monitoring apps, game cheat detections, and most importantly [Google's SafetyNet API](https://developer.android.com/training/safetynet/index.html).
## Bug Reports
**Make sure to install the latest [Canary Build](https://forum.xda-developers.com/apps/magisk/dev-magisk-canary-channel-bleeding-edge-t3839337) before reporting any bugs!** **DO NOT** report bugs that is already fixed upstream. Follow the instructions in the [Canary Channel XDA Thread](https://forum.xda-developers.com/apps/magisk/dev-magisk-canary-channel-bleeding-edge-t3839337), and report a bug either by opening an issue on GitHub or directly in the thread.
## Building Environment Requirements
1. Python 3.5+: run `build.py` script
@@ -15,20 +23,12 @@
4. Run `build.py` with argument `-h` to see the built-in help message. The `-h` option also works for each supported actions, e.g. `./build.py binary -h`
5. By default, `build.py` build binaries and Magisk Manager in debug mode. If you want to build Magisk Manager in release mode (via the `-r, --release` flag), you need a Java Keystore file `release-key.jks` (only `JKS` format is supported) to sign APKs and zips. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually).
## Bug Reports
**Make sure to install the latest [Canary Build](https://forum.xda-developers.com/apps/magisk/dev-magisk-canary-channel-bleeding-edge-t3839337) before reporting any bugs!** Please **DO NOT** report bugs that is already fixed upstream.
Follow the instructions in the [Canary Channel XDA Thread](https://forum.xda-developers.com/apps/magisk/dev-magisk-canary-channel-bleeding-edge-t3839337), and report a bug either by opening an issue on GitHub or directly in the thread.
## Documentation
[Link to Documentation](docs/README.MD)
## License
```
Magisk, including all git submodules are free software:
you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation,
you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,

View File

@@ -79,4 +79,12 @@ dependencies {
fullImplementation 'com.github.topjohnwu:libsu:2.0.2'
fullImplementation 'com.atlassian.commonmark:commonmark:0.11.0'
fullImplementation 'org.kamranzafar:jtar:2.3'
def butterKnifeVersion = '9.0.0-rc1'
if (properties.containsKey('android.injected.invoked.from.ide')) {
fullImplementation "com.jakewharton:butterknife-reflect:${butterKnifeVersion}"
} else {
fullImplementation "com.jakewharton:butterknife-runtime:${butterKnifeVersion}"
fullAnnotationProcessor "com.jakewharton:butterknife-compiler:${butterKnifeVersion}"
}
}

View File

@@ -15,16 +15,17 @@ import java.util.Locale;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
public class AboutActivity extends BaseActivity {
Toolbar toolbar;
AboutCardRow appVersionInfo;
AboutCardRow appChangelog;
AboutCardRow appTranslators;
AboutCardRow appSourceCode;
AboutCardRow supportThread;
AboutCardRow twitter;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.app_version_info) AboutCardRow appVersionInfo;
@BindView(R.id.app_changelog) AboutCardRow appChangelog;
@BindView(R.id.app_translators) AboutCardRow appTranslators;
@BindView(R.id.app_source_code) AboutCardRow appSourceCode;
@BindView(R.id.support_thread) AboutCardRow supportThread;
@BindView(R.id.follow_twitter) AboutCardRow twitter;
@Override
public int getDarkTheme() {
@@ -35,7 +36,7 @@ public class AboutActivity extends BaseActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
ViewBinder.bind(this);
new AboutActivity_ViewBinding(this);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish());

View File

@@ -41,7 +41,6 @@ public class Const {
/* A list of apps that should not be shown as hide-able */
public static final List<String> HIDE_BLACKLIST = Arrays.asList(
"android",
Data.MM().getPackageName(),
"com.google.android.gms"
);
@@ -49,11 +48,6 @@ public class Const {
public static final int USER_ID = Process.myUid() / 100000;
public static final class MAGISK_VER {
public static final int UNIFIED = 1300;
public static final int FBE_AWARE = 1410;
public static final int RESETPROP_PERSIST = 1436;
public static final int MANAGER_HIDE = 1440;
public static final int HIDDEN_PATH = 1460;
public static final int REMOVE_LEGACY_LINK = 1630;
public static final int SEPOL_REFACTOR = 1640;
public static final int FIX_ENV = 1650;

View File

@@ -95,8 +95,7 @@ public class Data {
try {
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0];
magiskVersionCode = Integer.parseInt(ShellUtils.fastCmd("magisk -V"));
String s = ShellUtils.fastCmd((magiskVersionCode >= Const.MAGISK_VER.RESETPROP_PERSIST ?
"resetprop -p " : "getprop ") + Const.MAGISKHIDE_PROP);
String s = ShellUtils.fastCmd(("resetprop -p ") + Const.MAGISKHIDE_PROP);
magiskHide = s.isEmpty() || Integer.parseInt(s) != 0;
} catch (NumberFormatException ignored) {}
}

View File

@@ -10,12 +10,13 @@ import com.topjohnwu.magisk.utils.Utils;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
public class DonationActivity extends BaseActivity {
Toolbar toolbar;
AboutCardRow paypal;
AboutCardRow patreon;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.paypal) AboutCardRow paypal;
@BindView(R.id.patreon) AboutCardRow patreon;
@Override
public int getDarkTheme() {
@@ -26,7 +27,7 @@ public class DonationActivity extends BaseActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_donation);
ViewBinder.bind(this);
new DonationActivity_ViewBinding(this);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish());

View File

@@ -31,25 +31,25 @@ import java.util.Locale;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
import butterknife.OnClick;
public class FlashActivity extends BaseActivity {
Toolbar toolbar;
TextView flashLogs;
public LinearLayout buttonPanel;
public Button reboot;
ScrollView sv;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.txtLog) TextView flashLogs;
@BindView(R.id.button_panel) public LinearLayout buttonPanel;
@BindView(R.id.reboot) public Button reboot;
@BindView(R.id.scrollView) ScrollView sv;
private List<String> logs;
void dismiss() {
finish();
}
@OnClick(R.id.reboot)
void reboot() {
Shell.su("/system/bin/reboot").submit();
}
@OnClick(R.id.save_logs)
void saveLogs() {
runWithPermission(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, () -> {
Calendar now = Calendar.getInstance();
@@ -82,7 +82,8 @@ public class FlashActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flash);
ViewBinder.bind(this);
new FlashActivity_ViewBinding(this);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
if (ab != null) {
@@ -133,13 +134,18 @@ public class FlashActivity extends BaseActivity {
new InstallMagisk(this, console, logs, InstallMagisk.SECOND_SLOT_MODE).exec();
break;
case Const.Value.PATCH_BOOT:
runWithPermission(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
() -> new InstallMagisk(this, console, logs,
intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)).exec());
new InstallMagisk(this, console, logs,
intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)).exec();
break;
}
}
@OnClick(R.id.close)
@Override
public void finish() {
super.finish();
}
@Override
public void onBackPressed() {
// Prevent user accidentally press back button

View File

@@ -38,7 +38,7 @@ public class MagiskManager extends ContainerApp {
Shell.Config.setInitializer(RootUtils.class);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
mDB = MagiskDatabaseHelper.getInstance(this);
mDB = MagiskDatabaseHelper.getInstance();
String pkg = mDB.getStrings(Const.Key.SU_MANAGER, null);
if (pkg != null && getPackageName().equals(Const.ORIG_PKG_NAME)) {

View File

@@ -26,6 +26,7 @@ import androidx.appcompat.widget.Toolbar;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import butterknife.BindView;
public class MainActivity extends BaseActivity
implements NavigationView.OnNavigationItemSelectedListener, Topic.Subscriber {
@@ -34,9 +35,9 @@ public class MainActivity extends BaseActivity
private int mDrawerItem;
private static boolean fromShortcut = false;
public Toolbar toolbar;
DrawerLayout drawer;
NavigationView navigationView;
@BindView(R.id.toolbar) public Toolbar toolbar;
@BindView(R.id.drawer_layout) DrawerLayout drawer;
@BindView(R.id.nav_view) NavigationView navigationView;
private float toolbarElevation;
@@ -54,7 +55,7 @@ public class MainActivity extends BaseActivity
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewBinder.bind(this);
new MainActivity_ViewBinding(this);
setSupportActionBar(toolbar);
@@ -118,7 +119,6 @@ public class MainActivity extends BaseActivity
public void checkHideSection() {
Menu menu = navigationView.getMenu();
menu.findItem(R.id.magiskhide).setVisible(Shell.rootAccess() &&
Data.magiskVersionCode >= Const.MAGISK_VER.UNIFIED &&
mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false));
menu.findItem(R.id.modules).setVisible(Shell.rootAccess() && Data.magiskVersionCode >= 0);
menu.findItem(R.id.downloads).setVisible(Download.checkNetworkStatus(this)

View File

@@ -27,17 +27,18 @@ import java.io.IOException;
import java.io.OutputStream;
import androidx.annotation.Nullable;
import butterknife.BindView;
public class SuRequestActivity extends BaseActivity {
LinearLayout suPopup;
Spinner timeout;
ImageView appIcon;
TextView appNameView;
TextView packageNameView;
Button grant_btn;
Button deny_btn;
ImageView fingerprintImg;
TextView warning;
@BindView(R.id.su_popup) LinearLayout suPopup;
@BindView(R.id.timeout) Spinner timeout;
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.app_name) TextView appNameView;
@BindView(R.id.package_name) TextView packageNameView;
@BindView(R.id.grant_btn) Button grant_btn;
@BindView(R.id.deny_btn) Button deny_btn;
@BindView(R.id.fingerprint) ImageView fingerprintImg;
@BindView(R.id.warning) TextView warning;
private SuConnector connector;
private Policy policy;
@@ -157,7 +158,7 @@ public class SuRequestActivity extends BaseActivity {
}
setContentView(R.layout.activity_request);
ViewBinder.bind(this);
new SuRequestActivity_ViewBinding(this);
appIcon.setImageDrawable(policy.info.loadIcon(pm));
appNameView.setText(policy.appName);

File diff suppressed because it is too large Load Diff

View File

@@ -3,8 +3,6 @@ package com.topjohnwu.magisk.adapters;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -17,9 +15,8 @@ import android.widget.TextView;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.utils.LocaleManager;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell;
import java.util.ArrayList;
@@ -29,6 +26,7 @@ import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.ViewHolder> {
@@ -52,25 +50,12 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
return new ViewHolder(v);
}
private String getLabel(ApplicationInfo info) {
if (info.labelRes > 0) {
try {
Resources res = pm.getResourcesForApplication(info);
Configuration config = new Configuration();
config.setLocale(LocaleManager.locale);
res.updateConfiguration(config, res.getDisplayMetrics());
return res.getString(info.labelRes);
} catch (PackageManager.NameNotFoundException ignored) { /* Impossible */ }
}
return info.loadLabel(pm).toString();
}
private void loadApps() {
fullList = pm.getInstalledApplications(0);
hideList = Shell.su("magiskhide --ls").exec().getOut();
for (Iterator<ApplicationInfo> i = fullList.iterator(); i.hasNext(); ) {
ApplicationInfo info = i.next();
if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled) {
if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled || info.uid == 1000) {
i.remove();
}
}
@@ -78,7 +63,8 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
boolean ah = hideList.contains(a.packageName);
boolean bh = hideList.contains(b.packageName);
if (ah == bh) {
return getLabel(a).toLowerCase().compareTo(getLabel(b).toLowerCase());
return Utils.getAppLabel(a, pm).toLowerCase()
.compareTo(Utils.getAppLabel(b, pm).toLowerCase());
} else if (ah) {
return -1;
} else {
@@ -93,7 +79,7 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
ApplicationInfo info = showList.get(position);
holder.appIcon.setImageDrawable(info.loadIcon(pm));
holder.appName.setText(getLabel(info));
holder.appName.setText(Utils.getAppLabel(info, pm));
holder.appPackage.setText(info.packageName);
holder.checkBox.setOnCheckedChangeListener(null);
@@ -122,20 +108,20 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView appIcon;
public TextView appName;
public TextView appPackage;
public CheckBox checkBox;
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.app_name) TextView appName;
@BindView(R.id.package_name) TextView appPackage;
@BindView(R.id.checkbox) CheckBox checkBox;
ViewHolder(View itemView) {
super(itemView);
ViewBinder.bind(this, itemView);
new ApplicationAdapter$ViewHolder_ViewBinding(this, itemView);
}
}
private class ApplicationFilter extends Filter {
class ApplicationFilter extends Filter {
private boolean lowercaseContains(String s, CharSequence filter) {
return !TextUtils.isEmpty(s) && s.toLowerCase().contains(filter);
@@ -149,7 +135,7 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
showList = new ArrayList<>();
String filter = constraint.toString().toLowerCase();
for (ApplicationInfo info : fullList) {
if (lowercaseContains(getLabel(info), filter)
if (lowercaseContains(Utils.getAppLabel(info, pm), filter)
|| lowercaseContains(info.packageName, filter)) {
showList.add(info);
}

View File

@@ -11,14 +11,15 @@ import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.superuser.Shell;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHolder> {
@@ -28,6 +29,7 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
mList = list;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false);
@@ -101,19 +103,19 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
return mList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
static class ViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public TextView versionName;
public TextView description;
public TextView notice;
public CheckBox checkBox;
public TextView author;
public ImageView delete;
@BindView(R.id.title) TextView title;
@BindView(R.id.version_name) TextView versionName;
@BindView(R.id.description) TextView description;
@BindView(R.id.notice) TextView notice;
@BindView(R.id.checkbox) CheckBox checkBox;
@BindView(R.id.author) TextView author;
@BindView(R.id.delete) ImageView delete;
ViewHolder(View itemView) {
super(itemView);
ViewBinder.bind(this, itemView);
new ModulesAdapter$ViewHolder_ViewBinding(this, itemView);
if (!Shell.rootAccess()) {
checkBox.setEnabled(false);

View File

@@ -10,19 +10,22 @@ import android.widget.Switch;
import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.components.CustomAlertDialog;
import com.topjohnwu.magisk.components.ExpandableView;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder> {
@@ -37,6 +40,7 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
this.pm = pm;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_policy, parent, false);
@@ -62,14 +66,34 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
holder.appName.setText(policy.appName);
holder.packageName.setText(policy.packageName);
holder.appIcon.setImageDrawable(policy.info.loadIcon(pm));
holder.masterSwitch.setOnCheckedChangeListener((v, isChecked) -> {
if ((isChecked && policy.policy == Policy.DENY) ||
(!isChecked && policy.policy == Policy.ALLOW)) {
policy.policy = isChecked ? Policy.ALLOW : Policy.DENY;
String message = v.getContext().getString(
isChecked ? R.string.su_snack_grant : R.string.su_snack_deny, policy.appName);
SnackbarMaker.make(holder.itemView, message, Snackbar.LENGTH_SHORT).show();
dbHelper.updatePolicy(policy);
holder.notificationSwitch.setOnCheckedChangeListener(null);
holder.loggingSwitch.setOnCheckedChangeListener(null);
holder.masterSwitch.setChecked(policy.policy == Policy.ALLOW);
holder.notificationSwitch.setChecked(policy.notification);
holder.loggingSwitch.setChecked(policy.logging);
holder.masterSwitch.setOnClickListener(v -> {
boolean isChecked = holder.masterSwitch.isChecked();
Runnable r = () -> {
if ((isChecked && policy.policy == Policy.DENY) ||
(!isChecked && policy.policy == Policy.ALLOW)) {
policy.policy = isChecked ? Policy.ALLOW : Policy.DENY;
String message = v.getContext().getString(
isChecked ? R.string.su_snack_grant : R.string.su_snack_deny, policy.appName);
SnackbarMaker.make(holder.itemView, message, Snackbar.LENGTH_SHORT).show();
dbHelper.updatePolicy(policy);
}
};
if (Data.suFingerprint) {
holder.masterSwitch.setChecked(!isChecked);
FingerprintHelper.showAuthDialog((Activity) v.getContext(), () -> {
holder.masterSwitch.setChecked(isChecked);
r.run();
});
} else {
r.run();
}
});
holder.notificationSwitch.setOnCheckedChangeListener((v, isChecked) -> {
@@ -106,9 +130,6 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
.setNegativeButton(R.string.no_thanks, null)
.setCancelable(true)
.show());
holder.masterSwitch.setChecked(policy.policy == Policy.ALLOW);
holder.notificationSwitch.setChecked(policy.notification);
holder.loggingSwitch.setChecked(policy.logging);
// Hide for now
holder.moreInfo.setVisibility(View.GONE);
@@ -119,24 +140,24 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
return policyList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
static class ViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
public TextView appName;
public TextView packageName;
public ImageView appIcon;
public Switch masterSwitch;
public Switch notificationSwitch;
public Switch loggingSwitch;
public ViewGroup expandLayout;
@BindView(R.id.app_name) TextView appName;
@BindView(R.id.package_name) TextView packageName;
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.master_switch) Switch masterSwitch;
@BindView(R.id.notification_switch) Switch notificationSwitch;
@BindView(R.id.logging_switch) Switch loggingSwitch;
@BindView(R.id.expand_layout) ViewGroup expandLayout;
public ImageView delete;
public ImageView moreInfo;
@BindView(R.id.delete) ImageView delete;
@BindView(R.id.more_info) ImageView moreInfo;
private Container container = new Container();
public ViewHolder(View itemView) {
super(itemView);
ViewBinder.bind(this, itemView);
new PolicyAdapter$ViewHolder_ViewBinding(this, itemView);
container.expandLayout = expandLayout;
setupExpandable();
}

View File

@@ -12,7 +12,6 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
import com.topjohnwu.magisk.asyncs.ProcessRepoZip;
import com.topjohnwu.magisk.components.BaseActivity;
@@ -26,6 +25,7 @@ import java.util.List;
import java.util.Map;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, ReposAdapter.RepoHolder> {
@@ -163,29 +163,29 @@ public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, R
notifyDataSetChanged();
}
public static class SectionHolder extends RecyclerView.ViewHolder {
static class SectionHolder extends RecyclerView.ViewHolder {
public TextView sectionText;
@BindView(R.id.section_text) TextView sectionText;
SectionHolder(View itemView) {
super(itemView);
ViewBinder.bind(this, itemView);
new ReposAdapter$SectionHolder_ViewBinding(this, itemView);
}
}
public static class RepoHolder extends RecyclerView.ViewHolder {
static class RepoHolder extends RecyclerView.ViewHolder {
public TextView title;
public TextView versionName;
public TextView description;
public TextView author;
public LinearLayout infoLayout;
public ImageView downloadImage;
public TextView updateTime;
@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;
@BindView(R.id.update_time) TextView updateTime;
RepoHolder(View itemView) {
super(itemView);
ViewBinder.bind(this, itemView);
new ReposAdapter$RepoHolder_ViewBinding(this, itemView);
}
}

View File

@@ -10,7 +10,6 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.components.ExpandableView;
import com.topjohnwu.magisk.container.SuLogEntry;
import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
@@ -21,6 +20,7 @@ import java.util.List;
import java.util.Set;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, SuLogAdapter.LogViewHolder> {
@@ -116,32 +116,32 @@ public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, S
notifyDataSetChanged();
}
public static class SectionHolder extends RecyclerView.ViewHolder {
static class SectionHolder extends RecyclerView.ViewHolder {
public TextView date;
public ImageView arrow;
@BindView(R.id.date) TextView date;
@BindView(R.id.arrow) ImageView arrow;
SectionHolder(View itemView) {
super(itemView);
ViewBinder.bind(this, itemView);
new SuLogAdapter$SectionHolder_ViewBinding(this, itemView);
}
}
public static class LogViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
static class LogViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
public TextView appName;
public TextView action;
public TextView time;
public TextView fromPid;
public TextView toUid;
public TextView command;
public ViewGroup expandLayout;
@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;
@BindView(R.id.expand_layout) ViewGroup expandLayout;
private Container container = new Container();
LogViewHolder(View itemView) {
super(itemView);
ViewBinder.bind(this, itemView);
new SuLogAdapter$LogViewHolder_ViewBinding(this, itemView);
container.expandLayout = expandLayout;
setupExpandable();
}

View File

@@ -111,6 +111,7 @@ public class PatchAPK {
repack.delete();
mm.mDB.setStrings(Const.Key.SU_MANAGER, pkg);
mm.mDB.flush();
Data.exportPrefs();
RootUtils.uninstallPkg(Const.ORIG_PKG_NAME);

View File

@@ -66,17 +66,15 @@ public class UpdateRepos {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject rawRepo = jsonArray.getJSONObject(i);
String id = rawRepo.getString("description");
String name = rawRepo.getString("name");
String id = rawRepo.getString("name");
Date date = dateFormat.parse(rawRepo.getString("pushed_at"));
Set<String> set = Collections.synchronizedSet(cached);
threadPool.execute(() -> {
Repo repo = mm.repoDB.getRepo(id);
try {
if (repo == null)
repo = new Repo(name);
repo = new Repo(id);
else
set.remove(id);
cached.remove(id);
repo.update(date);
mm.repoDB.addRepo(repo);
} catch (Repo.IllegalRepoException e) {
@@ -141,7 +139,7 @@ public class UpdateRepos {
public void exec(boolean force) {
Topic.reset(Topic.REPO_LOAD_DONE);
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
cached = mm.repoDB.getRepoIDSet();
cached = Collections.synchronizedSet(mm.repoDB.getRepoIDSet());
threadPool = Executors.newFixedThreadPool(CORE_POOL_SIZE);
if (loadPage(0)) {

View File

@@ -27,17 +27,18 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import butterknife.BindView;
/**
* @author dvdandroid
*/
public class AboutCardRow extends LinearLayout {
public TextView mTitle;
public TextView mSummary;
public ImageView mIcon;
public View mView;
@BindView(android.R.id.title) TextView mTitle;
@BindView(android.R.id.summary) TextView mSummary;
@BindView(android.R.id.icon) ImageView mIcon;
@BindView(R.id.container) View mView;
public AboutCardRow(Context context) {
this(context, null);
@@ -50,7 +51,7 @@ public class AboutCardRow extends LinearLayout {
public AboutCardRow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.info_item_row, this);
ViewBinder.bind(this, this);
new AboutCardRow_ViewBinding(this, this);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AboutCardRow, 0, 0);
String title;

View File

@@ -7,10 +7,12 @@ import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Topic;
import androidx.fragment.app.Fragment;
import butterknife.Unbinder;
public class BaseFragment extends Fragment implements Topic.AutoSubscriber {
public MagiskManager mm;
protected Unbinder unbinder = null;
public BaseFragment() {
mm = Data.MM();
@@ -28,6 +30,13 @@ public class BaseFragment extends Fragment implements Topic.AutoSubscriber {
super.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (unbinder != null)
unbinder.unbind();
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, this::onActivityResult);

View File

@@ -9,13 +9,13 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AlertDialog;
import butterknife.BindView;
public class CustomAlertDialog extends AlertDialog.Builder {
@@ -27,16 +27,16 @@ public class CustomAlertDialog extends AlertDialog.Builder {
private ViewHolder vh;
public class ViewHolder {
public LinearLayout dialogLayout;
public LinearLayout buttons;
@BindView(R.id.dialog_layout) public LinearLayout dialogLayout;
@BindView(R.id.button_panel) public LinearLayout buttons;
public TextView messageView;
public Button negative;
public Button positive;
public Button neutral;
@BindView(R.id.message) public TextView messageView;
@BindView(R.id.negative) public Button negative;
@BindView(R.id.positive) public Button positive;
@BindView(R.id.neutral) public Button neutral;
ViewHolder(View v) {
ViewBinder.bind(this, v);
new CustomAlertDialog$ViewHolder_ViewBinding(this, v);
messageView.setVisibility(View.GONE);
negative.setVisibility(View.GONE);
positive.setVisibility(View.GONE);

View File

@@ -1,11 +1,12 @@
package com.topjohnwu.magisk.components;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.FlashActivity;
@@ -27,23 +28,21 @@ class InstallMethodDialog extends AlertDialog.Builder {
Intent intent;
switch (idx) {
case 1:
if (Data.remoteMagiskVersionCode < 1400) {
SnackbarMaker.make(activity, R.string.no_boot_file_patch_support,
Snackbar.LENGTH_LONG).show();
return;
}
Utils.toast(R.string.boot_file_patch_msg, Toast.LENGTH_LONG);
intent = new Intent(Intent.ACTION_GET_CONTENT).setType("*/*");
activity.startActivityForResult(intent, Const.ID.SELECT_BOOT,
(requestCode, resultCode, data) -> {
if (requestCode == Const.ID.SELECT_BOOT &&
resultCode == BaseActivity.RESULT_OK && data != null) {
Intent i = new Intent(activity, Data.classMap.get(FlashActivity.class))
.putExtra(Const.Key.FLASH_SET_BOOT, data.getData())
.putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_BOOT);
activity.startActivity(i);
}
});
activity.runWithPermission(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, () ->
activity.startActivityForResult(intent, Const.ID.SELECT_BOOT,
(requestCode, resultCode, data) -> {
if (requestCode == Const.ID.SELECT_BOOT &&
resultCode == Activity.RESULT_OK && data != null) {
Intent i = new Intent(activity, Data.classMap.get(FlashActivity.class))
.putExtra(Const.Key.FLASH_SET_BOOT, data.getData())
.putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_BOOT);
activity.startActivity(i);
}
})
);
break;
case 0:
String filename = Utils.fmt("Magisk-v%s(%d).zip",
@@ -62,16 +61,16 @@ class InstallMethodDialog extends AlertDialog.Builder {
break;
case 3:
new CustomAlertDialog(activity)
.setTitle(R.string.warning)
.setMessage(R.string.install_inactive_slot_msg)
.setCancelable(true)
.setPositiveButton(R.string.yes, (d, i) -> {
Intent it = new Intent(activity, Data.classMap.get(FlashActivity.class))
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_INACTIVE_SLOT);
activity.startActivity(it);
})
.setNegativeButton(R.string.no_thanks, null)
.show();
.setTitle(R.string.warning)
.setMessage(R.string.install_inactive_slot_msg)
.setCancelable(true)
.setPositiveButton(R.string.yes, (d, i) -> {
Intent it = new Intent(activity, Data.classMap.get(FlashActivity.class))
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_INACTIVE_SLOT);
activity.startActivity(it);
})
.setNegativeButton(R.string.no_thanks, null)
.show();
break;
default:
}

View File

@@ -5,6 +5,8 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import com.topjohnwu.magisk.utils.Utils;
import androidx.annotation.NonNull;
@@ -26,7 +28,7 @@ public class Policy implements Comparable<Policy>{
this.uid = uid;
packageName = pkgs[0];
info = pm.getApplicationInfo(packageName, 0);
appName = info.loadLabel(pm).toString();
appName = Utils.getAppLabel(info, pm);
}
public Policy(Cursor c, PackageManager pm) throws PackageManager.NameNotFoundException {

View File

@@ -2,7 +2,6 @@ package com.topjohnwu.magisk.container;
import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.utils.Download;
@@ -15,16 +14,14 @@ import java.util.Date;
public class Repo extends BaseModule {
private String repoName;
private Date mLastUpdate;
public Repo(String name) {
repoName = name;
public Repo(String id) {
setId(id);
}
public Repo(Cursor c) {
super(c);
repoName = c.getString(c.getColumnIndex("repo_name"));
mLastUpdate = new Date(c.getLong(c.getColumnIndex("last_update")));
}
@@ -33,17 +30,14 @@ public class Repo extends BaseModule {
try {
parseProps(props);
} catch (NumberFormatException e) {
throw new IllegalRepoException("Repo [" + repoName + "] parse error: " + e.getMessage());
throw new IllegalRepoException("Repo [" + getId() + "] parse error: " + e.getMessage());
}
if (TextUtils.isEmpty(getId())) {
throw new IllegalRepoException("Repo [" + repoName + "] does not contain id");
}
if (getVersionCode() < 0) {
throw new IllegalRepoException("Repo [" + repoName + "] does not contain versionCode");
throw new IllegalRepoException("Repo [" + getId() + "] does not contain versionCode");
}
if (getMinMagiskVersion() < Const.MIN_MODULE_VER()) {
Logger.debug("Repo [" + repoName + "] is outdated");
Logger.debug("Repo [" + getId() + "] is outdated");
}
}
@@ -55,25 +49,20 @@ public class Repo extends BaseModule {
@Override
public ContentValues getContentValues() {
ContentValues values = super.getContentValues();
values.put("repo_name", repoName);
values.put("last_update", mLastUpdate.getTime());
return values;
}
public String getRepoName() {
return repoName;
}
public String getZipUrl() {
return String.format(Const.Url.ZIP_URL, repoName);
return String.format(Const.Url.ZIP_URL, getId());
}
public String getManifestUrl() {
return String.format(Const.Url.FILE_URL, repoName, "module.prop");
return String.format(Const.Url.FILE_URL, getId(), "module.prop");
}
public String getDetailUrl() {
return String.format(Const.Url.FILE_URL, repoName, "README.md");
return String.format(Const.Url.FILE_URL, getId(), "README.md");
}
public String getLastUpdateString() {

View File

@@ -38,26 +38,30 @@ public class MagiskDatabaseHelper {
private static final String LOG_TABLE = "logs";
private static final String SETTINGS_TABLE = "settings";
private static final String STRINGS_TABLE = "strings";
private static final File MANAGER_DB =
new File(Utils.fmt("/sbin/.core/db-%d/magisk.db", Const.USER_ID));
private PackageManager pm;
private SQLiteDatabase db;
private MagiskManager mm;
@NonNull
public static MagiskDatabaseHelper getInstance(MagiskManager mm) {
public static MagiskDatabaseHelper getInstance() {
try {
return new MagiskDatabaseHelper(mm);
return new MagiskDatabaseHelper();
} catch (Exception e) {
// Let's cleanup everything and try again
Shell.su("db_clean '*'").exec();
return new MagiskDatabaseHelper(mm);
return new MagiskDatabaseHelper();
}
}
private MagiskDatabaseHelper(MagiskManager context) {
mm = context;
pm = mm.getPackageManager();
db = openDatabase(mm);
private MagiskDatabaseHelper() {
pm = Data.MM().getPackageManager();
init();
}
private void init() {
db = openDatabase();
db.disableWriteAheadLogging();
int version = Data.magiskVersionCode >= Const.MAGISK_VER.DBVER_SIX ? DATABASE_VER : OLD_DATABASE_VER;
int curVersion = db.getVersion();
@@ -71,48 +75,37 @@ public class MagiskDatabaseHelper {
clearOutdated();
}
private SQLiteDatabase openDatabase(MagiskManager mm) {
final File DB_FILE = new File(Utils.fmt("/sbin/.core/db-%d/magisk.db", Const.USER_ID));
private SQLiteDatabase openDatabase() {
MagiskManager mm = Data.MM();
Context de = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
? mm.createDeviceProtectedStorageContext() : mm;
if (!DB_FILE.canWrite()) {
if (!MANAGER_DB.canWrite()) {
if (!Shell.rootAccess()) {
// We don't want the app to crash, create a db and return
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
}
// Cleanup
Shell.su("db_clean " + Const.USER_ID).exec();
if (Data.magiskVersionCode < Const.MAGISK_VER.FBE_AWARE) {
// Super old legacy mode
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
} else if (Data.magiskVersionCode < Const.MAGISK_VER.HIDDEN_PATH) {
// Legacy mode with FBE aware
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
de.moveDatabaseFrom(mm, "su.db");
}
return de.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
} else {
// Global database
final SuFile GLOBAL_DB = new SuFile("/data/adb/magisk.db");
mm.deleteDatabase("su.db");
de.deleteDatabase("su.db");
if (Data.magiskVersionCode < Const.MAGISK_VER.SEPOL_REFACTOR) {
// We need some additional policies on old versions
Shell.su("db_sepatch").exec();
}
if (!GLOBAL_DB.exists()) {
Shell.su("db_init").exec();
SQLiteDatabase.openOrCreateDatabase(GLOBAL_DB, null).close();
Shell.su("db_restore").exec();
}
// Global database
final SuFile GLOBAL_DB = new SuFile("/data/adb/magisk.db");
mm.deleteDatabase("su.db");
de.deleteDatabase("su.db");
if (Data.magiskVersionCode < Const.MAGISK_VER.SEPOL_REFACTOR) {
// We need some additional policies on old versions
Shell.su("db_sepatch").exec();
}
if (!GLOBAL_DB.exists()) {
Shell.su("db_init").exec();
SQLiteDatabase.openOrCreateDatabase(GLOBAL_DB, null).close();
Shell.su("db_restore").exec();
}
Shell.su("db_setup " + Process.myUid()).exec();
}
// Not using legacy mode, open the mounted global DB
return SQLiteDatabase.openOrCreateDatabase(DB_FILE, null);
return SQLiteDatabase.openOrCreateDatabase(MANAGER_DB, null);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion) {
private void onUpgrade(SQLiteDatabase db, int oldVersion) {
if (oldVersion == 0) {
createTables(db);
oldVersion = 3;
@@ -147,13 +140,13 @@ public class MagiskDatabaseHelper {
}
if (oldVersion == 5) {
setSettings(Const.Key.SU_FINGERPRINT,
mm.prefs.getBoolean(Const.Key.SU_FINGERPRINT, false) ? 1 : 0);
Data.MM().prefs.getBoolean(Const.Key.SU_FINGERPRINT, false) ? 1 : 0);
++oldVersion;
}
}
// Remove everything, we do not support downgrade
public void onDowngrade(SQLiteDatabase db) {
private void onDowngrade(SQLiteDatabase db) {
Utils.toast(R.string.su_db_corrupt, Toast.LENGTH_LONG);
db.execSQL("DROP TABLE IF EXISTS " + POLICY_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + LOG_TABLE);
@@ -182,6 +175,11 @@ public class MagiskDatabaseHelper {
"(key TEXT, value INT, PRIMARY KEY(key))");
}
public void flush() {
db.close();
init();
}
public void clearOutdated() {
// Clear outdated policies
db.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < %d", System.currentTimeMillis() / 1000), null);

View File

@@ -16,7 +16,7 @@ import java.util.Set;
public class RepoDatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VER = 3;
private static final int DATABASE_VER = 4;
private static final String TABLE_NAME = "repos";
private SQLiteDatabase mDb;
@@ -40,21 +40,14 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
if (oldVersion < 3) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " " +
"(id TEXT, name TEXT, version TEXT, versionCode INT, minMagisk INT, " +
"author TEXT, description TEXT, repo_name TEXT, last_update INT, " +
"PRIMARY KEY(id))");
mm.prefs.edit().remove(Const.Key.ETAG_KEY).apply();
oldVersion = 3;
}
} catch (Exception e) {
e.printStackTrace();
// Reset database
onDowngrade(db, DATABASE_VER, 0);
if (oldVersion != newVersion) {
// Nuke old DB and create new table
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " " +
"(id TEXT, name TEXT, version TEXT, versionCode INT, minMagisk INT, " +
"author TEXT, description TEXT, last_update INT, PRIMARY KEY(id))");
mm.prefs.edit().remove(Const.Key.ETAG_KEY).apply();
}
}
@@ -75,8 +68,7 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
}
public void removeRepo(Repo repo) {
mDb.delete(TABLE_NAME, "repo_name=?", new String[] { repo.getRepoName() });
notifyAdapter();
removeRepo(repo.getId());
}
public void removeRepo(Iterable<String> list) {

View File

@@ -11,23 +11,23 @@ import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.MainActivity;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.TabFragmentAdapter;
import com.topjohnwu.magisk.components.BaseFragment;
import androidx.viewpager.widget.ViewPager;
import butterknife.BindView;
public class LogFragment extends BaseFragment {
public ViewPager viewPager;
public TabLayout tab;
@BindView(R.id.container) ViewPager viewPager;
@BindView(R.id.tab) TabLayout tab;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_log, container, false);
ViewBinder.bind(this, v);
unbinder = new LogFragment_ViewBinding(this, v);
((MainActivity) requireActivity()).toolbar.setElevation(0);
@@ -44,10 +44,4 @@ public class LogFragment extends BaseFragment {
return v;
}
@Override
public void onDestroyView() {
super.onDestroyView();
ViewBinder.unbind(this);
}
}

View File

@@ -20,7 +20,6 @@ import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.MainActivity;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.asyncs.CheckSafetyNet;
import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.components.BaseActivity;
@@ -42,6 +41,9 @@ import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.cardview.widget.CardView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindColor;
import butterknife.BindView;
import butterknife.OnClick;
public class MagiskFragment extends BaseFragment
implements SwipeRefreshLayout.OnRefreshListener, ExpandableView, Topic.Subscriber {
@@ -49,41 +51,42 @@ public class MagiskFragment extends BaseFragment
private Container expandableContainer = new Container();
private static boolean shownDialog = false;
public SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.swipeRefreshLayout) public SwipeRefreshLayout mSwipeRefreshLayout;
public CardView coreOnlyNotice;
@BindView(R.id.core_only_notice) CardView coreOnlyNotice;
public RelativeLayout magiskUpdate;
public ImageView magiskUpdateIcon;
public TextView magiskUpdateText;
public ProgressBar magiskUpdateProgress;
public ImageView magiskStatusIcon;
public TextView magiskVersionText;
@BindView(R.id.magisk_update) RelativeLayout magiskUpdate;
@BindView(R.id.magisk_update_icon) ImageView magiskUpdateIcon;
@BindView(R.id.magisk_update_status) TextView magiskUpdateText;
@BindView(R.id.magisk_update_progress) ProgressBar magiskUpdateProgress;
@BindView(R.id.magisk_status_icon) ImageView magiskStatusIcon;
@BindView(R.id.magisk_version) TextView magiskVersionText;
public CardView safetyNetCard;
public ImageView safetyNetRefreshIcon;
public TextView safetyNetStatusText;
public ProgressBar safetyNetProgress;
public LinearLayout expandLayout;
public ImageView ctsStatusIcon;
public TextView ctsStatusText;
public ImageView basicStatusIcon;
public TextView basicStatusText;
@BindView(R.id.safetyNet_card) CardView safetyNetCard;
@BindView(R.id.safetyNet_refresh) ImageView safetyNetRefreshIcon;
@BindView(R.id.safetyNet_status) TextView safetyNetStatusText;
@BindView(R.id.safetyNet_check_progress) ProgressBar safetyNetProgress;
@BindView(R.id.expand_layout) LinearLayout expandLayout;
@BindView(R.id.cts_status_icon) ImageView ctsStatusIcon;
@BindView(R.id.cts_status) TextView ctsStatusText;
@BindView(R.id.basic_status_icon) ImageView basicStatusIcon;
@BindView(R.id.basic_status) TextView basicStatusText;
public CardView installOptionCard;
public CheckBox keepEncChkbox;
public CheckBox keepVerityChkbox;
public CardView installButton;
public TextView installText;
public CardView uninstallButton;
@BindView(R.id.install_option_card) CardView installOptionCard;
@BindView(R.id.keep_force_enc) CheckBox keepEncChkbox;
@BindView(R.id.keep_verity) CheckBox keepVerityChkbox;
@BindView(R.id.install_button) CardView installButton;
@BindView(R.id.install_text) TextView installText;
@BindView(R.id.uninstall_button) CardView uninstallButton;
public int colorBad;
public int colorOK;
public int colorWarn;
public int colorNeutral;
public int colorInfo;
@BindColor(R.color.red500) int colorBad;
@BindColor(R.color.green500) int colorOK;
@BindColor(R.color.yellow500) int colorWarn;
@BindColor(R.color.green500) int colorNeutral;
@BindColor(R.color.blue500) int colorInfo;
public void safetyNet() {
@OnClick(R.id.safetyNet_title)
void safetyNet() {
Runnable task = () -> {
safetyNetProgress.setVisibility(View.VISIBLE);
safetyNetRefreshIcon.setVisibility(View.GONE);
@@ -106,7 +109,8 @@ public class MagiskFragment extends BaseFragment
}
public void install() {
@OnClick(R.id.install_button)
void install() {
shownDialog = true;
// Show Manager update first
@@ -119,7 +123,8 @@ public class MagiskFragment extends BaseFragment
new MagiskInstallDialog((BaseActivity) getActivity()).show();
}
public void uninstall() {
@OnClick(R.id.uninstall_button)
void uninstall() {
new UninstallDialog(requireActivity()).show();
}
@@ -128,7 +133,7 @@ public class MagiskFragment extends BaseFragment
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_magisk, container, false);
ViewBinder.bind(this, v);
unbinder = new MagiskFragment_ViewBinding(this, v);
requireActivity().setTitle(R.string.magisk);
expandableContainer.expandLayout = expandLayout;
@@ -145,12 +150,6 @@ public class MagiskFragment extends BaseFragment
return v;
}
@Override
public void onDestroyView() {
super.onDestroyView();
ViewBinder.unbind(this);
}
@Override
public void onRefresh() {
Data.loadMagiskInfo();
@@ -215,11 +214,10 @@ public class MagiskFragment extends BaseFragment
boolean hasNetwork = Download.checkNetworkStatus(mm);
boolean hasRoot = Shell.rootAccess();
boolean isUpToDate = Data.magiskVersionCode > Const.MAGISK_VER.UNIFIED;
magiskUpdate.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
installOptionCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
uninstallButton.setVisibility(isUpToDate && hasRoot ? View.VISIBLE : View.GONE);
uninstallButton.setVisibility(hasRoot ? View.VISIBLE : View.GONE);
coreOnlyNotice.setVisibility(mm.prefs.getBoolean(Const.Key.COREONLY, false) ? View.VISIBLE : View.GONE);
int image, color;

View File

@@ -9,7 +9,6 @@ import android.view.ViewGroup;
import android.widget.SearchView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.ApplicationAdapter;
import com.topjohnwu.magisk.components.BaseFragment;
import com.topjohnwu.magisk.utils.Topic;
@@ -18,11 +17,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindView;
public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber {
public SwipeRefreshLayout mSwipeRefreshLayout;
public RecyclerView recyclerView;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
SearchView search;
private ApplicationAdapter appAdapter;
@@ -39,7 +39,7 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_magisk_hide, container, false);
ViewBinder.bind(this, view);
unbinder = new MagiskHideFragment_ViewBinding(this, view);
appAdapter = new ApplicationAdapter(requireActivity());
recyclerView.setAdapter(appAdapter);
@@ -73,12 +73,6 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber
search.setOnQueryTextListener(searchListener);
}
@Override
public void onDestroyView() {
super.onDestroyView();
ViewBinder.unbind(this);
}
@Override
public int[] getSubscribedTopics() {
return new int[] {Topic.MAGISK_HIDE_DONE};

View File

@@ -17,7 +17,6 @@ import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.components.BaseFragment;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Download;
@@ -29,19 +28,20 @@ import java.io.IOException;
import java.util.Calendar;
import androidx.annotation.Nullable;
import butterknife.BindView;
public class MagiskLogFragment extends BaseFragment {
public TextView txtLog;
public ScrollView svLog;
public HorizontalScrollView hsvLog;
public ProgressBar progressBar;
@BindView(R.id.txtLog) TextView txtLog;
@BindView(R.id.svLog) ScrollView svLog;
@BindView(R.id.hsvLog) HorizontalScrollView hsvLog;
@BindView(R.id.progressBar) ProgressBar progressBar;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_magisk_log, container, false);
ViewBinder.bind(this, view);
unbinder = new MagiskLogFragment_ViewBinding(this, view);
setHasOptionsMenu(true);
txtLog.setTextIsSelectable(true);
return view;
@@ -59,12 +59,6 @@ public class MagiskLogFragment extends BaseFragment {
readLogs();
}
@Override
public void onDestroyView() {
super.onDestroyView();
ViewBinder.unbind(this);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_log, menu);
@@ -87,7 +81,7 @@ public class MagiskLogFragment extends BaseFragment {
}
}
public void readLogs() {
private void readLogs() {
Shell.su("cat " + Const.MAGISK_LOG + " | tail -n 5000").submit(result -> {
progressBar.setVisibility(View.GONE);
if (result.getOut().isEmpty())
@@ -99,7 +93,7 @@ public class MagiskLogFragment extends BaseFragment {
});
}
public void saveLogs() {
private void saveLogs() {
Calendar now = Calendar.getInstance();
String filename = Utils.fmt("magisk_log_%04d%02d%02d_%02d%02d%02d.log",
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
@@ -117,7 +111,7 @@ public class MagiskLogFragment extends BaseFragment {
SnackbarMaker.make(txtLog, logFile.getPath(), Snackbar.LENGTH_SHORT).show());
}
public void clearLogs() {
private void clearLogs() {
Shell.su("echo -n > " + Const.MAGISK_LOG).submit();
txtLog.setText(R.string.log_is_empty);
SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();

View File

@@ -16,7 +16,6 @@ import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.ModulesAdapter;
import com.topjohnwu.magisk.components.BaseFragment;
import com.topjohnwu.magisk.container.Module;
@@ -32,14 +31,17 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindView;
import butterknife.OnClick;
public class ModulesFragment extends BaseFragment implements Topic.Subscriber {
public SwipeRefreshLayout mSwipeRefreshLayout;
public RecyclerView recyclerView;
public TextView emptyRv;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyRv;
public void selectFile() {
@OnClick(R.id.fab)
void selectFile() {
runWithPermission(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/zip");
@@ -53,7 +55,7 @@ public class ModulesFragment extends BaseFragment implements Topic.Subscriber {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_modules, container, false);
ViewBinder.bind(this, view);
unbinder = new ModulesFragment_ViewBinding(this, view);
setHasOptionsMenu(true);
mSwipeRefreshLayout.setOnRefreshListener(() -> {
@@ -98,12 +100,6 @@ public class ModulesFragment extends BaseFragment implements Topic.Subscriber {
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
ViewBinder.unbind(this);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_reboot, menu);

View File

@@ -14,7 +14,6 @@ import android.widget.TextView;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.ReposAdapter;
import com.topjohnwu.magisk.asyncs.UpdateRepos;
import com.topjohnwu.magisk.components.BaseFragment;
@@ -27,12 +26,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindView;
public class ReposFragment extends BaseFragment implements Topic.Subscriber {
public RecyclerView recyclerView;
public TextView emptyRv;
public SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyRv;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
private ReposAdapter adapter;
@@ -46,7 +46,7 @@ public class ReposFragment extends BaseFragment implements Topic.Subscriber {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_repos, container, false);
ViewBinder.bind(this, view);
unbinder = new ReposFragment_ViewBinding(this, view);
mSwipeRefreshLayout.setRefreshing(true);
recyclerView.setVisibility(View.GONE);
@@ -120,6 +120,5 @@ public class ReposFragment extends BaseFragment implements Topic.Subscriber {
public void onDestroyView() {
super.onDestroyView();
mm.repoDB.unregisterAdapter();
ViewBinder.unbind(this);
}
}

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