mirror of
https://github.com/topjohnwu/Magisk
synced 2025-10-31 10:40:52 +01:00
Compare commits
21 Commits
manager-v5
...
manager-v5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15ed3e52f2 | ||
|
|
8990919dab | ||
|
|
e5638e4b15 | ||
|
|
404c6fac9a | ||
|
|
267395bfa2 | ||
|
|
920fc5ae99 | ||
|
|
92ed0ae51b | ||
|
|
6764a98409 | ||
|
|
fd7b5f393a | ||
|
|
2ca528f93f | ||
|
|
ce2e6b7d35 | ||
|
|
684c5d225a | ||
|
|
b75018b03b | ||
|
|
41499d4b3c | ||
|
|
383c97c303 | ||
|
|
74b54ef371 | ||
|
|
bbf7b4db79 | ||
|
|
c61f0acab5 | ||
|
|
398af123b2 | ||
|
|
315fa9d7d3 | ||
|
|
fb5e8ef40c |
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.topjohnwu.magisk"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion rootProject.ext.compileSdkVersion
|
||||
versionCode 112
|
||||
versionName "5.6.4"
|
||||
versionCode 115
|
||||
versionName "5.7.0"
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
argument('butterknife.debuggable', 'false')
|
||||
|
||||
@@ -71,6 +71,11 @@
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.ManagerUpdate" />
|
||||
<receiver android:name=".receivers.RebootReceiver" />
|
||||
<receiver android:name=".receivers.ShortcutReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.LOCALE_CHANGED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:name=".services.OnBootIntentService" />
|
||||
<service
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -22,6 +23,7 @@ import com.topjohnwu.magisk.asyncs.CheckUpdates;
|
||||
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||
import com.topjohnwu.magisk.components.ExpandableView;
|
||||
import com.topjohnwu.magisk.components.Fragment;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
import com.topjohnwu.magisk.utils.ShowUI;
|
||||
import com.topjohnwu.magisk.utils.Topic;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
@@ -91,7 +93,14 @@ public class MagiskFragment extends Fragment
|
||||
new CheckSafetyNet(getActivity()).exec();
|
||||
collapse();
|
||||
};
|
||||
if (!CheckSafetyNet.dexPath.exists()) {
|
||||
if (!TextUtils.equals(mm.getPackageName(), Const.ORIG_PKG_NAME)) {
|
||||
new AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.cannot_check_sn_title)
|
||||
.setMessage(R.string.cannot_check_sn_notice)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
} else if (!CheckSafetyNet.dexPath.exists()) {
|
||||
// Show dialog
|
||||
new AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.proprietary_title)
|
||||
@@ -205,7 +214,7 @@ public class MagiskFragment extends Fragment
|
||||
|
||||
boolean hasNetwork = Utils.checkNetworkStatus();
|
||||
boolean hasRoot = Shell.rootAccess();
|
||||
boolean isUpToDate = mm.magiskVersionCode > 1300;
|
||||
boolean isUpToDate = mm.magiskVersionCode > Const.MAGISK_VER.UNIFIED;
|
||||
|
||||
magiskUpdate.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
|
||||
safetyNetCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE);
|
||||
|
||||
@@ -15,8 +15,8 @@ import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.topjohnwu.magisk.container.Module;
|
||||
import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
|
||||
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
|
||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
||||
import com.topjohnwu.magisk.services.UpdateCheckService;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
import com.topjohnwu.magisk.utils.Topic;
|
||||
@@ -85,7 +85,7 @@ public class MagiskManager extends Shell.ContainerApp {
|
||||
|
||||
// Global resources
|
||||
public SharedPreferences prefs;
|
||||
public SuDatabaseHelper suDB;
|
||||
public MagiskDatabaseHelper mDB;
|
||||
public RepoDatabaseHelper repoDB;
|
||||
public Runnable permissionGrantCallback = null;
|
||||
|
||||
@@ -106,9 +106,9 @@ public class MagiskManager extends Shell.ContainerApp {
|
||||
@Override
|
||||
public void onRootShellInit(@NonNull Shell shell) {
|
||||
try (InputStream utils = getAssets().open(Const.UTIL_FUNCTIONS);
|
||||
InputStream sudb = getResources().openRawResource(R.raw.sudb)) {
|
||||
InputStream magiskDB = getResources().openRawResource(R.raw.magiskdb)) {
|
||||
shell.loadInputStream(null, null, utils);
|
||||
shell.loadInputStream(null, null, sudb);
|
||||
shell.loadInputStream(null, null, magiskDB);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -131,16 +131,15 @@ public class MagiskManager extends Shell.ContainerApp {
|
||||
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
|
||||
}
|
||||
|
||||
suDB = SuDatabaseHelper.getInstance(this);
|
||||
mDB = MagiskDatabaseHelper.getInstance(this);
|
||||
|
||||
String pkg = suDB.getStrings(Const.Key.SU_REQUESTER, Const.ORIG_PKG_NAME);
|
||||
String pkg = mDB.getStrings(Const.Key.SU_REQUESTER, Const.ORIG_PKG_NAME);
|
||||
if (getPackageName().equals(Const.ORIG_PKG_NAME) && !pkg.equals(Const.ORIG_PKG_NAME)) {
|
||||
suDB.setStrings(Const.Key.SU_REQUESTER, null);
|
||||
mDB.setStrings(Const.Key.SU_REQUESTER, null);
|
||||
Utils.uninstallPkg(pkg);
|
||||
suDB = SuDatabaseHelper.getInstance(this);
|
||||
mDB = MagiskDatabaseHelper.getInstance(this);
|
||||
}
|
||||
|
||||
repoDB = new RepoDatabaseHelper(this);
|
||||
defaultLocale = Locale.getDefault();
|
||||
setLocale();
|
||||
loadConfig();
|
||||
@@ -168,9 +167,9 @@ public class MagiskManager extends Shell.ContainerApp {
|
||||
suRequestTimeout = Utils.getPrefsInt(prefs, Const.Key.SU_REQUEST_TIMEOUT, Const.Value.timeoutList[2]);
|
||||
suResponseType = Utils.getPrefsInt(prefs, Const.Key.SU_AUTO_RESPONSE, Const.Value.SU_PROMPT);
|
||||
suNotificationType = Utils.getPrefsInt(prefs, Const.Key.SU_NOTIFICATION, Const.Value.NOTIFICATION_TOAST);
|
||||
suAccessState = suDB.getSettings(Const.Key.ROOT_ACCESS, Const.Value.ROOT_ACCESS_APPS_AND_ADB);
|
||||
multiuserMode = suDB.getSettings(Const.Key.SU_MULTIUSER_MODE, Const.Value.MULTIUSER_MODE_OWNER_ONLY);
|
||||
suNamespaceMode = suDB.getSettings(Const.Key.SU_MNT_NS, Const.Value.NAMESPACE_MODE_REQUESTER);
|
||||
suAccessState = mDB.getSettings(Const.Key.ROOT_ACCESS, Const.Value.ROOT_ACCESS_APPS_AND_ADB);
|
||||
multiuserMode = mDB.getSettings(Const.Key.SU_MULTIUSER_MODE, Const.Value.MULTIUSER_MODE_OWNER_ONLY);
|
||||
suNamespaceMode = mDB.getSettings(Const.Key.SU_MNT_NS, Const.Value.NAMESPACE_MODE_REQUESTER);
|
||||
|
||||
// config
|
||||
isDarkTheme = prefs.getBoolean(Const.Key.DARK_THEME, false);
|
||||
@@ -211,7 +210,7 @@ public class MagiskManager extends Shell.ContainerApp {
|
||||
try {
|
||||
magiskVersionString = Utils.cmd("magisk -v").split(":")[0];
|
||||
magiskVersionCode = Integer.parseInt(Utils.cmd("magisk -V"));
|
||||
String s = Utils.cmd((magiskVersionCode > 1435 ? "resetprop -p " : "getprop ")
|
||||
String s = Utils.cmd((magiskVersionCode >= Const.MAGISK_VER.RESETPROP_PERSIST ? "resetprop -p " : "getprop ")
|
||||
+ Const.MAGISKHIDE_PROP);
|
||||
magiskHide = s == null || Integer.parseInt(s) != 0;
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
@@ -30,8 +29,8 @@ public class MainActivity extends Activity
|
||||
implements NavigationView.OnNavigationItemSelectedListener, Topic.Subscriber {
|
||||
|
||||
private final Handler mDrawerHandler = new Handler();
|
||||
private SharedPreferences prefs;
|
||||
private int mDrawerItem;
|
||||
private boolean fromShortcut = true;
|
||||
|
||||
@BindView(R.id.toolbar) Toolbar toolbar;
|
||||
@BindView(R.id.drawer_layout) DrawerLayout drawer;
|
||||
@@ -48,7 +47,6 @@ public class MainActivity extends Activity
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
|
||||
MagiskManager mm = getMagiskManager();
|
||||
prefs = mm.prefs;
|
||||
|
||||
if (!mm.hasInit) {
|
||||
Intent intent = new Intent(this, SplashActivity.class);
|
||||
@@ -95,7 +93,7 @@ public class MainActivity extends Activity
|
||||
navigationView.setNavigationItemSelectedListener(this);
|
||||
|
||||
if (mm.prefs.getInt(Const.Key.APP_VER, -1) < BuildConfig.VERSION_CODE) {
|
||||
prefs.edit().putInt(Const.Key.APP_VER, BuildConfig.VERSION_CODE).apply();
|
||||
mm.prefs.edit().putInt(Const.Key.APP_VER, BuildConfig.VERSION_CODE).apply();
|
||||
new MarkDownWindow(this, getString(R.string.app_changelog),
|
||||
getResources().openRawResource(R.raw.changelog)).exec();
|
||||
}
|
||||
@@ -111,7 +109,7 @@ public class MainActivity extends Activity
|
||||
public void onBackPressed() {
|
||||
if (drawer.isDrawerOpen(navigationView)) {
|
||||
drawer.closeDrawer(navigationView);
|
||||
} else if (mDrawerItem != R.id.magisk) {
|
||||
} else if (mDrawerItem != R.id.magisk && !fromShortcut) {
|
||||
navigate(R.id.magisk);
|
||||
} else {
|
||||
finish();
|
||||
@@ -140,8 +138,8 @@ public class MainActivity extends Activity
|
||||
MagiskManager mm = getMagiskManager();
|
||||
Menu menu = navigationView.getMenu();
|
||||
menu.findItem(R.id.magiskhide).setVisible(
|
||||
Shell.rootAccess() && mm.magiskVersionCode >= 1300
|
||||
&& prefs.getBoolean(Const.Key.MAGISKHIDE, false));
|
||||
Shell.rootAccess() && mm.magiskVersionCode >= Const.MAGISK_VER.UNIFIED
|
||||
&& mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false));
|
||||
menu.findItem(R.id.modules).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false) &&
|
||||
Shell.rootAccess() && mm.magiskVersionCode >= 0);
|
||||
menu.findItem(R.id.downloads).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false)
|
||||
@@ -155,9 +153,6 @@ public class MainActivity extends Activity
|
||||
int itemId = R.id.magisk;
|
||||
if (item != null) {
|
||||
switch (item) {
|
||||
case "magisk":
|
||||
itemId = R.id.magisk;
|
||||
break;
|
||||
case "superuser":
|
||||
itemId = R.id.superuser;
|
||||
break;
|
||||
@@ -190,6 +185,7 @@ public class MainActivity extends Activity
|
||||
navigationView.setCheckedItem(itemId);
|
||||
switch (itemId) {
|
||||
case R.id.magisk:
|
||||
fromShortcut = false;
|
||||
displayFragment(new MagiskFragment(), true);
|
||||
break;
|
||||
case R.id.superuser:
|
||||
|
||||
@@ -156,7 +156,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
||||
fingerprint.setSummary(R.string.disable_fingerprint);
|
||||
}
|
||||
|
||||
if (mm.magiskVersionCode >= 1440) {
|
||||
if (mm.magiskVersionCode >= Const.MAGISK_VER.MANAGER_HIDE) {
|
||||
if (mm.getPackageName().equals(Const.ORIG_PKG_NAME)) {
|
||||
hideManager.setOnPreferenceClickListener((pref) -> {
|
||||
new HideManager(getActivity()).exec();
|
||||
@@ -194,7 +194,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
||||
if (!Shell.rootAccess()) {
|
||||
prefScreen.removePreference(magiskCategory);
|
||||
generalCatagory.removePreference(hideManager);
|
||||
} else if (mm.magiskVersionCode < 1300) {
|
||||
} else if (mm.magiskVersionCode < Const.MAGISK_VER.UNIFIED) {
|
||||
prefScreen.removePreference(magiskCategory);
|
||||
}
|
||||
}
|
||||
@@ -276,7 +276,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
||||
case Const.Key.ROOT_ACCESS:
|
||||
case Const.Key.SU_MULTIUSER_MODE:
|
||||
case Const.Key.SU_MNT_NS:
|
||||
mm.suDB.setSettings(key, Utils.getPrefsInt(prefs, key));
|
||||
mm.mDB.setSettings(key, Utils.getPrefsInt(prefs, key));
|
||||
break;
|
||||
case Const.Key.LOCALE:
|
||||
mm.setLocale();
|
||||
|
||||
@@ -11,6 +11,8 @@ import com.topjohnwu.magisk.asyncs.LoadModules;
|
||||
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
||||
import com.topjohnwu.magisk.asyncs.UpdateRepos;
|
||||
import com.topjohnwu.magisk.components.Activity;
|
||||
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
|
||||
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
@@ -23,6 +25,7 @@ public class SplashActivity extends Activity {
|
||||
|
||||
MagiskManager mm = getMagiskManager();
|
||||
|
||||
mm.repoDB = new RepoDatabaseHelper(this);
|
||||
mm.loadMagiskInfo();
|
||||
mm.getDefaultInstallFlags();
|
||||
Utils.loadPrefs();
|
||||
@@ -37,6 +40,9 @@ public class SplashActivity extends Activity {
|
||||
getSystemService(NotificationManager.class).createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
// Setup shortcuts
|
||||
sendBroadcast(new Intent(this, ShortcutReceiver.class));
|
||||
|
||||
LoadModules loadModuleTask = new LoadModules();
|
||||
|
||||
if (Utils.checkNetworkStatus()) {
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SuLogFragment extends Fragment {
|
||||
View v = inflater.inflate(R.layout.fragment_su_log, container, false);
|
||||
unbinder = ButterKnife.bind(this, v);
|
||||
mm = getApplication();
|
||||
adapter = new SuLogAdapter(mm.suDB);
|
||||
adapter = new SuLogAdapter(mm.mDB);
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
updateList();
|
||||
@@ -73,7 +73,7 @@ public class SuLogFragment extends Fragment {
|
||||
updateList();
|
||||
return true;
|
||||
case R.id.menu_clear:
|
||||
mm.suDB.clearLogs();
|
||||
mm.mDB.clearLogs();
|
||||
updateList();
|
||||
return true;
|
||||
default:
|
||||
|
||||
@@ -34,13 +34,13 @@ public class SuperuserFragment extends Fragment {
|
||||
PackageManager pm = getActivity().getPackageManager();
|
||||
MagiskManager mm = getApplication();
|
||||
|
||||
List<Policy> policyList = mm.suDB.getPolicyList(pm);
|
||||
List<Policy> policyList = mm.mDB.getPolicyList(pm);
|
||||
|
||||
if (policyList.size() == 0) {
|
||||
emptyRv.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
} else {
|
||||
recyclerView.setAdapter(new PolicyAdapter(policyList, mm.suDB, pm));
|
||||
recyclerView.setAdapter(new PolicyAdapter(policyList, mm.mDB, pm));
|
||||
emptyRv.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.topjohnwu.magisk.adapters;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -16,7 +15,6 @@ import android.widget.TextView;
|
||||
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
import com.topjohnwu.magisk.utils.Topic;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
@@ -16,7 +16,7 @@ import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||
import com.topjohnwu.magisk.components.ExpandableView;
|
||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||
import com.topjohnwu.magisk.container.Policy;
|
||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
||||
import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -28,11 +28,11 @@ import butterknife.ButterKnife;
|
||||
public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder> {
|
||||
|
||||
private List<Policy> policyList;
|
||||
private SuDatabaseHelper dbHelper;
|
||||
private MagiskDatabaseHelper dbHelper;
|
||||
private PackageManager pm;
|
||||
private Set<Policy> expandList = new HashSet<>();
|
||||
|
||||
public PolicyAdapter(List<Policy> list, SuDatabaseHelper db, PackageManager pm) {
|
||||
public PolicyAdapter(List<Policy> list, MagiskDatabaseHelper db, PackageManager pm) {
|
||||
policyList = list;
|
||||
dbHelper = db;
|
||||
this.pm = pm;
|
||||
|
||||
@@ -13,7 +13,7 @@ import android.widget.TextView;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.components.ExpandableView;
|
||||
import com.topjohnwu.magisk.container.SuLogEntry;
|
||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
||||
import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -27,10 +27,10 @@ public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, S
|
||||
|
||||
private List<List<Integer>> logEntryList;
|
||||
private Set<Integer> itemExpanded, sectionExpanded;
|
||||
private SuDatabaseHelper suDB;
|
||||
private MagiskDatabaseHelper suDB;
|
||||
private Cursor suLogCursor = null;
|
||||
|
||||
public SuLogAdapter(SuDatabaseHelper db) {
|
||||
public SuLogAdapter(MagiskDatabaseHelper db) {
|
||||
suDB = db;
|
||||
logEntryList = Collections.emptyList();
|
||||
sectionExpanded = new HashSet<>();
|
||||
|
||||
@@ -43,31 +43,26 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
|
||||
conn.disconnect();
|
||||
}
|
||||
|
||||
private void loadClasses() throws ClassNotFoundException {
|
||||
loader = new DexClassLoader(dexPath.toString(), dexPath.getParent(),
|
||||
private void dyload() throws Exception {
|
||||
loader = new DexClassLoader(dexPath.getPath(), dexPath.getParent(),
|
||||
null, ClassLoader.getSystemClassLoader());
|
||||
helperClazz = loader.loadClass(Const.SNET_PKG + ".SafetyNetHelper");
|
||||
callbackClazz = loader.loadClass(Const.SNET_PKG + ".SafetyNetCallback");
|
||||
int snet_ver = (int) helperClazz.getMethod("getVersion").invoke(null);
|
||||
if (snet_ver != Const.SNET_VER) {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Exception doInBackground(Void... voids) {
|
||||
int snet_ver = -1;
|
||||
|
||||
try {
|
||||
if (!dexPath.exists())
|
||||
dlSnet();
|
||||
loadClasses();
|
||||
|
||||
try {
|
||||
snet_ver = (int) helperClazz.getMethod("getVersion").invoke(null);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (snet_ver != Const.SNET_VER) {
|
||||
dyload();
|
||||
} catch (Exception e) {
|
||||
// If dynamic load failed, try re-downloading and reload
|
||||
dlSnet();
|
||||
loadClasses();
|
||||
dyload();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return e;
|
||||
|
||||
@@ -135,7 +135,7 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
||||
|
||||
repack.delete();
|
||||
|
||||
mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
|
||||
mm.mDB.setStrings(Const.Key.SU_REQUESTER, pkg);
|
||||
Utils.dumpPrefs();
|
||||
Utils.uninstallPkg(Const.ORIG_PKG_NAME);
|
||||
|
||||
|
||||
@@ -76,11 +76,19 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
|
||||
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
|
||||
String arch;
|
||||
if (abis.contains("x86_64")) arch = "x64";
|
||||
else if (abis.contains("arm64-v8a")) arch = "arm64";
|
||||
else if (abis.contains("x86")) arch = "x86";
|
||||
else arch = "arm";
|
||||
console.add("- Device platform: " + arch);
|
||||
|
||||
if (mm.remoteMagiskVersionCode >= Const.MAGISK_VER.SEPOL_REFACTOR) {
|
||||
// 32-bit only
|
||||
if (abis.contains("x86")) arch = "x86";
|
||||
else arch = "arm";
|
||||
} else {
|
||||
if (abis.contains("x86_64")) arch = "x64";
|
||||
else if (abis.contains("arm64-v8a")) arch = "arm64";
|
||||
else if (abis.contains("x86")) arch = "x86";
|
||||
else arch = "arm";
|
||||
}
|
||||
|
||||
console.add("- Device platform: " + Build.SUPPORTED_ABIS[0]);
|
||||
|
||||
try {
|
||||
// Unzip files
|
||||
@@ -182,7 +190,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
|
||||
Shell.Sync.sh("mv -f new-boot.img ../",
|
||||
"mv bin/busybox busybox",
|
||||
"rm -rf bin *.img update-binary",
|
||||
"rm -rf magisk.apk bin *.img update-binary",
|
||||
"cd /");
|
||||
|
||||
SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img");
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.topjohnwu.magisk.asyncs;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import com.topjohnwu.magisk.MagiskManager;
|
||||
import com.topjohnwu.magisk.ReposFragment;
|
||||
import com.topjohnwu.magisk.container.Repo;
|
||||
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.WebService;
|
||||
@@ -16,6 +14,7 @@ import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -24,55 +23,81 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
||||
|
||||
private static final int CHECK_ETAG = 0;
|
||||
private static final int LOAD_NEXT = 1;
|
||||
private static final int LOAD_PREV = 2;
|
||||
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
||||
|
||||
private MagiskManager mm;
|
||||
private List<String> cached, etags, newEtags = new ArrayList<>();
|
||||
private RepoDatabaseHelper repoDB;
|
||||
private SharedPreferences prefs;
|
||||
private boolean forceUpdate;
|
||||
|
||||
private int tasks = 0;
|
||||
private AtomicInteger taskCount = new AtomicInteger(0);
|
||||
final private Object allDone = new Object();
|
||||
|
||||
public UpdateRepos(boolean force) {
|
||||
MagiskManager mm = MagiskManager.get();
|
||||
prefs = mm.prefs;
|
||||
repoDB = mm.repoDB;
|
||||
mm = MagiskManager.get();
|
||||
mm.repoLoadDone.reset();
|
||||
// Legacy data cleanup
|
||||
File old = new File(mm.getApplicationInfo().dataDir + "/shared_prefs", "RepoMap.xml");
|
||||
if (old.exists() || prefs.getString("repomap", null) != null) {
|
||||
if (old.exists() || mm.prefs.getString("repomap", null) != null) {
|
||||
old.delete();
|
||||
prefs.edit().remove("version").remove("repomap").remove(Const.Key.ETAG_KEY).apply();
|
||||
repoDB.clearRepo();
|
||||
mm.prefs.edit().remove("version").remove("repomap").remove(Const.Key.ETAG_KEY).apply();
|
||||
mm.repoDB.clearRepo();
|
||||
}
|
||||
forceUpdate = force;
|
||||
}
|
||||
|
||||
private void queueTask(Runnable task) {
|
||||
// Thread pool's queue has an upper bound, batch it with 64 tasks
|
||||
while (taskCount.get() >= 64) {
|
||||
waitTasks();
|
||||
}
|
||||
taskCount.incrementAndGet();
|
||||
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
|
||||
task.run();
|
||||
if (taskCount.decrementAndGet() == 0) {
|
||||
synchronized (allDone) {
|
||||
allDone.notify();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void waitTasks() {
|
||||
if (taskCount.get() == 0)
|
||||
return;
|
||||
synchronized (allDone) {
|
||||
try {
|
||||
allDone.wait();
|
||||
} catch (InterruptedException e) {
|
||||
// Wait again
|
||||
waitTasks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadJSON(String jsonString) throws Exception {
|
||||
JSONArray jsonArray = new JSONArray(jsonString);
|
||||
|
||||
// Empty page, throw error
|
||||
if (jsonArray.length() == 0) throw new Exception();
|
||||
if (jsonArray.length() == 0)
|
||||
throw new Exception();
|
||||
|
||||
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);
|
||||
++tasks;
|
||||
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
|
||||
Repo repo = repoDB.getRepo(id);
|
||||
JSONObject rawRepo = jsonArray.getJSONObject(i);
|
||||
String id = rawRepo.getString("description");
|
||||
String name = rawRepo.getString("name");
|
||||
Date date = dateFormat.parse(rawRepo.getString("pushed_at"));
|
||||
queueTask(() -> {
|
||||
Repo repo = mm.repoDB.getRepo(id);
|
||||
Boolean updated;
|
||||
try {
|
||||
if (repo == null) {
|
||||
repo = new Repo(name, updatedDate);
|
||||
repo = new Repo(name, date);
|
||||
updated = true;
|
||||
} else {
|
||||
// Popout from cached
|
||||
@@ -81,11 +106,11 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
||||
repo.update();
|
||||
updated = true;
|
||||
} else {
|
||||
updated = repo.update(updatedDate);
|
||||
updated = repo.update(date);
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
repoDB.addRepo(repo);
|
||||
mm.repoDB.addRepo(repo);
|
||||
publishProgress();
|
||||
}
|
||||
if (!id.equals(repo.getId())) {
|
||||
@@ -93,9 +118,8 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
||||
}
|
||||
} catch (Repo.IllegalRepoException e) {
|
||||
Logger.error(e.getMessage());
|
||||
repoDB.removeRepo(id);
|
||||
mm.repoDB.removeRepo(id);
|
||||
}
|
||||
--tasks;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -111,7 +135,8 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
||||
HttpURLConnection conn = WebService.request(url, header);
|
||||
|
||||
try {
|
||||
if (conn == null) throw new Exception();
|
||||
if (conn == null)
|
||||
throw new Exception();
|
||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
|
||||
newEtags.add(etag);
|
||||
return page + 1 < etags.size() && loadPage(page + 1, CHECK_ETAG);
|
||||
@@ -143,17 +168,6 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Void waitTasks() {
|
||||
while (tasks > 0) {
|
||||
try {
|
||||
Thread.sleep(5);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Void... values) {
|
||||
if (ReposFragment.adapter != null)
|
||||
@@ -162,55 +176,52 @@ public class UpdateRepos extends ParallelTask<Void, Void, Void> {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
MagiskManager.get().repoLoadDone.setPending();
|
||||
mm.repoLoadDone.setPending();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
etags = new ArrayList<>(Arrays.asList(prefs.getString(Const.Key.ETAG_KEY, "").split(",")));
|
||||
cached = repoDB.getRepoIDList();
|
||||
etags = new ArrayList<>(Arrays.asList(mm.prefs.getString(Const.Key.ETAG_KEY, "").split(",")));
|
||||
cached = mm.repoDB.getRepoIDList();
|
||||
|
||||
if (!loadPage(0, CHECK_ETAG)) {
|
||||
// Nothing changed online
|
||||
if (forceUpdate) {
|
||||
for (String id : cached) {
|
||||
if (id == null) continue;
|
||||
++tasks;
|
||||
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
|
||||
Repo repo = repoDB.getRepo(id);
|
||||
queueTask(() -> {
|
||||
Repo repo = mm.repoDB.getRepo(id);
|
||||
try {
|
||||
repo.update();
|
||||
repoDB.addRepo(repo);
|
||||
mm.repoDB.addRepo(repo);
|
||||
} catch (Repo.IllegalRepoException e) {
|
||||
Logger.error(e.getMessage());
|
||||
repoDB.removeRepo(repo);
|
||||
mm.repoDB.removeRepo(repo);
|
||||
}
|
||||
--tasks;
|
||||
});
|
||||
}
|
||||
}
|
||||
return waitTasks();
|
||||
waitTasks();
|
||||
} else {
|
||||
waitTasks();
|
||||
|
||||
// The leftover cached means they are removed from online repo
|
||||
mm.repoDB.removeRepo(cached);
|
||||
|
||||
// Update ETag
|
||||
StringBuilder etagBuilder = new StringBuilder();
|
||||
for (int i = 0; i < newEtags.size(); ++i) {
|
||||
if (i != 0) etagBuilder.append(",");
|
||||
etagBuilder.append(newEtags.get(i));
|
||||
}
|
||||
mm.prefs.edit().putString(Const.Key.ETAG_KEY, etagBuilder.toString()).apply();
|
||||
}
|
||||
|
||||
// Wait till all tasks are done
|
||||
waitTasks();
|
||||
|
||||
// The leftover cached means they are removed from online repo
|
||||
repoDB.removeRepo(cached);
|
||||
|
||||
// Update ETag
|
||||
StringBuilder etagBuilder = new StringBuilder();
|
||||
for (int i = 0; i < newEtags.size(); ++i) {
|
||||
if (i != 0) etagBuilder.append(",");
|
||||
etagBuilder.append(newEtags.get(i));
|
||||
}
|
||||
prefs.edit().putString(Const.Key.ETAG_KEY, etagBuilder.toString()).apply();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void v) {
|
||||
MagiskManager.get().repoLoadDone.publish();
|
||||
mm.repoLoadDone.publish();
|
||||
super.onPostExecute(v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class Repo extends BaseModule {
|
||||
if (getVersionCode() < 0) {
|
||||
throw new IllegalRepoException("Repo [" + repoName + "] does not contain versionCode");
|
||||
}
|
||||
if (getMinMagiskVersion() < Const.MIN_MODULE_VER) {
|
||||
if (getMinMagiskVersion() < Const.MIN_MODULE_VER()) {
|
||||
throw new IllegalRepoException("Repo [" + repoName + "] is outdated");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class SuDatabaseHelper {
|
||||
public class MagiskDatabaseHelper {
|
||||
|
||||
private static final int DATABASE_VER = 5;
|
||||
private static final String POLICY_TABLE = "policies";
|
||||
@@ -36,80 +36,76 @@ public class SuDatabaseHelper {
|
||||
private static final String STRINGS_TABLE = "strings";
|
||||
|
||||
private PackageManager pm;
|
||||
private SQLiteDatabase mDb;
|
||||
private File DB_FILE;
|
||||
private SQLiteDatabase db;
|
||||
|
||||
@NonNull
|
||||
public static SuDatabaseHelper getInstance(MagiskManager mm) {
|
||||
public static MagiskDatabaseHelper getInstance(MagiskManager mm) {
|
||||
try {
|
||||
return new SuDatabaseHelper(mm);
|
||||
return new MagiskDatabaseHelper(mm);
|
||||
} catch (Exception e) {
|
||||
// Let's cleanup everything and try again
|
||||
Shell.Sync.su("sudb_clean '*'");
|
||||
return new SuDatabaseHelper(mm);
|
||||
Shell.Sync.su("db_clean '*'");
|
||||
return new MagiskDatabaseHelper(mm);
|
||||
}
|
||||
}
|
||||
|
||||
private SuDatabaseHelper(MagiskManager mm) {
|
||||
private MagiskDatabaseHelper(MagiskManager mm) {
|
||||
pm = mm.getPackageManager();
|
||||
mDb = openDatabase(mm);
|
||||
mDb.disableWriteAheadLogging();
|
||||
int version = mDb.getVersion();
|
||||
db = openDatabase(mm);
|
||||
db.disableWriteAheadLogging();
|
||||
int version = db.getVersion();
|
||||
if (version < DATABASE_VER) {
|
||||
onUpgrade(mDb, version);
|
||||
onUpgrade(db, version);
|
||||
} else if (version > DATABASE_VER) {
|
||||
onDowngrade(mDb);
|
||||
onDowngrade(db);
|
||||
}
|
||||
mDb.setVersion(DATABASE_VER);
|
||||
db.setVersion(DATABASE_VER);
|
||||
clearOutdated();
|
||||
}
|
||||
|
||||
private SQLiteDatabase openDatabase(MagiskManager mm) {
|
||||
final SuFile GLOBAL_DB = new SuFile("/data/adb/magisk.db", true);
|
||||
DB_FILE = new File(Utils.fmt("/sbin/.core/db-%d/magisk.db", Const.USER_ID));
|
||||
final File DB_FILE = new File(Utils.fmt("/sbin/.core/db-%d/magisk.db", Const.USER_ID));
|
||||
Context de = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||
? mm.createDeviceProtectedStorageContext() : mm;
|
||||
if (!DB_FILE.canWrite()) {
|
||||
if (!Shell.rootAccess()) {
|
||||
// We don't want the app to crash, create a db and return
|
||||
DB_FILE = mm.getDatabasePath("su.db");
|
||||
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
|
||||
}
|
||||
mm.loadMagiskInfo();
|
||||
// Cleanup
|
||||
Shell.Sync.su("sudb_clean " + Const.USER_ID);
|
||||
if (mm.magiskVersionCode < 1410) {
|
||||
Shell.Sync.su("db_clean " + Const.USER_ID);
|
||||
if (mm.magiskVersionCode < Const.MAGISK_VER.FBE_AWARE) {
|
||||
// Super old legacy mode
|
||||
DB_FILE = mm.getDatabasePath("su.db");
|
||||
return mm.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
|
||||
} else if (mm.magiskVersionCode < 1450) {
|
||||
} else if (mm.magiskVersionCode < Const.MAGISK_VER.LEGACY_GLOBAL_DB) {
|
||||
// Legacy mode with FBE aware
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
de.moveDatabaseFrom(mm, "su.db");
|
||||
}
|
||||
DB_FILE = de.getDatabasePath("su.db");
|
||||
return de.openOrCreateDatabase("su.db", Context.MODE_PRIVATE, null);
|
||||
} else {
|
||||
// Global database
|
||||
final SuFile GLOBAL_DB = new SuFile("/data/adb/magisk.db", true);
|
||||
mm.deleteDatabase("su.db");
|
||||
de.deleteDatabase("su.db");
|
||||
if (mm.magiskVersionCode < 1460) {
|
||||
if (mm.magiskVersionCode < Const.MAGISK_VER.HIDDEN_PATH) {
|
||||
// Link to new path
|
||||
File oldDB = new File(de.getFilesDir().getParentFile().getParentFile(),
|
||||
"magisk.db");
|
||||
Shell.Sync.su(Utils.fmt("mv -f %s %s; ln -s %s %s",
|
||||
oldDB, GLOBAL_DB, GLOBAL_DB, oldDB));
|
||||
}
|
||||
if (mm.magiskVersionCode < 1550) {
|
||||
if (mm.magiskVersionCode < Const.MAGISK_VER.SEPOL_REFACTOR) {
|
||||
// We need some additional policies on old versions
|
||||
Shell.Sync.su("magiskpolicy --live " +
|
||||
"'create su_file' 'allow * su_file file *' 'allow * su_file dir *'");
|
||||
Shell.Sync.su("db_sepatch");
|
||||
}
|
||||
if (!GLOBAL_DB.exists()) {
|
||||
Shell.Sync.su("sudb_init");
|
||||
Shell.Sync.su("db_init");
|
||||
SQLiteDatabase.openOrCreateDatabase(GLOBAL_DB, null).close();
|
||||
Shell.Sync.su("sudb_restore");
|
||||
Shell.Sync.su("db_restore");
|
||||
}
|
||||
Shell.Sync.su("sudb_setup " + Process.myUid());
|
||||
Shell.Sync.su("db_setup " + Process.myUid());
|
||||
}
|
||||
}
|
||||
// Not using legacy mode, open the mounted global DB
|
||||
@@ -183,9 +179,9 @@ public class SuDatabaseHelper {
|
||||
|
||||
public void clearOutdated() {
|
||||
// Clear outdated policies
|
||||
mDb.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < %d", System.currentTimeMillis() / 1000), null);
|
||||
db.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < %d", System.currentTimeMillis() / 1000), null);
|
||||
// Clear outdated logs
|
||||
mDb.delete(LOG_TABLE, Utils.fmt("time < %d", System.currentTimeMillis() - MagiskManager.get().suLogTimeout * 86400000), null);
|
||||
db.delete(LOG_TABLE, Utils.fmt("time < %d", System.currentTimeMillis() - MagiskManager.get().suLogTimeout * 86400000), null);
|
||||
}
|
||||
|
||||
public void deletePolicy(Policy policy) {
|
||||
@@ -193,16 +189,16 @@ public class SuDatabaseHelper {
|
||||
}
|
||||
|
||||
public void deletePolicy(String pkg) {
|
||||
mDb.delete(POLICY_TABLE, "package_name=?", new String[] { pkg });
|
||||
db.delete(POLICY_TABLE, "package_name=?", new String[] { pkg });
|
||||
}
|
||||
|
||||
public void deletePolicy(int uid) {
|
||||
mDb.delete(POLICY_TABLE, Utils.fmt("uid=%d", uid), null);
|
||||
db.delete(POLICY_TABLE, Utils.fmt("uid=%d", uid), null);
|
||||
}
|
||||
|
||||
public Policy getPolicy(int uid) {
|
||||
Policy policy = null;
|
||||
try (Cursor c = mDb.query(POLICY_TABLE, null, Utils.fmt("uid=%d", uid), null, null, null, null)) {
|
||||
try (Cursor c = db.query(POLICY_TABLE, null, Utils.fmt("uid=%d", uid), null, null, null, null)) {
|
||||
if (c.moveToNext()) {
|
||||
policy = new Policy(c, pm);
|
||||
}
|
||||
@@ -214,15 +210,15 @@ public class SuDatabaseHelper {
|
||||
}
|
||||
|
||||
public void addPolicy(Policy policy) {
|
||||
mDb.replace(POLICY_TABLE, null, policy.getContentValues());
|
||||
db.replace(POLICY_TABLE, null, policy.getContentValues());
|
||||
}
|
||||
|
||||
public void updatePolicy(Policy policy) {
|
||||
mDb.update(POLICY_TABLE, policy.getContentValues(), Utils.fmt("uid=%d", policy.uid), null);
|
||||
db.update(POLICY_TABLE, policy.getContentValues(), Utils.fmt("uid=%d", policy.uid), null);
|
||||
}
|
||||
|
||||
public List<Policy> getPolicyList(PackageManager pm) {
|
||||
try (Cursor c = mDb.query(POLICY_TABLE, null, Utils.fmt("uid/100000=%d", Const.USER_ID),
|
||||
try (Cursor c = db.query(POLICY_TABLE, null, Utils.fmt("uid/100000=%d", Const.USER_ID),
|
||||
null, null, null, null)) {
|
||||
List<Policy> ret = new ArrayList<>(c.getCount());
|
||||
while (c.moveToNext()) {
|
||||
@@ -240,7 +236,7 @@ public class SuDatabaseHelper {
|
||||
}
|
||||
|
||||
public List<List<Integer>> getLogStructure() {
|
||||
try (Cursor c = mDb.query(LOG_TABLE, new String[] { "time" }, Utils.fmt("from_uid/100000=%d", Const.USER_ID),
|
||||
try (Cursor c = db.query(LOG_TABLE, new String[] { "time" }, Utils.fmt("from_uid/100000=%d", Const.USER_ID),
|
||||
null, null, null, "time DESC")) {
|
||||
List<List<Integer>> ret = new ArrayList<>();
|
||||
List<Integer> list = null;
|
||||
@@ -260,28 +256,28 @@ public class SuDatabaseHelper {
|
||||
}
|
||||
|
||||
public Cursor getLogCursor() {
|
||||
return mDb.query(LOG_TABLE, null, Utils.fmt("from_uid/100000=%d", Const.USER_ID),
|
||||
return db.query(LOG_TABLE, null, Utils.fmt("from_uid/100000=%d", Const.USER_ID),
|
||||
null, null, null, "time DESC");
|
||||
}
|
||||
|
||||
public void addLog(SuLogEntry log) {
|
||||
mDb.insert(LOG_TABLE, null, log.getContentValues());
|
||||
db.insert(LOG_TABLE, null, log.getContentValues());
|
||||
}
|
||||
|
||||
public void clearLogs() {
|
||||
mDb.delete(LOG_TABLE, null, null);
|
||||
db.delete(LOG_TABLE, null, null);
|
||||
}
|
||||
|
||||
public void setSettings(String key, int value) {
|
||||
ContentValues data = new ContentValues();
|
||||
data.put("key", key);
|
||||
data.put("value", value);
|
||||
mDb.replace(SETTINGS_TABLE, null, data);
|
||||
db.replace(SETTINGS_TABLE, null, data);
|
||||
}
|
||||
|
||||
public int getSettings(String key, int defaultValue) {
|
||||
int value = defaultValue;
|
||||
try (Cursor c = mDb.query(SETTINGS_TABLE, null, "key=?",new String[] { key }, null, null, null)) {
|
||||
try (Cursor c = db.query(SETTINGS_TABLE, null, "key=?",new String[] { key }, null, null, null)) {
|
||||
if (c.moveToNext()) {
|
||||
value = c.getInt(c.getColumnIndex("value"));
|
||||
}
|
||||
@@ -291,18 +287,18 @@ public class SuDatabaseHelper {
|
||||
|
||||
public void setStrings(String key, String value) {
|
||||
if (value == null) {
|
||||
mDb.delete(STRINGS_TABLE, "key=?", new String[] { key });
|
||||
db.delete(STRINGS_TABLE, "key=?", new String[] { key });
|
||||
} else {
|
||||
ContentValues data = new ContentValues();
|
||||
data.put("key", key);
|
||||
data.put("value", value);
|
||||
mDb.replace(STRINGS_TABLE, null, data);
|
||||
db.replace(STRINGS_TABLE, null, data);
|
||||
}
|
||||
}
|
||||
|
||||
public String getStrings(String key, String defaultValue) {
|
||||
String value = defaultValue;
|
||||
try (Cursor c = mDb.query(STRINGS_TABLE, null, "key=?",new String[] { key }, null, null, null)) {
|
||||
try (Cursor c = db.query(STRINGS_TABLE, null, "key=?",new String[] { key }, null, null, null)) {
|
||||
if (c.moveToNext()) {
|
||||
value = c.getString(c.getColumnIndex("value"));
|
||||
}
|
||||
@@ -26,9 +26,9 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
|
||||
mm = Utils.getMagiskManager(context);
|
||||
mDb = getWritableDatabase();
|
||||
|
||||
// Clear bad repos
|
||||
// Remove outdated repos
|
||||
mDb.delete(TABLE_NAME, "minMagisk<?",
|
||||
new String[] { String.valueOf(Const.MIN_MODULE_VER) });
|
||||
new String[] { String.valueOf(Const.MIN_MODULE_VER()) });
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,11 +20,11 @@ public class PackageReceiver extends BroadcastReceiver {
|
||||
case Intent.ACTION_PACKAGE_REPLACED:
|
||||
// This will only work pre-O
|
||||
if (mm.prefs.getBoolean(Const.Key.SU_REAUTH, false)) {
|
||||
mm.suDB.deletePolicy(pkg);
|
||||
mm.mDB.deletePolicy(pkg);
|
||||
}
|
||||
break;
|
||||
case Intent.ACTION_PACKAGE_FULLY_REMOVED:
|
||||
mm.suDB.deletePolicy(pkg);
|
||||
mm.mDB.deletePolicy(pkg);
|
||||
Shell.Async.su("magiskhide --rm " + pkg);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.topjohnwu.magisk.receivers;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.topjohnwu.magisk.MagiskManager;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.SplashActivity;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ShortcutReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
MagiskManager mm = Utils.getMagiskManager(context);
|
||||
ShortcutManager manager = context.getSystemService(ShortcutManager.class);
|
||||
if (TextUtils.equals(intent.getAction(), Intent.ACTION_LOCALE_CHANGED)) {
|
||||
// It is triggered with locale change, manual load Magisk info
|
||||
mm.loadMagiskInfo();
|
||||
}
|
||||
manager.setDynamicShortcuts(getShortCuts(mm));
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
|
||||
private ArrayList<ShortcutInfo> getShortCuts(MagiskManager mm) {
|
||||
ArrayList<ShortcutInfo> shortCuts = new ArrayList<>();
|
||||
if (Shell.rootAccess() &&
|
||||
!(Const.USER_ID > 0 &&
|
||||
mm.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
|
||||
shortCuts.add(new ShortcutInfo.Builder(mm, "superuser")
|
||||
.setShortLabel(mm.getString(R.string.superuser))
|
||||
.setIntent(new Intent(mm, SplashActivity.class)
|
||||
.putExtra(Const.Key.OPEN_SECTION, "superuser")
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
|
||||
.setIcon(Icon.createWithResource(mm, R.drawable.sc_superuser))
|
||||
.setRank(0)
|
||||
.build());
|
||||
}
|
||||
if (Shell.rootAccess() && mm.magiskVersionCode >= Const.MAGISK_VER.UNIFIED
|
||||
&& mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false)) {
|
||||
shortCuts.add(new ShortcutInfo.Builder(mm, "magiskhide")
|
||||
.setShortLabel(mm.getString(R.string.magiskhide))
|
||||
.setIntent(new Intent(mm, SplashActivity.class)
|
||||
.putExtra(Const.Key.OPEN_SECTION, "magiskhide")
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
|
||||
.setIcon(Icon.createWithResource(mm, R.drawable.sc_magiskhide))
|
||||
.setRank(1)
|
||||
.build());
|
||||
}
|
||||
if (!mm.prefs.getBoolean(Const.Key.COREONLY, false) &&
|
||||
Shell.rootAccess() && mm.magiskVersionCode >= 0) {
|
||||
shortCuts.add(new ShortcutInfo.Builder(mm, "modules")
|
||||
.setShortLabel(mm.getString(R.string.modules))
|
||||
.setIntent(new Intent(mm, SplashActivity.class)
|
||||
.putExtra(Const.Key.OPEN_SECTION, "modules")
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
|
||||
.setIcon(Icon.createWithResource(mm, R.drawable.sc_extension))
|
||||
.setRank(3)
|
||||
.build());
|
||||
shortCuts.add(new ShortcutInfo.Builder(mm, "downloads")
|
||||
.setShortLabel(mm.getString(R.string.download))
|
||||
.setIntent(new Intent(mm, SplashActivity.class)
|
||||
.putExtra(Const.Key.OPEN_SECTION, "downloads")
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
|
||||
.setIcon(Icon.createWithResource(mm, R.drawable.sc_cloud_download))
|
||||
.setRank(2)
|
||||
.build());
|
||||
}
|
||||
return shortCuts;
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public class RequestActivity extends Activity {
|
||||
|
||||
pm = getPackageManager();
|
||||
mm = Utils.getMagiskManager(this);
|
||||
mm.suDB.clearOutdated();
|
||||
mm.mDB.clearOutdated();
|
||||
|
||||
Intent intent = getIntent();
|
||||
socketPath = intent.getStringExtra("socket");
|
||||
@@ -233,7 +233,7 @@ public class RequestActivity extends Activity {
|
||||
policy.policy = action;
|
||||
if (time >= 0) {
|
||||
policy.until = (time == 0) ? 0 : (System.currentTimeMillis() / 1000 + time * 60);
|
||||
mm.suDB.addPolicy(policy);
|
||||
mm.mDB.addPolicy(policy);
|
||||
}
|
||||
handleAction();
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class RequestActivity extends Activity {
|
||||
}
|
||||
|
||||
int uid = payload.getAsInteger("uid");
|
||||
policy = mm.suDB.getPolicy(uid);
|
||||
policy = mm.mDB.getPolicy(uid);
|
||||
if (policy == null) {
|
||||
policy = new Policy(uid, pm);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class SuReceiver extends BroadcastReceiver {
|
||||
action = intent.getStringExtra("action");
|
||||
if (action == null) return;
|
||||
|
||||
policy = mm.suDB.getPolicy(fromUid);
|
||||
policy = mm.mDB.getPolicy(fromUid);
|
||||
if (policy == null) {
|
||||
try {
|
||||
policy = new Policy(fromUid, context.getPackageManager());
|
||||
@@ -84,7 +84,7 @@ public class SuReceiver extends BroadcastReceiver {
|
||||
log.fromPid = pid;
|
||||
log.command = command;
|
||||
log.date = new Date();
|
||||
mm.suDB.addLog(log);
|
||||
mm.mDB.addLog(log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.topjohnwu.magisk.utils;
|
||||
import android.os.Environment;
|
||||
import android.os.Process;
|
||||
|
||||
import com.topjohnwu.magisk.BuildConfig;
|
||||
import com.topjohnwu.magisk.MagiskManager;
|
||||
import com.topjohnwu.superuser.io.SuFile;
|
||||
|
||||
@@ -13,7 +14,7 @@ import java.util.List;
|
||||
public class Const {
|
||||
|
||||
public static final String DEBUG_TAG = "MagiskManager";
|
||||
public static final String ORIG_PKG_NAME = "com.topjohnwu.magisk";
|
||||
public static final String ORIG_PKG_NAME = BuildConfig.APPLICATION_ID;
|
||||
public static final String SNET_PKG = "com.topjohnwu.snet";
|
||||
public static final String MAGISKHIDE_PROP = "persist.magisk.hide";
|
||||
|
||||
@@ -36,7 +37,10 @@ public class Const {
|
||||
// Versions
|
||||
public static final int UPDATE_SERVICE_VER = 1;
|
||||
public static final int SNET_VER = 7;
|
||||
public static final int MIN_MODULE_VER = 1400;
|
||||
|
||||
public static int MIN_MODULE_VER() {
|
||||
return MagiskManager.get().magiskVersionCode >= 1630 ? 1500 : 1400;
|
||||
}
|
||||
|
||||
public synchronized static SuFile MAGISK_PATH() {
|
||||
SuFile file;
|
||||
@@ -66,6 +70,17 @@ 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 DTBO_SUPPORT = 1446;
|
||||
public static final int LEGACY_GLOBAL_DB = 1450;
|
||||
public static final int HIDDEN_PATH = 1460;
|
||||
public static final int SEPOL_REFACTOR = 1640;
|
||||
}
|
||||
|
||||
public static class ID {
|
||||
public static final int UPDATE_SERVICE_ID = 1;
|
||||
public static final int FETCH_ZIP = 2;
|
||||
|
||||
@@ -268,7 +268,7 @@ public class ShowUI {
|
||||
Shell.Sync.su(
|
||||
Utils.fmt("echo '%s' > /cache/%s", uninstaller.toString().replace("'", "'\\''"), Const.UNINSTALLER),
|
||||
Utils.fmt("echo '%s' > %s/%s", utils.toString().replace("'", "'\\''"),
|
||||
mm.magiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk", Const.UTIL_FUNCTIONS)
|
||||
mm.magiskVersionCode >= Const.MAGISK_VER.HIDDEN_PATH ? "/data/adb/magisk" : "/data/magisk", Const.UTIL_FUNCTIONS)
|
||||
);
|
||||
try {
|
||||
uninstaller.close();
|
||||
|
||||
@@ -52,7 +52,7 @@ public class Utils {
|
||||
}
|
||||
|
||||
public static void uninstallPkg(String pkg) {
|
||||
Shell.Sync.su("sudb_clean " + Const.USER_ID, "pm uninstall " + pkg);
|
||||
Shell.Sync.su("db_clean " + Const.USER_ID, "pm uninstall " + pkg);
|
||||
}
|
||||
|
||||
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
|
||||
@@ -202,7 +202,7 @@ public class Utils {
|
||||
|
||||
public static void patchDTBO() {
|
||||
MagiskManager mm = MagiskManager.get();
|
||||
if (mm.magiskVersionCode >= 1446 && !mm.keepVerity) {
|
||||
if (mm.magiskVersionCode >= Const.MAGISK_VER.DTBO_SUPPORT && !mm.keepVerity) {
|
||||
if (ShellUtils.fastCmdResult(Shell.getShell(), "patch_dtbo_image")) {
|
||||
ShowUI.dtboPatchedNotification();
|
||||
}
|
||||
|
||||
9
src/main/res/drawable-v26/sc_cloud_download.xml
Normal file
9
src/main/res/drawable-v26/sc_cloud_download.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/su_request_background" />
|
||||
<foreground>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_cloud_download"
|
||||
android:inset="30%" />
|
||||
</foreground>
|
||||
</adaptive-icon>
|
||||
9
src/main/res/drawable-v26/sc_extension.xml
Normal file
9
src/main/res/drawable-v26/sc_extension.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/su_request_background" />
|
||||
<foreground>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_extension"
|
||||
android:inset="30%" />
|
||||
</foreground>
|
||||
</adaptive-icon>
|
||||
9
src/main/res/drawable-v26/sc_magiskhide.xml
Normal file
9
src/main/res/drawable-v26/sc_magiskhide.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/su_request_background" />
|
||||
<foreground>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_magiskhide"
|
||||
android:inset="30%" />
|
||||
</foreground>
|
||||
</adaptive-icon>
|
||||
9
src/main/res/drawable-v26/sc_superuser.xml
Normal file
9
src/main/res/drawable-v26/sc_superuser.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/su_request_background" />
|
||||
<foreground>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_superuser"
|
||||
android:inset="30%" />
|
||||
</foreground>
|
||||
</adaptive-icon>
|
||||
File diff suppressed because one or more lines are too long
@@ -4,6 +4,6 @@
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:fillColor="@color/primary_dark"
|
||||
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM17,13l-5,5 -5,-5h3V9h4v4h3z"/>
|
||||
</vector>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user