diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java b/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java index 4c56e25d0..2d2b86c87 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskManager.java @@ -24,6 +24,7 @@ public class MagiskManager extends Application { public static final String MAGISK_DISABLE_FILE = "/cache/.disable_magisk"; public static final String MAGISK_HIDE_PATH = "/magisk/.core/magiskhide/"; public static final String TMP_FOLDER_PATH = "/dev/tmp"; + public static final String MAGISK_PATH = "/magisk"; // Events public final CallbackEvent blockDetectionDone = new CallbackEvent<>(); @@ -33,7 +34,7 @@ public class MagiskManager extends Application { public final CallbackEvent repoLoadDone = new CallbackEvent<>(); public final CallbackEvent updateCheckDone = new CallbackEvent<>(); public final CallbackEvent safetyNetDone = new CallbackEvent<>(); - public SparseArray> uidMap = new SparseArray<>(); + public final SparseArray> uidSuRequest = new SparseArray<>(); // Info public double magiskVersion; diff --git a/app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java b/app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java index de1710cf9..7e45dd2d7 100644 --- a/app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java @@ -16,7 +16,6 @@ import android.widget.Toast; import com.topjohnwu.magisk.asyncs.MagiskHide; import com.topjohnwu.magisk.asyncs.SerialTask; import com.topjohnwu.magisk.components.Activity; -import com.topjohnwu.magisk.module.ModuleHelper; import com.topjohnwu.magisk.utils.Logger; import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Utils; @@ -104,7 +103,7 @@ public class SettingsActivity extends Activity { setSummary(); findPreference("clear").setOnPreferenceClickListener((pref) -> { - ModuleHelper.clearRepoCache(getActivity()); + Utils.clearRepoCache(getActivity()); return true; }); diff --git a/app/src/main/java/com/topjohnwu/magisk/asyncs/LoadModules.java b/app/src/main/java/com/topjohnwu/magisk/asyncs/LoadModules.java index ab4b5cb0d..96ed1dcd5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/asyncs/LoadModules.java +++ b/app/src/main/java/com/topjohnwu/magisk/asyncs/LoadModules.java @@ -2,7 +2,12 @@ package com.topjohnwu.magisk.asyncs; import android.app.Activity; -import com.topjohnwu.magisk.module.ModuleHelper; +import com.topjohnwu.magisk.MagiskManager; +import com.topjohnwu.magisk.module.BaseModule; +import com.topjohnwu.magisk.module.Module; +import com.topjohnwu.magisk.utils.Logger; +import com.topjohnwu.magisk.utils.Utils; +import com.topjohnwu.magisk.utils.ValueSortedMap; public class LoadModules extends SerialTask { @@ -12,7 +17,20 @@ public class LoadModules extends SerialTask { @Override protected Void doInBackground(Void... voids) { - ModuleHelper.createModuleMap(magiskManager); + Logger.dev("LoadModules: Loading modules"); + + magiskManager.moduleMap = new ValueSortedMap<>(); + + for (String path : Utils.getModList(MagiskManager.MAGISK_PATH)) { + Logger.dev("LoadModules: Adding modules from " + path); + Module module; + try { + module = new Module(path); + magiskManager.moduleMap.put(module.getId(), module); + } catch (BaseModule.CacheModException ignored) {} + } + + Logger.dev("LoadModules: Data load done"); return null; } diff --git a/app/src/main/java/com/topjohnwu/magisk/asyncs/LoadRepos.java b/app/src/main/java/com/topjohnwu/magisk/asyncs/LoadRepos.java index dde914246..9bf47c6f3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/asyncs/LoadRepos.java +++ b/app/src/main/java/com/topjohnwu/magisk/asyncs/LoadRepos.java @@ -1,18 +1,129 @@ package com.topjohnwu.magisk.asyncs; import android.app.Activity; +import android.content.SharedPreferences; -import com.topjohnwu.magisk.module.ModuleHelper; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.topjohnwu.magisk.R; +import com.topjohnwu.magisk.module.BaseModule; +import com.topjohnwu.magisk.module.Repo; +import com.topjohnwu.magisk.utils.Logger; +import com.topjohnwu.magisk.utils.ValueSortedMap; +import com.topjohnwu.magisk.utils.WebService; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; public class LoadRepos extends ParallelTask { + public static final String ETAG_KEY = "ETag"; + public static final String VERSION_KEY = "version"; + public static final String REPO_KEY = "repomap"; + public static final String FILE_KEY = "RepoMap"; + private static final int GSON_DB_VER = 1; + public LoadRepos(Activity context) { super(context); } @Override protected Void doInBackground(Void... voids) { - ModuleHelper.createRepoMap(magiskManager); + Logger.dev("LoadRepos: Loading repos"); + + SharedPreferences prefs = magiskManager.prefs; + + magiskManager.repoMap = new ValueSortedMap<>(); + + Gson gson = new Gson(); + String jsonString; + + int cachedVersion = prefs.getInt(VERSION_KEY, 0); + if (cachedVersion != GSON_DB_VER) { + // Ignore incompatible cached database + jsonString = null; + } else { + jsonString = prefs.getString(REPO_KEY, null); + } + + Map cached = null; + + if (jsonString != null) { + cached = gson.fromJson(jsonString, new TypeToken>(){}.getType()); + } + + if (cached == null) { + cached = new ValueSortedMap<>(); + } + + // Get cached ETag to add in the request header + String etag = prefs.getString(ETAG_KEY, ""); + Map header = new HashMap<>(); + header.put("If-None-Match", etag); + + // Making a request to main URL for repo info + jsonString = WebService.request( + magiskManager.getString(R.string.url_main), WebService.GET, null, header, false); + + if (!jsonString.isEmpty()) { + try { + JSONArray jsonArray = new JSONArray(jsonString); + // If it gets to this point, the response is valid, update ETag + etag = WebService.getLastResponseHeader().get(ETAG_KEY).get(0); + // Maybe bug in Android build tools, sometimes the ETag has crap in it... + etag = etag.substring(etag.indexOf('\"'), etag.lastIndexOf('\"') + 1); + + // Update repo info + 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; + try { + updatedDate = format.parse(lastUpdate); + } catch (ParseException e) { + continue; + } + Repo repo = cached.get(id); + try { + if (repo == null) { + Logger.dev("LoadRepos: Create new repo " + id); + repo = new Repo(magiskManager, name, updatedDate); + } else { + Logger.dev("LoadRepos: Update cached repo " + id); + repo.update(updatedDate); + } + if (repo.getId() != null) { + magiskManager.repoMap.put(id, repo); + } + } catch (BaseModule.CacheModException ignored) {} + } + } catch (JSONException e) { + e.printStackTrace(); + } + } else { + // Use cached if no internet or no updates + Logger.dev("LoadRepos: No updates, use cached"); + magiskManager.repoMap.putAll(cached); + } + + prefs.edit() + .putInt(VERSION_KEY, GSON_DB_VER) + .putString(REPO_KEY, gson.toJson(magiskManager.repoMap)) + .putString(ETAG_KEY, etag) + .apply(); + + Logger.dev("LoadRepos: Repo load done"); return null; } diff --git a/app/src/main/java/com/topjohnwu/magisk/module/BaseModule.java b/app/src/main/java/com/topjohnwu/magisk/module/BaseModule.java index 8704e7f45..4179c75c2 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/BaseModule.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/BaseModule.java @@ -97,7 +97,7 @@ public abstract class BaseModule implements Comparable { public static class CacheModException extends Exception { public CacheModException(String id) { - Logger.dev("Cache mods are no longer supported! id: " + id); + Logger.error("Cache mods are no longer supported! id: " + id); } } diff --git a/app/src/main/java/com/topjohnwu/magisk/module/ModuleHelper.java b/app/src/main/java/com/topjohnwu/magisk/module/ModuleHelper.java deleted file mode 100644 index 2ee230a66..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/module/ModuleHelper.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.topjohnwu.magisk.module; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.widget.Toast; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.topjohnwu.magisk.MagiskManager; -import com.topjohnwu.magisk.R; -import com.topjohnwu.magisk.asyncs.LoadRepos; -import com.topjohnwu.magisk.utils.Logger; -import com.topjohnwu.magisk.utils.Utils; -import com.topjohnwu.magisk.utils.ValueSortedMap; -import com.topjohnwu.magisk.utils.WebService; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -public class ModuleHelper { - - private static final String MAGISK_PATH = "/magisk"; - - private static final int GSON_DB_VER = 1; - private static final String ETAG_KEY = "ETag"; - private static final String VERSION_KEY = "version"; - private static final String REPO_KEY = "repomap"; - private static final String FILE_KEY = "RepoMap"; - - public static void createModuleMap(MagiskManager magiskManager) { - Logger.dev("ModuleHelper: Loading modules"); - - magiskManager.moduleMap = new ValueSortedMap<>(); - - for (String path : Utils.getModList(MAGISK_PATH)) { - Logger.dev("ModuleHelper: Adding modules from " + path); - Module module; - try { - module = new Module(path); - magiskManager.moduleMap.put(module.getId(), module); - } catch (BaseModule.CacheModException ignored) {} - } - - Logger.dev("ModuleHelper: Data load done"); - } - - public static void createRepoMap(MagiskManager magiskManager) { - Logger.dev("ModuleHelper: Loading repos"); - - SharedPreferences prefs = magiskManager.prefs; - - magiskManager.repoMap = new ValueSortedMap<>(); - - Gson gson = new Gson(); - String jsonString; - - int cachedVersion = prefs.getInt(VERSION_KEY, 0); - if (cachedVersion != GSON_DB_VER) { - // Ignore incompatible cached database - jsonString = null; - } else { - jsonString = prefs.getString(REPO_KEY, null); - } - - Map cached = null; - - if (jsonString != null) { - cached = gson.fromJson(jsonString, new TypeToken>(){}.getType()); - } - - if (cached == null) { - cached = new ValueSortedMap<>(); - } - - // Get cached ETag to add in the request header - String etag = prefs.getString(ETAG_KEY, ""); - Map header = new HashMap<>(); - header.put("If-None-Match", etag); - - // Making a request to main URL for repo info - jsonString = WebService.request( - magiskManager.getString(R.string.url_main), WebService.GET, null, header, false); - - if (!jsonString.isEmpty()) { - try { - JSONArray jsonArray = new JSONArray(jsonString); - // If it gets to this point, the response is valid, update ETag - etag = WebService.getLastResponseHeader().get(ETAG_KEY).get(0); - // Maybe bug in Android build tools, sometimes the ETag has crap in it... - etag = etag.substring(etag.indexOf('\"'), etag.lastIndexOf('\"') + 1); - - // Update repo info - 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; - try { - updatedDate = format.parse(lastUpdate); - } catch (ParseException e) { - continue; - } - Repo repo = cached.get(id); - try { - if (repo == null) { - Logger.dev("ModuleHelper: Create new repo " + id); - repo = new Repo(magiskManager, name, updatedDate); - } else { - Logger.dev("ModuleHelper: Update cached repo " + id); - repo.update(updatedDate); - } - if (repo.getId() != null) { - magiskManager.repoMap.put(id, repo); - } - } catch (BaseModule.CacheModException ignored) {} - } - } catch (JSONException e) { - e.printStackTrace(); - } - } else { - // Use cached if no internet or no updates - Logger.dev("ModuleHelper: No updates, use cached"); - magiskManager.repoMap.putAll(cached); - } - - prefs.edit() - .putInt(VERSION_KEY, GSON_DB_VER) - .putString(REPO_KEY, gson.toJson(magiskManager.repoMap)) - .putString(ETAG_KEY, etag) - .apply(); - - Logger.dev("ModuleHelper: Repo load done"); - } - - public static void clearRepoCache(Activity activity) { - MagiskManager magiskManager = Utils.getMagiskManager(activity); - SharedPreferences repoMap = activity.getSharedPreferences(FILE_KEY, Context.MODE_PRIVATE); - repoMap.edit() - .remove(ETAG_KEY) - .remove(VERSION_KEY) - .apply(); - magiskManager.repoLoadDone.isTriggered = false; - new LoadRepos(activity).exec(); - Toast.makeText(activity, R.string.repo_cache_cleared, Toast.LENGTH_SHORT).show(); - } - -} diff --git a/app/src/main/java/com/topjohnwu/magisk/module/Repo.java b/app/src/main/java/com/topjohnwu/magisk/module/Repo.java index 4a5ea52d6..41da8c2fa 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Repo.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Repo.java @@ -28,8 +28,7 @@ public class Repo extends BaseModule { } public void update(Date lastUpdate) throws CacheModException { - Logger.dev("Repo: Old: " + mLastUpdate); - Logger.dev("Repo: New: " + lastUpdate); + Logger.dev("Repo: Old: " + mLastUpdate + " New: " + lastUpdate); if (mIsCacheModule) throw new CacheModException(mId); if (lastUpdate.after(mLastUpdate)) { diff --git a/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java b/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java index 0ca5368b3..1c3fa2d7a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/superuser/SuRequestActivity.java @@ -223,7 +223,7 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene return; } boolean showRequest = false; - event = magiskManager.uidMap.get(uid); + event = magiskManager.uidSuRequest.get(uid); if (event == null) { showRequest = true; event = new CallbackEvent() { @@ -231,10 +231,10 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene public void trigger(Policy result) { super.trigger(result); unRegister(); - magiskManager.uidMap.remove(uid); + magiskManager.uidSuRequest.remove(uid); } }; - magiskManager.uidMap.put(uid, event); + magiskManager.uidSuRequest.put(uid, event); } event.register(self); try { diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java index bc0588f78..7d6abf978 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -1,6 +1,7 @@ package com.topjohnwu.magisk.utils; import android.Manifest; +import android.app.Activity; import android.app.DownloadManager; import android.content.Context; import android.content.IntentFilter; @@ -15,6 +16,7 @@ import android.widget.Toast; import com.topjohnwu.magisk.MagiskManager; import com.topjohnwu.magisk.R; +import com.topjohnwu.magisk.asyncs.LoadRepos; import com.topjohnwu.magisk.receivers.DownloadReceiver; import java.io.File; @@ -152,4 +154,16 @@ public class Utils { } }.requestTest(); } + + public static void clearRepoCache(Activity activity) { + MagiskManager magiskManager = getMagiskManager(activity); + SharedPreferences repoMap = activity.getSharedPreferences(LoadRepos.FILE_KEY, Context.MODE_PRIVATE); + repoMap.edit() + .remove(LoadRepos.ETAG_KEY) + .remove(LoadRepos.VERSION_KEY) + .apply(); + magiskManager.repoLoadDone.isTriggered = false; + new LoadRepos(activity).exec(); + Toast.makeText(activity, R.string.repo_cache_cleared, Toast.LENGTH_SHORT).show(); + } } \ No newline at end of file