Magisk/src/main/java/com/topjohnwu/magisk/MagiskManager.java

253 lines
9.9 KiB
Java
Raw Normal View History

2017-02-07 02:01:32 +08:00
package com.topjohnwu.magisk;
2018-02-20 00:39:17 +08:00
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Intent;
2017-02-07 02:01:32 +08:00
import android.content.SharedPreferences;
2017-10-21 22:54:47 +08:00
import android.content.pm.PackageManager;
2017-07-22 22:14:02 +08:00
import android.content.res.Configuration;
import android.content.res.Resources;
2017-02-07 06:02:06 +08:00
import android.os.Handler;
2017-02-07 02:01:32 +08:00
import android.preference.PreferenceManager;
2018-01-25 18:43:30 +08:00
import android.support.annotation.NonNull;
2018-02-12 23:07:35 +08:00
import android.text.TextUtils;
2017-02-07 06:02:06 +08:00
import android.widget.Toast;
2017-02-07 02:01:32 +08:00
2017-10-07 17:12:36 +08:00
import com.topjohnwu.magisk.container.Module;
2017-07-21 00:46:13 +08:00
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
2017-06-01 00:19:52 +08:00
import com.topjohnwu.magisk.database.SuDatabaseHelper;
2018-02-20 00:39:17 +08:00
import com.topjohnwu.magisk.services.UpdateCheckService;
2017-11-06 04:41:23 +08:00
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Topic;
2017-02-07 02:01:32 +08:00
import com.topjohnwu.magisk.utils.Utils;
2018-02-12 23:07:35 +08:00
import com.topjohnwu.superuser.BusyBox;
2018-01-21 06:07:24 +08:00
import com.topjohnwu.superuser.Shell;
2017-02-07 02:01:32 +08:00
2018-02-12 23:07:35 +08:00
import java.io.File;
2018-01-21 06:07:24 +08:00
import java.io.IOException;
import java.io.InputStream;
2017-10-16 00:54:48 +08:00
import java.lang.ref.WeakReference;
2017-02-07 02:01:32 +08:00
import java.util.List;
2017-07-22 22:14:02 +08:00
import java.util.Locale;
import java.util.Map;
2017-02-07 02:01:32 +08:00
2018-01-25 18:43:30 +08:00
public class MagiskManager extends Shell.ContainerApp {
2017-02-07 02:01:32 +08:00
2017-10-16 00:54:48 +08:00
// Global weak reference to self
private static WeakReference<MagiskManager> weakSelf;
// Topics
public final Topic magiskHideDone = new Topic();
public final Topic reloadActivity = new Topic();
public final Topic moduleLoadDone = new Topic();
public final Topic repoLoadDone = new Topic();
public final Topic updateCheckDone = new Topic();
public final Topic safetyNetDone = new Topic();
public final Topic localeDone = new Topic();
2017-02-07 02:01:32 +08:00
// Info
2017-11-06 04:47:24 +08:00
public boolean hasInit = false;
public String magiskVersionString;
2017-05-12 02:25:07 +08:00
public int magiskVersionCode = -1;
public String remoteMagiskVersionString;
public int remoteMagiskVersionCode = -1;
2017-02-07 02:01:32 +08:00
public String magiskLink;
public String releaseNoteLink;
2017-06-07 02:19:23 +08:00
public String remoteManagerVersionString;
public int remoteManagerVersionCode = -1;
public String managerLink;
2017-02-07 02:01:32 +08:00
public String bootBlock = null;
public boolean keepVerity = false;
public boolean keepEnc = false;
2017-02-07 02:01:32 +08:00
// Data
public Map<String, Module> moduleMap;
2017-07-22 22:14:02 +08:00
public List<Locale> locales;
2017-02-07 02:01:32 +08:00
// Configurations
2017-07-22 22:14:02 +08:00
public static Locale locale;
public static Locale defaultLocale;
2017-02-07 02:01:32 +08:00
2017-02-07 07:32:40 +08:00
public boolean magiskHide;
2017-02-07 02:01:32 +08:00
public boolean isDarkTheme;
public int suRequestTimeout;
public int suLogTimeout = 14;
public int suAccessState;
2017-05-27 02:41:24 +08:00
public int multiuserMode;
2017-02-07 02:01:32 +08:00
public int suResponseType;
public int suNotificationType;
2017-06-08 22:27:24 +08:00
public int suNamespaceMode;
2017-08-27 01:38:05 +08:00
public String localeConfig;
2017-08-29 01:34:42 +08:00
public int updateChannel;
2017-09-03 17:24:05 +08:00
public String bootFormat;
2017-12-27 01:07:33 +08:00
public int repoOrder;
2017-02-07 02:01:32 +08:00
2017-06-01 00:19:52 +08:00
// Global resources
2017-02-07 02:01:32 +08:00
public SharedPreferences prefs;
2017-06-01 00:19:52 +08:00
public SuDatabaseHelper suDB;
2017-07-21 00:46:13 +08:00
public RepoDatabaseHelper repoDB;
2017-11-06 05:36:20 +08:00
public Runnable permissionGrantCallback = null;
2017-02-07 02:01:32 +08:00
2017-02-07 06:02:06 +08:00
private static Handler mHandler = new Handler();
2017-10-16 11:51:34 +08:00
public MagiskManager() {
weakSelf = new WeakReference<>(this);
2018-02-12 23:07:35 +08:00
}
@Override
public void onCreate() {
super.onCreate();
2018-01-21 06:07:24 +08:00
Shell.setFlags(Shell.FLAG_MOUNT_MASTER);
2018-02-13 03:27:27 +08:00
Shell.verboseLogging(BuildConfig.DEBUG);
2018-02-12 23:07:35 +08:00
BusyBox.BB_PATH = new File(Const.BUSYBOX_PATH);
2018-01-25 18:43:30 +08:00
Shell.setInitializer(new Shell.Initializer() {
2018-01-21 06:07:24 +08:00
@Override
2018-01-25 18:43:30 +08:00
public void onRootShellInit(@NonNull Shell shell) {
2018-02-18 12:41:58 +08:00
try (InputStream utils = MagiskManager.get().getAssets().open(Const.UTIL_FUNCTIONS);
InputStream sudb = getResources().openRawResource(R.raw.sudb)) {
shell.loadInputStream(null, null, utils);
shell.loadInputStream(null, null, sudb);
2018-01-21 06:07:24 +08:00
} catch (IOException e) {
e.printStackTrace();
}
2018-01-25 18:43:30 +08:00
shell.run(null, null,
2018-01-21 06:07:24 +08:00
"mount_partitions",
"run_migrations");
}
});
2017-10-16 11:51:34 +08:00
2017-08-12 01:31:34 +08:00
prefs = PreferenceManager.getDefaultSharedPreferences(this);
2017-09-15 18:03:25 +08:00
// Handle duplicate package
2017-11-06 04:41:23 +08:00
if (!getPackageName().equals(Const.ORIG_PKG_NAME)) {
2017-10-21 22:54:47 +08:00
try {
2017-11-06 04:41:23 +08:00
getPackageManager().getApplicationInfo(Const.ORIG_PKG_NAME, 0);
Intent intent = getPackageManager().getLaunchIntentForPackage(Const.ORIG_PKG_NAME);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
2017-10-21 22:54:47 +08:00
return;
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
2017-12-12 02:35:00 +08:00
}
suDB = SuDatabaseHelper.getInstance(this);
2018-02-13 03:27:27 +08:00
String pkg = suDB.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);
Utils.uninstallPkg(pkg);
suDB = SuDatabaseHelper.getInstance(this);
}
2017-08-12 01:31:34 +08:00
repoDB = new RepoDatabaseHelper(this);
2017-09-03 21:12:09 +08:00
defaultLocale = Locale.getDefault();
setLocale();
2017-08-12 01:31:34 +08:00
loadConfig();
}
2017-10-16 00:54:48 +08:00
public static MagiskManager get() {
return weakSelf.get();
}
2017-07-22 22:14:02 +08:00
public void setLocale() {
2017-11-06 04:41:23 +08:00
localeConfig = prefs.getString(Const.Key.LOCALE, "");
2017-08-27 01:38:05 +08:00
if (localeConfig.isEmpty()) {
2017-07-22 22:14:02 +08:00
locale = defaultLocale;
} else {
2017-08-27 01:38:05 +08:00
locale = Locale.forLanguageTag(localeConfig);
2017-07-22 22:14:02 +08:00
}
Resources res = getBaseContext().getResources();
Configuration config = new Configuration(res.getConfiguration());
config.setLocale(locale);
res.updateConfiguration(config, res.getDisplayMetrics());
}
2017-09-03 15:35:14 +08:00
public void loadConfig() {
2017-08-12 01:31:34 +08:00
// su
2017-11-06 04:41:23 +08:00
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);
2017-12-03 04:15:17 +08:00
// config
isDarkTheme = prefs.getBoolean(Const.Key.DARK_THEME, false);
2017-11-06 04:41:23 +08:00
updateChannel = Utils.getPrefsInt(prefs, Const.Key.UPDATE_CHANNEL, Const.Value.STABLE_CHANNEL);
bootFormat = prefs.getString(Const.Key.BOOT_FORMAT, ".img");
2017-12-27 01:07:33 +08:00
repoOrder = prefs.getInt(Const.Key.REPO_ORDER, Const.Value.ORDER_NAME);
}
public void writeConfig() {
prefs.edit()
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
2018-02-12 23:07:35 +08:00
.putBoolean(Const.Key.HOSTS, Const.MAGISK_HOST_FILE().exists())
.putBoolean(Const.Key.COREONLY, Const.MAGISK_DISABLE_FILE.exists())
2017-12-27 01:07:33 +08:00
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
.putString(Const.Key.ROOT_ACCESS, String.valueOf(suAccessState))
.putString(Const.Key.SU_MULTIUSER_MODE, String.valueOf(multiuserMode))
.putString(Const.Key.SU_MNT_NS, String.valueOf(suNamespaceMode))
.putString(Const.Key.UPDATE_CHANNEL, String.valueOf(updateChannel))
.putString(Const.Key.LOCALE, localeConfig)
.putString(Const.Key.BOOT_FORMAT, bootFormat)
.putInt(Const.Key.UPDATE_SERVICE_VER, Const.UPDATE_SERVICE_VER)
.putInt(Const.Key.REPO_ORDER, repoOrder)
.apply();
2017-02-07 02:01:32 +08:00
}
2018-01-12 01:53:49 +08:00
public static void toast(CharSequence msg, int duration) {
2017-10-16 00:54:48 +08:00
mHandler.post(() -> Toast.makeText(weakSelf.get(), msg, duration).show());
2017-02-07 06:02:06 +08:00
}
2017-10-16 00:54:48 +08:00
public static void toast(int resId, int duration) {
mHandler.post(() -> Toast.makeText(weakSelf.get(), resId, duration).show());
2017-02-07 06:02:06 +08:00
}
2017-11-06 04:47:24 +08:00
public void loadMagiskInfo() {
try {
2018-02-12 23:07:35 +08:00
magiskVersionString = Utils.cmd("magisk -v").split(":")[0];
magiskVersionCode = Integer.parseInt(Utils.cmd("magisk -V"));
2018-02-18 12:41:58 +08:00
String s = Utils.cmd((magiskVersionCode > 1435 ? "resetprop -p " : "getprop ")
+ Const.MAGISKHIDE_PROP);
2018-02-12 23:07:35 +08:00
magiskHide = s == null || Integer.parseInt(s) != 0;
} catch (Exception ignored) {}
2017-12-07 04:20:15 +08:00
2018-02-12 23:07:35 +08:00
bootBlock = Utils.cmd("echo \"$BOOTIMAGE\"");
}
public void getDefaultInstallFlags() {
2018-02-12 23:07:35 +08:00
keepVerity = Boolean.parseBoolean(Utils.cmd("getvar KEEPVERITY; echo $KEEPVERITY")) ||
Utils.cmd("echo \"$DTBOIMAGE\"") != null;
2018-02-12 23:07:35 +08:00
keepEnc = Boolean.parseBoolean(Utils.cmd("getvar KEEPFORCEENCRYPT; echo $KEEPFORCEENCRYPT")) ||
TextUtils.equals("encrypted", Utils.cmd("getprop ro.crypto.state"));
2017-07-18 03:34:06 +08:00
}
2017-11-06 05:36:20 +08:00
public void setPermissionGrantCallback(Runnable callback) {
permissionGrantCallback = callback;
}
2018-02-20 00:39:17 +08:00
public void setupUpdateCheck() {
JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
if (prefs.getBoolean(Const.Key.CHECK_UPDATES, true)) {
if (scheduler.getAllPendingJobs().isEmpty() ||
Const.UPDATE_SERVICE_VER > prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
ComponentName service = new ComponentName(this, UpdateCheckService.class);
JobInfo info = new JobInfo.Builder(Const.ID.UPDATE_SERVICE_ID, service)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.setPeriodic(8 * 60 * 60 * 1000)
.build();
scheduler.schedule(info);
}
} else {
scheduler.cancel(Const.UPDATE_SERVICE_VER);
}
}
2017-02-07 02:01:32 +08:00
}