diff --git a/src/main/java/com/topjohnwu/magisk/SplashActivity.java b/src/main/java/com/topjohnwu/magisk/SplashActivity.java index 114adecdc..2f3249c2e 100644 --- a/src/main/java/com/topjohnwu/magisk/SplashActivity.java +++ b/src/main/java/com/topjohnwu/magisk/SplashActivity.java @@ -20,8 +20,6 @@ import com.topjohnwu.magisk.utils.Const; import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Utils; -import java.util.List; - public class SplashActivity extends Activity { @Override diff --git a/src/main/java/com/topjohnwu/magisk/database/SuDatabaseHelper.java b/src/main/java/com/topjohnwu/magisk/database/SuDatabaseHelper.java index ed040e288..608356d76 100644 --- a/src/main/java/com/topjohnwu/magisk/database/SuDatabaseHelper.java +++ b/src/main/java/com/topjohnwu/magisk/database/SuDatabaseHelper.java @@ -19,7 +19,6 @@ import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Utils; import java.io.File; -import java.io.IOException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Collections; @@ -43,52 +42,71 @@ public class SuDatabaseHelper extends SQLiteOpenHelper { private SQLiteDatabase mDb; private static Context initDB(boolean verify) { - Context context; + Context context, de = null; MagiskManager ce = MagiskManager.get(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - Context de = ce.createDeviceProtectedStorageContext(); - File deDB = Utils.getDatabasePath(de, DB_NAME); - if (deDB.exists()) { - context = de; - } else if (ce.magiskVersionCode > 1410) { - // Migrate DB path - context = de; - de.moveDatabaseFrom(ce, DB_NAME); - } else { + de = ce.createDeviceProtectedStorageContext(); + File ceDB = Utils.getDB(ce, DB_NAME); + if (ceDB.exists()) { context = ce; + } else { + context = de; } } else { context = ce; } - File db = Utils.getDatabasePath(context, DB_NAME); - if (!verify && db.length() == 0) { - ce.loadMagiskInfo(); - return initDB(true); + File db = Utils.getDB(context, DB_NAME); + if (!verify) { + if (db.length() == 0) { + ce.loadMagiskInfo(); + // Continue verification + } else { + return context; + } } - // Only care about local db (no shell involved) - if (!verify) + // Encryption storage + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (ce.magiskVersionCode < 1410) { + if (context == de) { + ce.moveDatabaseFrom(de, DB_NAME); + context = ce; + } + } else { + if (context == ce) { + de.moveDatabaseFrom(ce, DB_NAME); + context = de; + } + } + } + + if (!Shell.rootAccess()) return context; - // We need to make sure the global db is setup properly - if (ce.magiskVersionCode >= 1464 && Shell.rootAccess()) { + // Verify the global db matches the local with the same inode + if (ce.magiskVersionCode >= 1450 && ce.magiskVersionCode < 1460) { + // v14.5 global su db + File OLD_GLOBAL_DB = new File(context.getFilesDir().getParentFile().getParentFile(), "magisk.db"); + verified = TextUtils.equals(Utils.checkInode(OLD_GLOBAL_DB), Utils.checkInode(db)); + if (!verified) { + context.deleteDatabase(DB_NAME); + db.getParentFile().mkdirs(); + Shell.su(Utils.fmt("magisk --clone-attr %s %s; chmod 600 %s; ln %s %s", + context.getFilesDir(), OLD_GLOBAL_DB, OLD_GLOBAL_DB, OLD_GLOBAL_DB, db)); + verified = TextUtils.equals(Utils.checkInode(OLD_GLOBAL_DB), Utils.checkInode(db)); + } + } else if (ce.magiskVersionCode >= 1464) { + // New global su db Shell.su(Utils.fmt("mkdir %s 2>/dev/null; chmod 700 %s", GLOBAL_DB.getParent(), GLOBAL_DB.getParent())); if (!Utils.itemExist(GLOBAL_DB)) { - db = context.getDatabasePath(DB_NAME); + Utils.javaCreateFile(db); Shell.su(Utils.fmt("cp -af %s %s; rm -f %s*", db, GLOBAL_DB, db)); } - - try { - db.getParentFile().mkdirs(); - db.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - - // Make sure the global and local db is the same inode verified = TextUtils.equals(Utils.checkInode(GLOBAL_DB), Utils.checkInode(db)); if (!verified) { + context.deleteDatabase(DB_NAME); + Utils.javaCreateFile(db); Shell.su(Utils.fmt( "chown 0.0 %s; chmod 666 %s; chcon u:object_r:su_file:s0 %s;" + "mount -o bind %s %s", diff --git a/src/main/java/com/topjohnwu/magisk/receivers/ManagerUpdate.java b/src/main/java/com/topjohnwu/magisk/receivers/ManagerUpdate.java index 955ea1a10..2f478592f 100644 --- a/src/main/java/com/topjohnwu/magisk/receivers/ManagerUpdate.java +++ b/src/main/java/com/topjohnwu/magisk/receivers/ManagerUpdate.java @@ -8,7 +8,6 @@ import android.os.Build; import android.support.v4.content.FileProvider; import com.topjohnwu.magisk.utils.Const; -import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Utils; import java.io.File; @@ -21,30 +20,22 @@ public class ManagerUpdate extends BroadcastReceiver { new DownloadReceiver() { @Override public void onDownloadDone(Uri uri) { - if (Shell.rootAccess()) { - Shell.su(Utils.fmt("pm install -r %s", mFile)); - if (!context.getPackageName().equals(Const.ORIG_PKG_NAME)) { - Utils.dumpPrefs(); - Shell.su(Utils.fmt("rm -rf /data/user*/*/%s/*", Const.ORIG_PKG_NAME)); - Intent intent = context.getPackageManager().getLaunchIntentForPackage(Const.ORIG_PKG_NAME); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); - } + if (!context.getPackageName().equals(Const.ORIG_PKG_NAME)) { + Utils.dumpPrefs(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE); + install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Uri content = FileProvider.getUriForFile(context, + context.getPackageName() + ".provider", new File(uri.getPath())); + install.setData(content); + context.startActivity(install); } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE); - install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - Uri content = FileProvider.getUriForFile(context, - context.getPackageName() + ".provider", new File(uri.getPath())); - install.setData(content); - context.startActivity(install); - } else { - Intent install = new Intent(Intent.ACTION_VIEW); - install.setDataAndType(uri, "application/vnd.android.package-archive"); - install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(install); - } + Intent install = new Intent(Intent.ACTION_VIEW); + install.setDataAndType(uri, "application/vnd.android.package-archive"); + install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(install); } } }, diff --git a/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/src/main/java/com/topjohnwu/magisk/utils/Utils.java index 3a8bd0c8d..1525bd68b 100644 --- a/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -54,6 +54,17 @@ public class Utils { Shell.su_raw(fmt("mkdir -p `dirname '%s'` 2>/dev/null; touch '%s' 2>/dev/null", path, path)); } + public static boolean javaCreateFile(File path) { + path.getParentFile().mkdirs(); + try { + path.createNewFile(); + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + public static void removeItem(Object path) { Shell.su_raw(fmt("rm -rf %s 2>/dev/null", path)); } @@ -64,7 +75,7 @@ public class Utils { public static String checkInode(Object path) { List ret = Shell.su(fmt("ls -i %s", path)); - return isValidShellResponse(ret) ? ret.get(0).trim().split("\\s+")[0] : null; + return isValidShellResponse(ret) ? ret.get(0).trim().split("\\s+")[0] : path.toString(); } public static void uninstallPkg(String pkg) { @@ -215,11 +226,11 @@ public class Utils { } } - public static File getDatabasePath(String dbName) { - return getDatabasePath(MagiskManager.get(), dbName); + public static File getDB(String dbName) { + return getDB(MagiskManager.get(), dbName); } - public static File getDatabasePath(Context context, String dbName) { + public static File getDB(Context context, String dbName) { return new File(context.getFilesDir().getParent() + "/databases", dbName); } @@ -263,7 +274,9 @@ public class Utils { public static void dumpPrefs() { Gson gson = new Gson(); - String json = gson.toJson(MagiskManager.get().prefs.getAll(), new TypeToken>(){}.getType()); + Map prefs = MagiskManager.get().prefs.getAll(); + prefs.remove("App Restrictions"); + String json = gson.toJson(prefs, new TypeToken>(){}.getType()); Shell.su(fmt("for usr in /data/user/*; do echo '%s' > ${usr}/%s; done", json, Const.MANAGER_CONFIGS)); }