Improve LSPosed support, add more modules config fallback.

pull/110/head
Fox2Code 2 years ago
parent 0f2bb7ba44
commit a5d0c22bc0

@ -154,14 +154,15 @@ public final class ModuleHolder implements Comparable<ModuleHolder> {
public void getButtons(Context context, List<ActionButtonType> buttonTypeList, boolean showcaseMode) {
if (!this.isModuleHolder()) return;
if (this.moduleInfo != null && !showcaseMode) {
LocalModuleInfo localModuleInfo = this.moduleInfo;
if (localModuleInfo != null && !showcaseMode) {
buttonTypeList.add(ActionButtonType.UNINSTALL);
}
if (this.repoModule != null && this.repoModule.notesUrl != null) {
buttonTypeList.add(ActionButtonType.INFO);
}
if ((this.repoModule != null || (this.moduleInfo != null &&
this.moduleInfo.updateZipUrl != null))) {
if ((this.repoModule != null || (localModuleInfo != null &&
localModuleInfo.updateZipUrl != null))) {
buttonTypeList.add(ActionButtonType.UPDATE_INSTALL);
}
String config = this.getMainModuleConfig();
@ -171,7 +172,7 @@ public final class ModuleHolder implements Comparable<ModuleHolder> {
} else {
String pkg = IntentHelper.getPackageOfConfig(config);
try {
context.getPackageManager().getPackageInfo(pkg, 0);
XHooks.checkConfigTargetExists(context, pkg, config);
buttonTypeList.add(ActionButtonType.CONFIG);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Config package \"" + pkg +
@ -180,6 +181,10 @@ public final class ModuleHolder implements Comparable<ModuleHolder> {
}
}
ModuleInfo moduleInfo = this.getMainModuleInfo();
if (moduleInfo == null) { // Avoid concurrency NPE
if (localModuleInfo == null) return;
moduleInfo = localModuleInfo;
}
if (moduleInfo.support != null) {
buttonTypeList.add(ActionButtonType.SUPPORT);
}

@ -186,16 +186,18 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter<ModuleViewAdap
this.creditText.setText((localModuleInfo == null ||
Objects.equals(moduleInfo.version, localModuleInfo.version) ?
moduleInfo.version : localModuleInfo.version + " (" +
this.getString(R.string.module_last_update) +
this.getString(R.string.module_last_update) + " " +
moduleInfo.version + ")") + " " +
this.getString(R.string.module_by) + " " + moduleInfo.author);
} else {
this.creditText.setText(localModuleInfo.version + (
(localModuleInfo.updateVersion != null &&
(localModuleInfo.updateVersion != null && (Objects.equals(
localModuleInfo.version, localModuleInfo.updateVersion) ||
Objects.equals(localModuleInfo.version,
localModuleInfo.updateVersion)) ?
localModuleInfo.updateVersion + " (" +
localModuleInfo.updateVersionCode + ")"))) ?
"" : " (" + this.getString(R.string.module_last_update) +
localModuleInfo.updateVersion + ")") + " " +
" " + localModuleInfo.updateVersion + ")") + " " +
this.getString(R.string.module_by) + " " + localModuleInfo.author);
}
if (moduleInfo.description == null || moduleInfo.description.isEmpty()) {

@ -0,0 +1,41 @@
package com.fox2code.mmm;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.webkit.WebView;
import androidx.annotation.Keep;
import com.fox2code.mmm.manager.ModuleManager;
/**
* Class made to expose some manager functions to xposed modules.
* It will not be obfuscated on release builds
*/
@Keep
public class XHooks {
@Keep
public static boolean isModuleActive(String moduleId) {
return ModuleManager.isModuleActive(moduleId);
}
@Keep
public static void checkConfigTargetExists(Context context, String packageName, String config)
throws PackageManager.NameNotFoundException {
if ("org.lsposed.manager".equals(config) && "org.lsposed.manager".equals(packageName) &&
(XHooks.isModuleActive("riru_lsposed") || XHooks.isModuleActive("zygisk_lsposed")))
return; // Skip check for lsposed as it is probably injected into the system.
context.getPackageManager().getPackageInfo(packageName, 0);
}
@Keep
public static Intent getConfigIntent(Context context, String packageName,String config) {
return context.getPackageManager().getLaunchIntentForPackage(packageName);
}
@Keep
public static void onWebViewInitialize(WebView webView,boolean allowInstall) {
if (webView == null) throw new NullPointerException("WebView is null!");
}
}

@ -26,6 +26,7 @@ import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.Constants;
import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.R;
import com.fox2code.mmm.XHooks;
import com.fox2code.mmm.compat.CompatActivity;
import com.fox2code.mmm.utils.Http;
import com.fox2code.mmm.utils.IntentHelper;
@ -92,7 +93,7 @@ public class AndroidacyActivity extends CompatActivity {
if (config != null && !config.isEmpty()) {
String configPkg = IntentHelper.getPackageOfConfig(config);
try {
this.getPackageManager().getPackageInfo(configPkg, 0);
XHooks.checkConfigTargetExists(this, configPkg, config);
this.setActionBarExtraMenuButton(R.drawable.ic_baseline_app_settings_alt_24,
menu -> {
IntentHelper.openConfig(this, config);
@ -182,6 +183,7 @@ public class AndroidacyActivity extends CompatActivity {
IntentHelper.openCustomTab(this, downloadUrl);
}
});
XHooks.onWebViewInitialize(this.webView, allowInstall);
this.webView.addJavascriptInterface(androidacyWebAPI =
new AndroidacyWebAPI(this, allowInstall), "mmm");
if (compatLevel != 0) androidacyWebAPI.notifyCompatModeRaw(compatLevel);

@ -21,6 +21,7 @@ import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.Constants;
import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.R;
import com.fox2code.mmm.XHooks;
import com.fox2code.mmm.compat.CompatActivity;
import com.fox2code.mmm.utils.FastException;
import com.fox2code.mmm.utils.Files;
@ -567,7 +568,7 @@ public class InstallerActivity extends CompatActivity {
if (config != null && !config.isEmpty()) {
String configPkg = IntentHelper.getPackageOfConfig(config);
try {
this.getPackageManager().getPackageInfo(configPkg, 0);
XHooks.checkConfigTargetExists(this, configPkg, config);
this.setActionBarExtraMenuButton(R.drawable.ic_baseline_app_settings_alt_24, menu -> {
IntentHelper.openConfig(this, config);
return true;

@ -253,4 +253,9 @@ public final class ModuleManager {
moduleInfo.flags = ModuleInfo.FLAG_METADATA_INVALID;
return true;
}
public static boolean isModuleActive(String moduleId) {
ModuleInfo moduleInfo = ModuleManager.getINSTANCE().getModules().get(moduleId);
return moduleInfo != null && (moduleInfo.flags & ModuleInfo.FLAGS_MODULE_ACTIVE) != 0;
}
}

@ -15,6 +15,7 @@ import androidx.annotation.Nullable;
import com.fox2code.mmm.Constants;
import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.R;
import com.fox2code.mmm.XHooks;
import com.fox2code.mmm.compat.CompatActivity;
import com.fox2code.mmm.utils.Http;
import com.fox2code.mmm.utils.IntentHelper;
@ -83,7 +84,7 @@ public class MarkdownActivity extends CompatActivity {
if (config != null && !config.isEmpty()) {
String configPkg = IntentHelper.getPackageOfConfig(config);
try {
this.getPackageManager().getPackageInfo(configPkg, 0);
XHooks.checkConfigTargetExists(this, configPkg, config);
this.setActionBarExtraMenuButton(R.drawable.ic_baseline_app_settings_alt_24, menu -> {
IntentHelper.openConfig(this, config);
return true;

@ -22,10 +22,15 @@ import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.Constants;
import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.R;
import com.fox2code.mmm.XHooks;
import com.fox2code.mmm.androidacy.AndroidacyActivity;
import com.fox2code.mmm.compat.CompatActivity;
import com.fox2code.mmm.installer.InstallerActivity;
import com.fox2code.mmm.markdown.MarkdownActivity;
import com.topjohnwu.superuser.CallbackList;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils;
import com.topjohnwu.superuser.internal.Utils;
import com.topjohnwu.superuser.io.SuFileInputStream;
import java.io.File;
@ -33,6 +38,8 @@ import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
public class IntentHelper {
private static final String TAG = "IntentHelper";
@ -128,9 +135,23 @@ public class IntentHelper {
public static void openConfig(Context context, String config) {
String pkg = getPackageOfConfig(config);
try {
Intent intent = context.getPackageManager()
.getLaunchIntentForPackage(pkg);
Intent intent = XHooks.getConfigIntent(context, pkg, config);
if (intent == null) {
if ("org.lsposed.manager".equals(config) && (
XHooks.isModuleActive("riru_lsposed") ||
XHooks.isModuleActive("zygisk_lsposed"))) {
Shell.getShell().newJob().add(
"am start -a android.intent.action.MAIN " +
"-c org.lsposed.manager.LAUNCH_MANAGER " +
"com.android.shell/.BugreportWarningActivity")
.to(new CallbackList<String>() {
@Override
public void onAddElement(String str) {
Log.d(TAG, "LSPosed: " + str);
}
}).submit();
return;
}
intent = new Intent("android.intent.action.APPLICATION_PREFERENCES");
intent.setPackage(pkg);
}

@ -45,8 +45,10 @@ public class PropUtils {
moduleSupportsFallbacks.put("substratum", "https://github.com/substratum/substratum/issues");
// Config are application installed by modules that allow them to be configured
moduleConfigsFallbacks.put("quickstepswitcher", "xyz.paphonb.quickstepswitcher");
moduleConfigsFallbacks.put("hex_installer_module", "project.vivid.hex.bodhi");
moduleConfigsFallbacks.put("riru_edxposed", "org.meowcat.edxposed.manager");
moduleConfigsFallbacks.put("riru_lsposed", "org.lsposed.manager");
moduleConfigsFallbacks.put("zygisk_lsposed", "org.lsposed.manager");
moduleConfigsFallbacks.put("xposed_dalvik", "de.robv.android.xposed.installer");
moduleConfigsFallbacks.put("xposed", "de.robv.android.xposed.installer");
moduleConfigsFallbacks.put("substratum", "projekt.substratum");

Loading…
Cancel
Save