mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Change new magisk database
This commit is contained in:
parent
aa75c8e5e4
commit
fd6cbb138c
@ -10,6 +10,7 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.adapters.TabFragmentAdapter;
|
import com.topjohnwu.magisk.adapters.TabFragmentAdapter;
|
||||||
import com.topjohnwu.magisk.components.Fragment;
|
import com.topjohnwu.magisk.components.Fragment;
|
||||||
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
@ -33,7 +34,9 @@ public class LogFragment extends Fragment {
|
|||||||
|
|
||||||
TabFragmentAdapter adapter = new TabFragmentAdapter(getChildFragmentManager());
|
TabFragmentAdapter adapter = new TabFragmentAdapter(getChildFragmentManager());
|
||||||
|
|
||||||
adapter.addTab(new SuLogFragment(), getString(R.string.superuser));
|
if (!(Const.USER_ID > 0 && getApplication().multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
|
||||||
|
adapter.addTab(new SuLogFragment(), getString(R.string.superuser));
|
||||||
|
}
|
||||||
adapter.addTab(new MagiskLogFragment(), getString(R.string.magisk));
|
adapter.addTab(new MagiskLogFragment(), getString(R.string.magisk));
|
||||||
tab.setupWithViewPager(viewPager);
|
tab.setupWithViewPager(viewPager);
|
||||||
tab.setVisibility(View.VISIBLE);
|
tab.setVisibility(View.VISIBLE);
|
||||||
|
@ -39,7 +39,6 @@ public class MagiskManager extends Application {
|
|||||||
|
|
||||||
// Info
|
// Info
|
||||||
public boolean hasInit = false;
|
public boolean hasInit = false;
|
||||||
public int userId;
|
|
||||||
public String magiskVersionString;
|
public String magiskVersionString;
|
||||||
public int magiskVersionCode = -1;
|
public int magiskVersionCode = -1;
|
||||||
public String remoteMagiskVersionString;
|
public String remoteMagiskVersionString;
|
||||||
@ -95,14 +94,6 @@ public class MagiskManager extends Application {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
userId = getApplicationInfo().uid / 100000;
|
|
||||||
|
|
||||||
if (Utils.getDatabasePath(this, SuDatabaseHelper.DB_NAME).exists()) {
|
|
||||||
// Don't migrate yet, wait and check Magisk version
|
|
||||||
suDB = new SuDatabaseHelper(this);
|
|
||||||
} else {
|
|
||||||
suDB = new SuDatabaseHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle duplicate package
|
// Handle duplicate package
|
||||||
if (!getPackageName().equals(Const.ORIG_PKG_NAME)) {
|
if (!getPackageName().equals(Const.ORIG_PKG_NAME)) {
|
||||||
@ -113,11 +104,15 @@ public class MagiskManager extends Application {
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
return;
|
return;
|
||||||
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
|
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
suDB = new SuDatabaseHelper(true);
|
||||||
|
|
||||||
|
if (getPackageName().equals(Const.ORIG_PKG_NAME)) {
|
||||||
String pkg = suDB.getStrings(Const.Key.SU_REQUESTER, null);
|
String pkg = suDB.getStrings(Const.Key.SU_REQUESTER, null);
|
||||||
if (pkg != null) {
|
if (pkg != null) {
|
||||||
suDB.setStrings(Const.Key.SU_REQUESTER, null);
|
suDB.setStrings(Const.Key.SU_REQUESTER, null);
|
||||||
Shell.su_raw("pm uninstall " + pkg);
|
Utils.uninstallPkg(pkg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,6 +211,11 @@ public class MagiskManager extends Application {
|
|||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
keepEnc = false;
|
keepEnc = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (suDB != null) {
|
||||||
|
suDB.close();
|
||||||
|
suDB = new SuDatabaseHelper();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPermissionGrantCallback(Runnable callback) {
|
public void setPermissionGrantCallback(Runnable callback) {
|
||||||
|
@ -149,13 +149,13 @@ public class MainActivity extends Activity
|
|||||||
menu.findItem(R.id.magiskhide).setVisible(
|
menu.findItem(R.id.magiskhide).setVisible(
|
||||||
Shell.rootAccess() && mm.magiskVersionCode >= 1300
|
Shell.rootAccess() && mm.magiskVersionCode >= 1300
|
||||||
&& prefs.getBoolean(Const.Key.MAGISKHIDE, false));
|
&& prefs.getBoolean(Const.Key.MAGISKHIDE, false));
|
||||||
menu.findItem(R.id.modules).setVisible(
|
menu.findItem(R.id.modules).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false) &&
|
||||||
Shell.rootAccess() && mm.magiskVersionCode >= 0);
|
Shell.rootAccess() && mm.magiskVersionCode >= 0);
|
||||||
menu.findItem(R.id.downloads).setVisible(Utils.checkNetworkStatus() &&
|
menu.findItem(R.id.downloads).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false)
|
||||||
Shell.rootAccess() && mm.magiskVersionCode >= 0);
|
&& Utils.checkNetworkStatus() && Shell.rootAccess() && mm.magiskVersionCode >= 0);
|
||||||
menu.setGroupVisible(R.id.second_group, !mm.prefs.getBoolean(Const.Key.COREONLY, false));
|
|
||||||
menu.findItem(R.id.log).setVisible(Shell.rootAccess());
|
menu.findItem(R.id.log).setVisible(Shell.rootAccess());
|
||||||
menu.findItem(R.id.superuser).setVisible(Shell.rootAccess());
|
menu.findItem(R.id.superuser).setVisible(Shell.rootAccess() &&
|
||||||
|
!(Const.USER_ID > 0 && mm.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void navigate(String item) {
|
public void navigate(String item) {
|
||||||
|
@ -133,12 +133,12 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
|
|
||||||
setSummary();
|
setSummary();
|
||||||
|
|
||||||
// Disable dangerous settings in user mode if selected owner manage
|
// Disable dangerous settings in secondary user
|
||||||
if (mm.userId > 0) {
|
if (Const.USER_ID > 0) {
|
||||||
suCategory.removePreference(multiuserMode);
|
suCategory.removePreference(multiuserMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove re-authentication option on Android O, it will not work
|
// Disable re-authentication option on Android O, it will not work
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
reauth.setEnabled(false);
|
reauth.setEnabled(false);
|
||||||
reauth.setSummary(R.string.android_o_not_support);
|
reauth.setSummary(R.string.android_o_not_support);
|
||||||
@ -155,9 +155,13 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
generalCatagory.removePreference(hideManager);
|
generalCatagory.removePreference(hideManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Shell.rootAccess() || (Const.USER_ID > 0 &&
|
||||||
|
mm.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
|
||||||
|
prefScreen.removePreference(suCategory);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Shell.rootAccess()) {
|
if (!Shell.rootAccess()) {
|
||||||
prefScreen.removePreference(magiskCategory);
|
prefScreen.removePreference(magiskCategory);
|
||||||
prefScreen.removePreference(suCategory);
|
|
||||||
generalCatagory.removePreference(hideManager);
|
generalCatagory.removePreference(hideManager);
|
||||||
} else if (mm.magiskVersionCode < 1300) {
|
} else if (mm.magiskVersionCode < 1300) {
|
||||||
prefScreen.removePreference(magiskCategory);
|
prefScreen.removePreference(magiskCategory);
|
||||||
|
@ -15,7 +15,6 @@ import com.topjohnwu.magisk.asyncs.LoadModules;
|
|||||||
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
||||||
import com.topjohnwu.magisk.asyncs.UpdateRepos;
|
import com.topjohnwu.magisk.asyncs.UpdateRepos;
|
||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
|
||||||
import com.topjohnwu.magisk.services.UpdateCheckService;
|
import com.topjohnwu.magisk.services.UpdateCheckService;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
import com.topjohnwu.magisk.utils.Shell;
|
||||||
@ -68,9 +67,6 @@ public class SplashActivity extends Activity {
|
|||||||
mm.bootBlock = ret.get(0);
|
mm.bootBlock = ret.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup suDB
|
|
||||||
SuDatabaseHelper.setupSuDB();
|
|
||||||
|
|
||||||
// Add update checking service
|
// Add update checking service
|
||||||
if (Const.Value.UPDATE_SERVICE_VER > mm.prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
|
if (Const.Value.UPDATE_SERVICE_VER > mm.prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
|
||||||
ComponentName service = new ComponentName(this, UpdateCheckService.class);
|
ComponentName service = new ComponentName(this, UpdateCheckService.class);
|
||||||
|
@ -38,7 +38,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
|
|
||||||
private boolean unzipAndCheck() throws Exception {
|
private boolean unzipAndCheck() throws Exception {
|
||||||
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
|
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
|
||||||
List<String> ret = Utils.readFile(new File(mCachedFile.getParentFile(), "updater-script").getPath());
|
List<String> ret = Utils.readFile(new File(mCachedFile.getParentFile(), "updater-script"));
|
||||||
return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK");
|
return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
|
|
||||||
public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
||||||
@ -130,7 +129,7 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
|||||||
|
|
||||||
mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
|
mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
|
||||||
Utils.dumpPrefs();
|
Utils.dumpPrefs();
|
||||||
Shell.su_raw("pm uninstall " + Const.ORIG_PKG_NAME);
|
Utils.uninstallPkg(Const.ORIG_PKG_NAME);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import com.topjohnwu.magisk.utils.Utils;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class RestoreStockBoot extends ParallelTask<Void, Void, Boolean> {
|
public class RestoreImages extends ParallelTask<Void, Void, Boolean> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Boolean doInBackground(Void... voids) {
|
protected Boolean doInBackground(Void... voids) {
|
@ -21,7 +21,7 @@ public class Policy implements Comparable<Policy>{
|
|||||||
public Policy(int uid, PackageManager pm) throws PackageManager.NameNotFoundException {
|
public Policy(int uid, PackageManager pm) throws PackageManager.NameNotFoundException {
|
||||||
String[] pkgs = pm.getPackagesForUid(uid);
|
String[] pkgs = pm.getPackagesForUid(uid);
|
||||||
if (pkgs == null || pkgs.length == 0) throw new PackageManager.NameNotFoundException();
|
if (pkgs == null || pkgs.length == 0) throw new PackageManager.NameNotFoundException();
|
||||||
this.uid = uid % 100000;
|
this.uid = uid;
|
||||||
packageName = pkgs[0];
|
packageName = pkgs[0];
|
||||||
info = pm.getApplicationInfo(packageName, 0);
|
info = pm.getApplicationInfo(packageName, 0);
|
||||||
appName = info.loadLabel(pm).toString();
|
appName = info.loadLabel(pm).toString();
|
||||||
|
@ -15,10 +15,12 @@ import com.topjohnwu.magisk.MagiskManager;
|
|||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.container.Policy;
|
import com.topjohnwu.magisk.container.Policy;
|
||||||
import com.topjohnwu.magisk.container.SuLogEntry;
|
import com.topjohnwu.magisk.container.SuLogEntry;
|
||||||
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
import com.topjohnwu.magisk.utils.Shell;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -34,78 +36,75 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
private static final String LOG_TABLE = "logs";
|
private static final String LOG_TABLE = "logs";
|
||||||
private static final String SETTINGS_TABLE = "settings";
|
private static final String SETTINGS_TABLE = "settings";
|
||||||
private static final String STRINGS_TABLE = "strings";
|
private static final String STRINGS_TABLE = "strings";
|
||||||
|
private static final File GLOBAL_DB = new File("/data/adb/magisk.db");
|
||||||
private static String GLOBAL_DB;
|
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private PackageManager pm;
|
private PackageManager pm;
|
||||||
private SQLiteDatabase mDb;
|
private SQLiteDatabase mDb;
|
||||||
|
|
||||||
private static Context preProcess() {
|
private static Context initDB(boolean local) {
|
||||||
Context context;
|
Context context;
|
||||||
|
MagiskManager ce = MagiskManager.get();
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
Context ce = MagiskManager.get();
|
Context de = ce.createDeviceProtectedStorageContext();
|
||||||
context = ce.createDeviceProtectedStorageContext();
|
File deDB = Utils.getDatabasePath(de, DB_NAME);
|
||||||
File oldDB = Utils.getDatabasePath(ce, DB_NAME);
|
if (deDB.exists()) {
|
||||||
if (oldDB.exists()) {
|
context = de;
|
||||||
|
} else if (ce.magiskVersionCode > 1410) {
|
||||||
// Migrate DB path
|
// Migrate DB path
|
||||||
context.moveDatabaseFrom(ce, DB_NAME);
|
context = de;
|
||||||
|
de.moveDatabaseFrom(ce, DB_NAME);
|
||||||
|
} else {
|
||||||
|
context = ce;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context = MagiskManager.get();
|
context = ce;
|
||||||
}
|
}
|
||||||
GLOBAL_DB = context.getFilesDir().getParentFile().getParent() + "/magisk.db";
|
|
||||||
File db = Utils.getDatabasePath(context, DB_NAME);
|
File db = Utils.getDatabasePath(context, DB_NAME);
|
||||||
if (!db.exists() && Utils.itemExist(GLOBAL_DB)) {
|
if (local && db.length() == 0) {
|
||||||
// Migrate global DB to ours
|
ce.loadMagiskInfo();
|
||||||
db.getParentFile().mkdirs();
|
return initDB(false);
|
||||||
Shell.su(
|
}
|
||||||
"magisk --clone-attr " + context.getFilesDir() + " " + GLOBAL_DB,
|
|
||||||
"chmod 660 " + GLOBAL_DB,
|
// Only care about local db (no shell involved)
|
||||||
"ln " + GLOBAL_DB + " " + db
|
if (local)
|
||||||
);
|
return context;
|
||||||
|
|
||||||
|
// We need to make sure the global db is setup properly
|
||||||
|
if (ce.magiskVersionCode >= 1464 && Shell.rootAccess()) {
|
||||||
|
Shell.su_raw(Utils.fmt("mkdir %s; chmod 700 %s", GLOBAL_DB.getParent(), GLOBAL_DB.getParent()));
|
||||||
|
if (!Utils.itemExist(GLOBAL_DB)) {
|
||||||
|
db = context.getDatabasePath(DB_NAME);
|
||||||
|
Shell.su(Utils.fmt("cp -af %s %s; rm -f %s*", db, GLOBAL_DB, db));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
db.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the global and local db matches
|
||||||
|
if (!TextUtils.equals(Utils.checkMD5(GLOBAL_DB), Utils.checkMD5(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",
|
||||||
|
GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, db));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setupSuDB() {
|
|
||||||
MagiskManager mm = MagiskManager.get();
|
|
||||||
// Check if we need to migrate suDB
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && mm.magiskVersionCode >= 1410 &&
|
|
||||||
Utils.getDatabasePath(mm, SuDatabaseHelper.DB_NAME).exists()) {
|
|
||||||
mm.suDB.close();
|
|
||||||
mm.suDB = new SuDatabaseHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
File suDbFile = mm.suDB.getDbFile();
|
|
||||||
|
|
||||||
if (!Utils.itemExist(GLOBAL_DB)) {
|
|
||||||
// Hard link our DB globally
|
|
||||||
Shell.su_raw("ln " + suDbFile + " " + GLOBAL_DB);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we are linked globally
|
|
||||||
List<String> ret = Shell.sh("ls -l " + suDbFile);
|
|
||||||
if (Utils.isValidShellResponse(ret)) {
|
|
||||||
try {
|
|
||||||
int links = Integer.parseInt(ret.get(0).trim().split("\\s+")[1]);
|
|
||||||
if (links < 2) {
|
|
||||||
mm.suDB.close();
|
|
||||||
suDbFile.delete();
|
|
||||||
new File(suDbFile + "-journal").delete();
|
|
||||||
mm.suDB = new SuDatabaseHelper();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SuDatabaseHelper() {
|
public SuDatabaseHelper() {
|
||||||
this(preProcess());
|
this(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SuDatabaseHelper(Context context) {
|
public SuDatabaseHelper(boolean local) {
|
||||||
|
this(initDB(local));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SuDatabaseHelper(Context context) {
|
||||||
super(context, DB_NAME, null, DATABASE_VER);
|
super(context, DB_NAME, null, DATABASE_VER);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
pm = context.getPackageManager();
|
pm = context.getPackageManager();
|
||||||
@ -127,44 +126,32 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
}
|
}
|
||||||
if (oldVersion == 1) {
|
if (oldVersion == 1) {
|
||||||
// We're dropping column app_name, rename and re-construct table
|
// We're dropping column app_name, rename and re-construct table
|
||||||
db.execSQL("ALTER TABLE " + POLICY_TABLE + " RENAME TO " + POLICY_TABLE + "_old");
|
db.execSQL(Utils.fmt("ALTER TABLE %s RENAME TO %s_old", POLICY_TABLE));
|
||||||
|
|
||||||
// Create the new tables
|
// Create the new tables
|
||||||
createTables(db);
|
createTables(db);
|
||||||
|
|
||||||
// Migrate old data to new tables
|
// Migrate old data to new tables
|
||||||
db.execSQL(
|
db.execSQL(Utils.fmt("INSERT INTO %s SELECT " +
|
||||||
"INSERT INTO " + POLICY_TABLE + " SELECT " +
|
"uid, package_name, policy, until, logging, notification FROM %s_old",
|
||||||
"uid, package_name, policy, until, logging, notification " +
|
POLICY_TABLE, POLICY_TABLE));
|
||||||
"FROM " + POLICY_TABLE + "_old");
|
db.execSQL(Utils.fmt("DROP TABLE %s_old", POLICY_TABLE));
|
||||||
db.execSQL("DROP TABLE " + POLICY_TABLE + "_old");
|
|
||||||
|
|
||||||
File oldDB = Utils.getDatabasePath(MagiskManager.get(), "sulog.db");
|
MagiskManager.get().deleteDatabase("sulog.db");
|
||||||
if (oldDB.exists()) {
|
|
||||||
migrateLegacyLogList(oldDB, db);
|
|
||||||
MagiskManager.get().deleteDatabase("sulog.db");
|
|
||||||
}
|
|
||||||
++oldVersion;
|
++oldVersion;
|
||||||
}
|
}
|
||||||
if (oldVersion == 2) {
|
if (oldVersion == 2) {
|
||||||
db.execSQL("UPDATE " + LOG_TABLE + " SET time=time*1000");
|
db.execSQL(Utils.fmt("UPDATE %s SET time=time*1000", LOG_TABLE));
|
||||||
++oldVersion;
|
++oldVersion;
|
||||||
}
|
}
|
||||||
if (oldVersion == 3) {
|
if (oldVersion == 3) {
|
||||||
db.execSQL(
|
db.execSQL(Utils.fmt("CREATE TABLE IF NOT EXISTS %s (key TEXT, value TEXT, PRIMARY KEY(key))", STRINGS_TABLE));
|
||||||
"CREATE TABLE IF NOT EXISTS " + STRINGS_TABLE + " " +
|
|
||||||
"(key TEXT, value TEXT, PRIMARY KEY(key))");
|
|
||||||
++oldVersion;
|
++oldVersion;
|
||||||
}
|
}
|
||||||
if (oldVersion == 4) {
|
if (oldVersion == 4) {
|
||||||
db.execSQL("UPDATE " + POLICY_TABLE + " SET uid=uid%100000");
|
db.execSQL(Utils.fmt("UPDATE %s SET uid=uid%%100000", POLICY_TABLE));
|
||||||
++oldVersion;
|
++oldVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Utils.itemExist(GLOBAL_DB)) {
|
|
||||||
// Hard link our DB globally
|
|
||||||
Shell.su_raw("ln " + getDbFile() + " " + GLOBAL_DB);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
onDowngrade(db, DATABASE_VER, 0);
|
onDowngrade(db, DATABASE_VER, 0);
|
||||||
@ -208,15 +195,13 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
|
|
||||||
private void cleanup() {
|
private void cleanup() {
|
||||||
// Clear outdated policies
|
// Clear outdated policies
|
||||||
mDb.delete(POLICY_TABLE, "until > 0 AND until < ?",
|
mDb.delete(POLICY_TABLE, Utils.fmt("until > 0 AND until < ?", System.currentTimeMillis() / 1000), null);
|
||||||
new String[] { String.valueOf(System.currentTimeMillis() / 1000) });
|
|
||||||
// Clear outdated logs
|
// Clear outdated logs
|
||||||
mDb.delete(LOG_TABLE, "time < ?", new String[] { String.valueOf(
|
mDb.delete(LOG_TABLE, Utils.fmt("time < ?", System.currentTimeMillis() - MagiskManager.get().suLogTimeout * 86400000), null);
|
||||||
System.currentTimeMillis() - MagiskManager.get().suLogTimeout * 86400000) });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deletePolicy(Policy policy) {
|
public void deletePolicy(Policy policy) {
|
||||||
deletePolicy(policy.packageName);
|
deletePolicy(policy.uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deletePolicy(String pkg) {
|
public void deletePolicy(String pkg) {
|
||||||
@ -224,12 +209,12 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deletePolicy(int uid) {
|
public void deletePolicy(int uid) {
|
||||||
mDb.delete(POLICY_TABLE, "uid=?", new String[]{String.valueOf(uid)});
|
mDb.delete(POLICY_TABLE, Utils.fmt("uid=%d", uid), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Policy getPolicy(int uid) {
|
public Policy getPolicy(int uid) {
|
||||||
Policy policy = null;
|
Policy policy = null;
|
||||||
try (Cursor c = mDb.query(POLICY_TABLE, null, "uid=?", new String[] { String.valueOf(uid % 100000) }, null, null, null)) {
|
try (Cursor c = mDb.query(POLICY_TABLE, null, Utils.fmt("uid=%d", uid), null, null, null, null)) {
|
||||||
if (c.moveToNext()) {
|
if (c.moveToNext()) {
|
||||||
policy = new Policy(c, pm);
|
policy = new Policy(c, pm);
|
||||||
}
|
}
|
||||||
@ -240,30 +225,17 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
return policy;
|
return policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Policy getPolicy(String pkg) {
|
|
||||||
Policy policy = null;
|
|
||||||
try (Cursor c = mDb.query(POLICY_TABLE, null, "package_name=?", new String[] { pkg }, null, null, null)) {
|
|
||||||
if (c.moveToNext()) {
|
|
||||||
policy = new Policy(c, pm);
|
|
||||||
}
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
deletePolicy(pkg);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPolicy(Policy policy) {
|
public void addPolicy(Policy policy) {
|
||||||
mDb.replace(POLICY_TABLE, null, policy.getContentValues());
|
mDb.replace(POLICY_TABLE, null, policy.getContentValues());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePolicy(Policy policy) {
|
public void updatePolicy(Policy policy) {
|
||||||
mDb.update(POLICY_TABLE, policy.getContentValues(), "package_name=?",
|
mDb.update(POLICY_TABLE, policy.getContentValues(), Utils.fmt("uid=%d", policy.uid), null);
|
||||||
new String[] { policy.packageName });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Policy> getPolicyList(PackageManager pm) {
|
public List<Policy> getPolicyList(PackageManager pm) {
|
||||||
try (Cursor c = mDb.query(POLICY_TABLE, null, null, null, null, null, null)) {
|
try (Cursor c = mDb.query(POLICY_TABLE, null, Utils.fmt("uid/100000=%d", Const.USER_ID),
|
||||||
|
null, null, null, null)) {
|
||||||
List<Policy> ret = new ArrayList<>(c.getCount());
|
List<Policy> ret = new ArrayList<>(c.getCount());
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
try {
|
try {
|
||||||
@ -280,7 +252,8 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<List<Integer>> getLogStructure() {
|
public List<List<Integer>> getLogStructure() {
|
||||||
try (Cursor c = mDb.query(LOG_TABLE, new String[] { "time" }, null, null, null, null, "time DESC")) {
|
try (Cursor c = mDb.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<List<Integer>> ret = new ArrayList<>();
|
||||||
List<Integer> list = null;
|
List<Integer> list = null;
|
||||||
String dateString = null, newString;
|
String dateString = null, newString;
|
||||||
@ -299,22 +272,8 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Cursor getLogCursor() {
|
public Cursor getLogCursor() {
|
||||||
return getLogCursor(mDb);
|
return mDb.query(LOG_TABLE, null, Utils.fmt("from_uid/100000=%d", Const.USER_ID),
|
||||||
}
|
null, null, null, "time DESC");
|
||||||
|
|
||||||
public Cursor getLogCursor(SQLiteDatabase db) {
|
|
||||||
return db.query(LOG_TABLE, null, null, null, null, null, "time DESC");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void migrateLegacyLogList(File oldDB, SQLiteDatabase newDB) {
|
|
||||||
try (SQLiteDatabase oldDb = SQLiteDatabase.openDatabase(oldDB.getPath(), null, SQLiteDatabase.OPEN_READWRITE);
|
|
||||||
Cursor c = getLogCursor(oldDb)) {
|
|
||||||
while (c.moveToNext()) {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
DatabaseUtils.cursorRowToContentValues(c, values);
|
|
||||||
newDB.insert(LOG_TABLE, null, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLog(SuLogEntry log) {
|
public void addLog(SuLogEntry log) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.topjohnwu.magisk.utils;
|
package com.topjohnwu.magisk.utils;
|
||||||
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.os.Process;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -63,6 +64,8 @@ public class Const {
|
|||||||
"com.nianticlabs.pokemongo"
|
"com.nianticlabs.pokemongo"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static final int USER_ID = Process.myUid() / 100000;
|
||||||
|
|
||||||
public static class ID {
|
public static class ID {
|
||||||
public static final int UPDATE_SERVICE_ID = 1;
|
public static final int UPDATE_SERVICE_ID = 1;
|
||||||
public static final int FETCH_ZIP = 2;
|
public static final int FETCH_ZIP = 2;
|
||||||
|
@ -7,6 +7,7 @@ import android.app.PendingIntent;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Handler;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.TaskStackBuilder;
|
import android.support.v4.app.TaskStackBuilder;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
@ -16,14 +17,13 @@ import com.topjohnwu.magisk.FlashActivity;
|
|||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.SplashActivity;
|
import com.topjohnwu.magisk.SplashActivity;
|
||||||
import com.topjohnwu.magisk.asyncs.RestoreStockBoot;
|
import com.topjohnwu.magisk.asyncs.RestoreImages;
|
||||||
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||||
import com.topjohnwu.magisk.receivers.ManagerUpdate;
|
import com.topjohnwu.magisk.receivers.ManagerUpdate;
|
||||||
import com.topjohnwu.magisk.receivers.RebootReceiver;
|
import com.topjohnwu.magisk.receivers.RebootReceiver;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -258,42 +258,35 @@ public class ShowUI {
|
|||||||
.setTitle(R.string.uninstall_magisk_title)
|
.setTitle(R.string.uninstall_magisk_title)
|
||||||
.setMessage(R.string.uninstall_magisk_msg)
|
.setMessage(R.string.uninstall_magisk_msg)
|
||||||
.setPositiveButton(R.string.complete_uninstall, (d, i) -> {
|
.setPositiveButton(R.string.complete_uninstall, (d, i) -> {
|
||||||
try {
|
ByteArrayOutputStream uninstaller = new ByteArrayOutputStream();
|
||||||
InputStream in = mm.getAssets().open(Const.UNINSTALLER);
|
try (InputStream in = mm.getAssets().open(Const.UNINSTALLER)) {
|
||||||
File uninstaller = new File(mm.getCacheDir(), Const.UNINSTALLER);
|
Utils.inToOut(in, uninstaller);
|
||||||
FileOutputStream out = new FileOutputStream(uninstaller);
|
|
||||||
byte[] bytes = new byte[1024];
|
|
||||||
int read;
|
|
||||||
while ((read = in.read(bytes)) != -1) {
|
|
||||||
out.write(bytes, 0, read);
|
|
||||||
}
|
|
||||||
in.close();
|
|
||||||
out.close();
|
|
||||||
in = mm.getAssets().open(Const.UTIL_FUNCTIONS);
|
|
||||||
File utils = new File(mm.getCacheDir(), Const.UTIL_FUNCTIONS);
|
|
||||||
out = new FileOutputStream(utils);
|
|
||||||
while ((read = in.read(bytes)) != -1) {
|
|
||||||
out.write(bytes, 0, read);
|
|
||||||
}
|
|
||||||
in.close();
|
|
||||||
out.close();
|
|
||||||
Shell.su(
|
|
||||||
"cat " + uninstaller + " > /cache/" + Const.UNINSTALLER,
|
|
||||||
"cat " + utils + " > /data/magisk/" + Const.UTIL_FUNCTIONS
|
|
||||||
);
|
|
||||||
MagiskManager.toast(R.string.uninstall_toast, Toast.LENGTH_LONG);
|
|
||||||
Shell.su_raw(
|
|
||||||
"sleep 5",
|
|
||||||
"pm uninstall " + mm.getApplicationInfo().packageName
|
|
||||||
);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
ByteArrayOutputStream utils = new ByteArrayOutputStream();
|
||||||
|
try (InputStream in = mm.getAssets().open(Const.UTIL_FUNCTIONS)) {
|
||||||
|
Utils.inToOut(in, utils);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shell.su(
|
||||||
|
Utils.fmt("echo '%s' > /cache/%s", uninstaller.toString().replace("'", "'\\''"), Const.UNINSTALLER),
|
||||||
|
Utils.fmt("echo '%s' > /data/magisk/%s", utils.toString().replace("'", "'\\''"), Const.UTIL_FUNCTIONS)
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
uninstaller.close();
|
||||||
|
utils.close();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
|
||||||
|
MagiskManager.toast(R.string.uninstall_toast, Toast.LENGTH_LONG);
|
||||||
|
new Handler().postDelayed(() -> Utils.uninstallPkg(mm.getPackageName()), 5000);
|
||||||
})
|
})
|
||||||
.setNeutralButton(R.string.restore_stock_boot, (d, i) -> {
|
.setNeutralButton(R.string.restore_img, (d, i) -> new RestoreImages().exec())
|
||||||
new RestoreStockBoot().exec();
|
.setNegativeButton(R.string.uninstall_app, (d, i) -> Utils.uninstallPkg(mm.getPackageName()))
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.no_thanks, null)
|
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,24 +45,32 @@ public class Utils {
|
|||||||
|
|
||||||
public static boolean isDownloading = false;
|
public static boolean isDownloading = false;
|
||||||
|
|
||||||
public static boolean itemExist(String path) {
|
public static boolean itemExist(Object path) {
|
||||||
List<String> ret = Shell.su(fmt("[ -e %s ] && echo true || echo false", path));
|
List<String> ret = Shell.su(fmt("[ -e %s ] && echo true || echo false", path));
|
||||||
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
|
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createFile(String path) {
|
public static void createFile(Object path) {
|
||||||
String folder = path.substring(0, path.lastIndexOf('/'));
|
Shell.su_raw(fmt("mkdir -p `dirname '%s'` 2>/dev/null; touch '%s' 2>/dev/null", path, path));
|
||||||
Shell.su_raw(fmt("mkdir -p %s 2>/dev/null; touch %s 2>/dev/null", folder, path));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeItem(String path) {
|
public static void removeItem(Object path) {
|
||||||
Shell.su_raw(fmt("rm -rf %s 2>/dev/null", path));
|
Shell.su_raw(fmt("rm -rf %s 2>/dev/null", path));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> readFile(String path) {
|
public static List<String> readFile(Object path) {
|
||||||
return Shell.su(fmt("cat %s | sed '$a\\ ' | sed '$d'", path));
|
return Shell.su(fmt("cat %s | sed '$a\\ ' | sed '$d'", path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String checkMD5(Object path) {
|
||||||
|
List<String> ret = Shell.su(fmt("md5sum %s", path));
|
||||||
|
return isValidShellResponse(ret) ? ret.get(0).split("\\s+")[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void uninstallPkg(String pkg) {
|
||||||
|
Shell.su_raw(fmt("find /data/user*/*/%s -exec umount -l {} 2>/dev/null \\;; pm uninstall %s", pkg, pkg));
|
||||||
|
}
|
||||||
|
|
||||||
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
|
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
|
||||||
if (isDownloading)
|
if (isDownloading)
|
||||||
return;
|
return;
|
||||||
@ -209,6 +217,10 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File getDatabasePath(String dbName) {
|
||||||
|
return getDatabasePath(MagiskManager.get(), dbName);
|
||||||
|
}
|
||||||
|
|
||||||
public static File getDatabasePath(Context context, String dbName) {
|
public static File getDatabasePath(Context context, String dbName) {
|
||||||
return new File(context.getFilesDir().getParent() + "/databases", dbName);
|
return new File(context.getFilesDir().getParent() + "/databases", dbName);
|
||||||
}
|
}
|
||||||
@ -258,7 +270,7 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void loadPrefs() {
|
public static void loadPrefs() {
|
||||||
String config = fmt("/data/user/%d/%s", MagiskManager.get().userId, Const.MANAGER_CONFIGS);
|
String config = fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS);
|
||||||
List<String> ret = readFile(config);
|
List<String> ret = readFile(config);
|
||||||
if (isValidShellResponse(ret)) {
|
if (isValidShellResponse(ret)) {
|
||||||
removeItem(config);
|
removeItem(config);
|
||||||
|
@ -115,6 +115,8 @@
|
|||||||
<string name="boot_file_patch_msg">Select stock boot image dump in .img or .img.tar format</string>
|
<string name="boot_file_patch_msg">Select stock boot image dump in .img or .img.tar format</string>
|
||||||
<string name="complete_uninstall">Complete Uninstall</string>
|
<string name="complete_uninstall">Complete Uninstall</string>
|
||||||
<string name="restore_stock_boot">Restore Stock Boot</string>
|
<string name="restore_stock_boot">Restore Stock Boot</string>
|
||||||
|
<string name="restore_img">Restore Images</string>
|
||||||
|
<string name="uninstall_app">Uninstall App</string>
|
||||||
<string name="restore_done">Restoration done!</string>
|
<string name="restore_done">Restoration done!</string>
|
||||||
<string name="restore_fail">Stock backup does not exist!</string>
|
<string name="restore_fail">Stock backup does not exist!</string>
|
||||||
<string name="uninstall_toast">Uninstalling Magisk Manager in 5 seconds, please manually reboot afterwards</string>
|
<string name="uninstall_toast">Uninstalling Magisk Manager in 5 seconds, please manually reboot afterwards</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user