diff --git a/stub/build.gradle b/stub/build.gradle index 932b547fc..09e752235 100644 --- a/stub/build.gradle +++ b/stub/build.gradle @@ -11,7 +11,7 @@ android { buildTypes { release { minifyEnabled true - shrinkResources false /* Do NOT allow resource shrinking */ + shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } diff --git a/stub/src/main/AndroidManifest.xml b/stub/src/main/AndroidManifest.xml index 8222e9ca7..f83aeb971 100644 --- a/stub/src/main/AndroidManifest.xml +++ b/stub/src/main/AndroidManifest.xml @@ -5,76 +5,23 @@ package="com.topjohnwu.magisk"> - - - - - - + tools:ignore="AllowBackup"> + android:name="a.a" + android:theme="@android:style/Theme.Translucent.NoTitleBar"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:name="a.r" + tools:node="remove"/> diff --git a/stub/src/main/java/a/a.java b/stub/src/main/java/a/a.java index 3510c9096..c3f431e83 100644 --- a/stub/src/main/java/a/a.java +++ b/stub/src/main/java/a/a.java @@ -1,6 +1,6 @@ package a; -import com.topjohnwu.magisk.DelegateComponentFactory; +import com.topjohnwu.magisk.MainActivity; -public class a extends DelegateComponentFactory { +public class a extends MainActivity { } diff --git a/stub/src/main/java/a/c.java b/stub/src/main/java/a/c.java deleted file mode 100644 index 44b3521e1..000000000 --- a/stub/src/main/java/a/c.java +++ /dev/null @@ -1,6 +0,0 @@ -package a; - -import com.topjohnwu.magisk.DownloadActivity; - -public class c extends DownloadActivity { -} diff --git a/stub/src/main/java/a/e.java b/stub/src/main/java/a/e.java deleted file mode 100644 index cd2e45a4c..000000000 --- a/stub/src/main/java/a/e.java +++ /dev/null @@ -1,6 +0,0 @@ -package a; - -import com.topjohnwu.magisk.DelegateApplication; - -public class e extends DelegateApplication { -} diff --git a/stub/src/main/java/a/h.java b/stub/src/main/java/a/h.java deleted file mode 100644 index 51120d19c..000000000 --- a/stub/src/main/java/a/h.java +++ /dev/null @@ -1,6 +0,0 @@ -package a; - -import com.topjohnwu.magisk.dummy.DummyReceiver; - -public class h extends DummyReceiver { -} diff --git a/stub/src/main/java/com/topjohnwu/magisk/DelegateApplication.java b/stub/src/main/java/com/topjohnwu/magisk/DelegateApplication.java deleted file mode 100644 index c6b808802..000000000 --- a/stub/src/main/java/com/topjohnwu/magisk/DelegateApplication.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.topjohnwu.magisk; - -import android.annotation.SuppressLint; -import android.app.AppComponentFactory; -import android.app.Application; -import android.content.Context; -import android.content.ContextWrapper; -import android.content.res.Configuration; -import android.os.Build; -import android.util.Log; - -import com.topjohnwu.magisk.obfuscate.Mapping; -import com.topjohnwu.magisk.utils.DynamicClassLoader; - -import java.io.File; -import java.lang.reflect.Method; - -public class DelegateApplication extends Application { - - static File MANAGER_APK; - - private DelegateComponentFactory factory; - private Application delegate; - - public DelegateApplication() {} - - public DelegateApplication(DelegateComponentFactory o) { - factory = o; - } - - @Override - protected void attachBaseContext(Context base) { - super.attachBaseContext(base); - if (Build.VERSION.SDK_INT >= 28) { - setUpDynAPK(); - } else { - MANAGER_APK = new File(base.getCacheDir(), "app.apk"); - } - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - delegate.onConfigurationChanged(newConfig); - } - - @SuppressLint("NewApi") - private void setUpDynAPK() { - MANAGER_APK = DynAPK.current(this); - File update = DynAPK.update(this); - if (update.exists()) - update.renameTo(MANAGER_APK); - if (MANAGER_APK.exists()) { - ClassLoader cl = new DynamicClassLoader(MANAGER_APK, factory.loader); - try { - // Create the delegate AppComponentFactory - AppComponentFactory df = (AppComponentFactory) - cl.loadClass("androidx.core.app.CoreComponentFactory").newInstance(); - - // Create the delegate Application - delegate = (Application) cl.loadClass("a.e").getConstructor(Object.class) - .newInstance(DynAPK.pack(Mapping.data())); - - // Call attachBaseContext without ContextImpl to show it is being wrapped - Method m = ContextWrapper.class.getDeclaredMethod("attachBaseContext", Context.class); - m.setAccessible(true); - m.invoke(delegate, this); - - // If everything went well, set our loader and delegate - factory.delegate = df; - factory.loader = cl; - } catch (Exception e) { - Log.e(getClass().getSimpleName(), "", e); - MANAGER_APK.delete(); - } - } - } -} diff --git a/stub/src/main/java/com/topjohnwu/magisk/DelegateComponentFactory.java b/stub/src/main/java/com/topjohnwu/magisk/DelegateComponentFactory.java deleted file mode 100644 index f21839c52..000000000 --- a/stub/src/main/java/com/topjohnwu/magisk/DelegateComponentFactory.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.topjohnwu.magisk; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AppComponentFactory; -import android.app.Application; -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.ContentProvider; -import android.content.Intent; - -import com.topjohnwu.magisk.dummy.DummyActivity; -import com.topjohnwu.magisk.dummy.DummyProvider; -import com.topjohnwu.magisk.dummy.DummyReceiver; -import com.topjohnwu.magisk.dummy.DummyService; -import com.topjohnwu.magisk.obfuscate.Mapping; - -@SuppressLint("NewApi") -public class DelegateComponentFactory extends AppComponentFactory { - - ClassLoader loader; - AppComponentFactory delegate; - - @Override - public Application instantiateApplication(ClassLoader cl, String className) { - if (loader == null) loader = cl; - return new DelegateApplication(this); - } - - @Override - public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) - throws ClassNotFoundException, IllegalAccessException, InstantiationException { - if (delegate != null) - return delegate.instantiateActivity(loader, Mapping.get(className), intent); - return create(className, DummyActivity.class); - } - - @Override - public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className, Intent intent) - throws ClassNotFoundException, IllegalAccessException, InstantiationException { - if (delegate != null) - return delegate.instantiateReceiver(loader, Mapping.get(className), intent); - return create(className, DummyReceiver.class); - } - - @Override - public Service instantiateService(ClassLoader cl, String className, Intent intent) - throws ClassNotFoundException, IllegalAccessException, InstantiationException { - if (delegate != null) - return delegate.instantiateService(loader, Mapping.get(className), intent); - return create(className, DummyService.class); - } - - @Override - public ContentProvider instantiateProvider(ClassLoader cl, String className) - throws ClassNotFoundException, IllegalAccessException, InstantiationException { - if (loader == null) loader = cl; - if (delegate != null) - return delegate.instantiateProvider(loader, Mapping.get(className)); - return create(className, DummyProvider.class); - } - - /** - * Create the class or dummy implementation if creation failed - */ - private T create(String name, Class dummy) - throws InstantiationException, IllegalAccessException { - try { - return (T) loader.loadClass(name).newInstance(); - } catch (IllegalAccessException | InstantiationException | ClassNotFoundException ignored) { - return dummy.newInstance(); - } - } -} diff --git a/stub/src/main/java/com/topjohnwu/magisk/DownloadActivity.java b/stub/src/main/java/com/topjohnwu/magisk/MainActivity.java similarity index 56% rename from stub/src/main/java/com/topjohnwu/magisk/DownloadActivity.java rename to stub/src/main/java/com/topjohnwu/magisk/MainActivity.java index 87e79d151..19c62db2d 100644 --- a/stub/src/main/java/com/topjohnwu/magisk/DownloadActivity.java +++ b/stub/src/main/java/com/topjohnwu/magisk/MainActivity.java @@ -4,33 +4,33 @@ import android.app.Activity; import android.app.AlertDialog; import android.app.Application; import android.app.ProgressDialog; -import android.content.ComponentName; -import android.content.Intent; -import android.os.Build; import android.os.Bundle; import android.util.Log; import com.topjohnwu.magisk.net.ErrorHandler; import com.topjohnwu.magisk.net.Networking; import com.topjohnwu.magisk.net.ResponseListener; -import com.topjohnwu.magisk.obfuscate.Mapping; -import com.topjohnwu.magisk.obfuscate.RawData; import com.topjohnwu.magisk.utils.APKInstall; import org.json.JSONException; import org.json.JSONObject; +import java.io.File; + import static android.R.string.no; import static android.R.string.ok; import static android.R.string.yes; -import static com.topjohnwu.magisk.DelegateApplication.MANAGER_APK; +import static android.app.AlertDialog.THEME_DEVICE_DEFAULT_DARK; -public class DownloadActivity extends Activity { +public class MainActivity extends Activity { private static final boolean CANARY = !BuildConfig.VERSION_NAME.contains("."); private static final String URL = - BuildConfig.DEV_CHANNEL != null ? BuildConfig.DEV_CHANNEL : RawData.urlBase() + - (BuildConfig.DEBUG ? RawData.debug() : (CANARY ? RawData.canary() : RawData.stable())); + BuildConfig.DEV_CHANNEL != null ? BuildConfig.DEV_CHANNEL : + "https://raw.githubusercontent.com/topjohnwu/magisk_files/" + + (BuildConfig.DEBUG ? "canary/debug.json" : + (CANARY ? "canary/release.json" : "master/stable.json")); + private static final String APP_NAME = "Magisk Manager"; private String apkLink; private ErrorHandler err = (conn, e) -> { @@ -40,35 +40,26 @@ public class DownloadActivity extends Activity { private void showDialog() { ProgressDialog.show(this, - RawData.dling(), - RawData.dling() + " " + RawData.appName(), - true); + getString(R.string.dling), + getString(R.string.dling) + " " + APP_NAME, + true); } private void dlAPK() { showDialog(); - if (Build.VERSION.SDK_INT >= 28) { - // Download and relaunch the app - Networking.get(apkLink) - .setErrorHandler(err) - .getAsFile(MANAGER_APK, apk -> { - Intent intent = new Intent() - .setComponent(new ComponentName(this, Mapping.inverse("a.r"))); - ProcessPhoenix.triggerRebirth(this, intent); - }); - } else { - // Download and upgrade the app - Application app = getApplication(); - Networking.get(apkLink) - .setErrorHandler(err) - .getAsFile(MANAGER_APK, apk -> APKInstall.install(app, apk)); - } + // Download and upgrade the app + Application app = getApplication(); + Networking.get(apkLink) + .setErrorHandler(err) + .getAsFile( + new File(getCacheDir(), "manager.apk"), + apk -> APKInstall.install(app, apk) + ); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - RawData.res = getResources(); Networking.init(this); if (Networking.checkNetworkStatus(this)) { @@ -76,10 +67,10 @@ public class DownloadActivity extends Activity { .setErrorHandler(err) .getAsJSONObject(new JSONLoader()); } else { - new AlertDialog.Builder(this) + new AlertDialog.Builder(this, THEME_DEVICE_DEFAULT_DARK) .setCancelable(false) - .setTitle(RawData.appName()) - .setMessage(RawData.networkError()) + .setTitle(APP_NAME) + .setMessage(getString(R.string.no_internet_msg)) .setNegativeButton(ok, (d, w) -> finish()) .show(); } @@ -92,10 +83,10 @@ public class DownloadActivity extends Activity { try { JSONObject manager = json.getJSONObject("app"); apkLink = manager.getString("link"); - new AlertDialog.Builder(DownloadActivity.this) + new AlertDialog.Builder(MainActivity.this, THEME_DEVICE_DEFAULT_DARK) .setCancelable(false) - .setTitle(RawData.appName()) - .setMessage(RawData.upgradeMsg()) + .setTitle(APP_NAME) + .setMessage(getString(R.string.upgrade_msg)) .setPositiveButton(yes, (d, w) -> dlAPK()) .setNegativeButton(no, (d, w) -> finish()) .show(); diff --git a/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyActivity.java b/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyActivity.java deleted file mode 100644 index 7a279ba55..000000000 --- a/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyActivity.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.topjohnwu.magisk.dummy; - -import android.app.Activity; -import android.os.Bundle; - -public class DummyActivity extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - finish(); - } -} diff --git a/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyProvider.java b/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyProvider.java deleted file mode 100644 index 0c407ff8c..000000000 --- a/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.topjohnwu.magisk.dummy; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.database.Cursor; -import android.net.Uri; - -public class DummyProvider extends ContentProvider { - @Override - public boolean onCreate() { - return false; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - return null; - } - - @Override - public String getType(Uri uri) { - return null; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - return null; - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - return 0; - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - return 0; - } -} diff --git a/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyReceiver.java b/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyReceiver.java deleted file mode 100644 index f4e57e7a7..000000000 --- a/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyReceiver.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.topjohnwu.magisk.dummy; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class DummyReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) {} -} diff --git a/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyService.java b/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyService.java deleted file mode 100644 index 6bce30183..000000000 --- a/stub/src/main/java/com/topjohnwu/magisk/dummy/DummyService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.topjohnwu.magisk.dummy; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; - -public class DummyService extends Service { - @Override - public IBinder onBind(Intent intent) { - stopSelf(); - return null; - } -} diff --git a/stub/src/main/java/com/topjohnwu/magisk/obfuscate/Mapping.java b/stub/src/main/java/com/topjohnwu/magisk/obfuscate/Mapping.java deleted file mode 100644 index 95ac2d0cd..000000000 --- a/stub/src/main/java/com/topjohnwu/magisk/obfuscate/Mapping.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.topjohnwu.magisk.obfuscate; - -import java.util.HashMap; -import java.util.Map; - -import static com.topjohnwu.magisk.DynAPK.Data; - -public class Mapping { - private static final int STUB_VERSION = 7; - - private static Map map = new HashMap<>(); - private static Map inverseMap; - - static { - map.put("a.x", "androidx.work.impl.background.systemjob.SystemJobService"); - inverseMap = new HashMap<>(map.size()); - for (Map.Entry e : map.entrySet()) { - inverseMap.put(e.getValue(), e.getKey()); - } - } - - public static String get(String name) { - String n = map.get(name); - return n != null ? n : name; - } - - public static String inverse(String name) { - String n = inverseMap.get(name); - return n != null ? n : name; - } - - public static Data data() { - Data data = new Data(); - data.version = STUB_VERSION; - data.classToComponent = inverseMap; - return data; - } -} diff --git a/stub/src/main/java/com/topjohnwu/magisk/obfuscate/RawData.java b/stub/src/main/java/com/topjohnwu/magisk/obfuscate/RawData.java deleted file mode 100644 index 27ce8cf92..000000000 --- a/stub/src/main/java/com/topjohnwu/magisk/obfuscate/RawData.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.topjohnwu.magisk.obfuscate; - -import android.content.res.Resources; - -import com.topjohnwu.magisk.R; - -public class RawData { - - public static Resources res; - - public static String appName() { - return "Magisk Manager"; - } - - public static String urlBase() { - return "https://raw.githubusercontent.com/topjohnwu/magisk_files/"; - } - - public static String debug() { - return "canary/debug.json"; - } - - public static String canary() { - return "canary/release.json"; - } - - public static String stable() { - return "master/stable.json"; - } - - public static String networkError() { - return res.getString(R.string.no_internet_msg); - } - - public static String upgradeMsg() { - return res.getString(R.string.upgrade_msg); - } - - public static String dling() { - return res.getString(R.string.dling); - } -} diff --git a/stub/src/main/res/values-v28/styles.xml b/stub/src/main/res/values-v28/styles.xml deleted file mode 100644 index 2c3e644c9..000000000 --- a/stub/src/main/res/values-v28/styles.xml +++ /dev/null @@ -1,4 +0,0 @@ - - -