Adapt to new EdXposed
This commit is contained in:
parent
b6bdfe508e
commit
abc3598881
|
|
@ -19,6 +19,5 @@
|
|||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
-keep class org.meowcat.edxposed.manager.util.json.**{public *; }
|
||||
-keep class org.meowcat.edxposed.manager.xposed.**{ *; }
|
||||
-keep class de.robv.android.xposed.installer.**{public *; }
|
||||
-keep class org.meowcat.edxposed.manager.util.json.** {public *; }
|
||||
-keep class org.meowcat.edxposed.manager.Constants { *; }
|
||||
|
|
@ -97,18 +97,6 @@
|
|||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<meta-data
|
||||
android:name="xposedmodule"
|
||||
android:value="true" />
|
||||
|
||||
<meta-data
|
||||
android:name="xposeddescription"
|
||||
android:value="@string/xposed_description" />
|
||||
|
||||
<meta-data
|
||||
android:name="xposedminversion"
|
||||
android:value="82" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -1 +0,0 @@
|
|||
org.meowcat.edxposed.manager.xposed.Enhancement
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
package de.robv.android.xposed.installer;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.robv.android.xposed.installer.util.InstallZipUtil;
|
||||
|
||||
import static de.robv.android.xposed.installer.util.InstallZipUtil.parseXposedProp;
|
||||
|
||||
@SuppressLint("Registered")
|
||||
public class XposedApp extends Application {
|
||||
public static final String TAG = "EdXposedManager";
|
||||
private static final File EDXPOSED_PROP_FILE = new File("/system/framework/edconfig.jar");
|
||||
public InstallZipUtil.XposedProp mXposedProp;
|
||||
|
||||
public static boolean isEnhancementEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This method is hooked by XposedBridge to return the current version
|
||||
public static Integer getActiveXposedVersion() {
|
||||
Log.d(TAG, "EdXposed is not active");
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
reloadXposedProp();
|
||||
}
|
||||
|
||||
// This method is hooked by XposedBridge
|
||||
public void reloadXposedProp() {
|
||||
InstallZipUtil.XposedProp prop = null;
|
||||
File file = null;
|
||||
|
||||
if (EDXPOSED_PROP_FILE.canRead()) {
|
||||
file = EDXPOSED_PROP_FILE;
|
||||
}
|
||||
|
||||
if (file != null) {
|
||||
try (FileInputStream is = new FileInputStream(file)) {
|
||||
prop = parseXposedProp(is);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not read " + file.getPath(), e);
|
||||
}
|
||||
}
|
||||
synchronized (this) {
|
||||
mXposedProp = prop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
package de.robv.android.xposed.installer.util;
|
||||
|
||||
import org.meowcat.edxposed.manager.util.ModuleUtil;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public final class InstallZipUtil {
|
||||
|
||||
public static XposedProp parseXposedProp(InputStream is) throws IOException {
|
||||
XposedProp prop = new XposedProp();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
String[] parts = line.split("=", 2);
|
||||
if (parts.length != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = parts[0].trim();
|
||||
if (key.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
String value = parts[1].trim();
|
||||
|
||||
if ("version".equals(key)) {
|
||||
prop.mVersion = value;
|
||||
prop.mVersionInt = ModuleUtil.extractIntPart(value);
|
||||
}
|
||||
}
|
||||
reader.close();
|
||||
return prop.isComplete() ? prop : null;
|
||||
}
|
||||
|
||||
public static class XposedProp {
|
||||
private String mVersion = null;
|
||||
private int mVersionInt = 0;
|
||||
|
||||
private boolean isComplete() {
|
||||
return mVersion != null
|
||||
&& mVersionInt > 0;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return mVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,12 +35,8 @@ import java.util.Collection;
|
|||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import de.robv.android.xposed.installer.XposedApp;
|
||||
import de.robv.android.xposed.installer.util.InstallZipUtil;
|
||||
|
||||
public class App extends XposedApp implements Application.ActivityLifecycleCallbacks {
|
||||
public static String BASE_DIR = null;
|
||||
public static String ENABLED_MODULES_LIST_FILE = null;
|
||||
public class App extends Application implements Application.ActivityLifecycleCallbacks {
|
||||
public static final String TAG = "EdXposedManager";
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static App instance = null;
|
||||
private static Thread uiThread;
|
||||
|
|
@ -53,10 +49,6 @@ public class App extends XposedApp implements Application.ActivityLifecycleCallb
|
|||
return instance;
|
||||
}
|
||||
|
||||
public static InstallZipUtil.XposedProp getXposedProp() {
|
||||
return getInstance().mXposedProp;
|
||||
}
|
||||
|
||||
public static void runOnUiThread(Runnable action) {
|
||||
if (Thread.currentThread() != uiThread) {
|
||||
mainHandler.post(action);
|
||||
|
|
@ -70,14 +62,14 @@ public class App extends XposedApp implements Application.ActivityLifecycleCallb
|
|||
}
|
||||
|
||||
public static void mkdirAndChmod(String dir, int permissions) {
|
||||
dir = BASE_DIR + dir;
|
||||
dir = Constants.getBaseDir() + dir;
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
new File(dir).mkdir();
|
||||
FileUtils.setPermissions(dir, permissions);
|
||||
}
|
||||
|
||||
public static boolean supportScope() {
|
||||
return App.getActiveXposedVersion() >= 92;
|
||||
return Constants.getXposedApiVersion() >= 92;
|
||||
}
|
||||
|
||||
public void onCreate() {
|
||||
|
|
@ -111,11 +103,6 @@ public class App extends XposedApp implements Application.ActivityLifecycleCallb
|
|||
}
|
||||
}
|
||||
|
||||
final ApplicationInfo appInfo = getApplicationInfo();
|
||||
BASE_DIR = appInfo.deviceProtectedDataDir + "/";
|
||||
ENABLED_MODULES_LIST_FILE = BASE_DIR + "conf/enabled_modules.list";
|
||||
ModuleUtil.MODULES_LIST_FILE = BASE_DIR + "conf/modules.list";
|
||||
|
||||
instance = this;
|
||||
uiThread = Thread.currentThread();
|
||||
mainHandler = new Handler();
|
||||
|
|
@ -158,7 +145,7 @@ public class App extends XposedApp implements Application.ActivityLifecycleCallb
|
|||
@SuppressWarnings({"OctalInteger"})
|
||||
@SuppressLint({"PrivateApi", "NewApi"})
|
||||
private void createDirectories() {
|
||||
FileUtils.setPermissions(BASE_DIR, 00777);
|
||||
FileUtils.setPermissions(Constants.getBaseDir(), 00777);
|
||||
mkdirAndChmod("conf", 00777);
|
||||
mkdirAndChmod("log", 00777);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package org.meowcat.edxposed.manager;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class Constants {
|
||||
public static int getXposedApiVersion() {
|
||||
Log.e(App.TAG, "getXposedApiVersion: Xposed is not active");
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static String getXposedVersion() {
|
||||
Log.e(App.TAG, "getXposedVersion: Xposed is not active");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getXposedVersionCode() {
|
||||
Log.e(App.TAG, "getXposedVersionCode: Xposed is not active");
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static String getXposedVariant() {
|
||||
Log.e(App.TAG, "getXposedVariant: Xposed is not active");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getEnabledModulesListFile() {
|
||||
return getBaseDir() + "conf/enabled_modules.list";
|
||||
}
|
||||
|
||||
public static String getModulesListFile() {
|
||||
return getBaseDir() + "conf/modules.list";
|
||||
}
|
||||
|
||||
public static String getBaseDir() {
|
||||
return App.getInstance().getApplicationInfo().deviceProtectedDataDir + "/";
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ import androidx.fragment.app.FragmentManager;
|
|||
|
||||
import org.meowcat.edxposed.manager.App;
|
||||
import org.meowcat.edxposed.manager.BuildConfig;
|
||||
import org.meowcat.edxposed.manager.Constants;
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.util.CompileUtil;
|
||||
import org.meowcat.edxposed.manager.util.FileUtils;
|
||||
|
|
@ -30,7 +31,6 @@ import java.io.FileWriter;
|
|||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
|
@ -41,9 +41,7 @@ import static android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS;
|
|||
@SuppressWarnings("deprecation")
|
||||
public class AppHelper {
|
||||
|
||||
public static final String TAG = App.TAG;
|
||||
|
||||
private static final String BASE_PATH = App.BASE_DIR;
|
||||
private static final String BASE_PATH = Constants.getBaseDir();
|
||||
private static final String WHITE_LIST_PATH = "conf/whitelist/";
|
||||
private static final String BLACK_LIST_PATH = "conf/blacklist/";
|
||||
private static final String COMPAT_LIST_PATH = "conf/compatlist/";
|
||||
|
|
@ -51,7 +49,7 @@ public class AppHelper {
|
|||
private static final String WHITE_LIST_MODE = "conf/usewhitelist";
|
||||
private static final String BLACK_LIST_MODE = "conf/blackwhitelist";
|
||||
|
||||
private static final List<String> FORCE_WHITE_LIST = new ArrayList<>(App.isEnhancementEnabled() ? Arrays.asList(BuildConfig.APPLICATION_ID, "android") : Collections.singletonList(BuildConfig.APPLICATION_ID));
|
||||
private static final List<String> FORCE_WHITE_LIST = new ArrayList<>(Collections.singletonList(BuildConfig.APPLICATION_ID));
|
||||
public static List<String> FORCE_WHITE_LIST_MODULE = new ArrayList<>(FORCE_WHITE_LIST);
|
||||
|
||||
private static final HashMap<String, List<String>> scopeList = new HashMap<>();
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.google.android.material.tabs.TabLayout;
|
|||
|
||||
import org.meowcat.edxposed.manager.App;
|
||||
import org.meowcat.edxposed.manager.BuildConfig;
|
||||
import org.meowcat.edxposed.manager.Constants;
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityLogsBinding;
|
||||
import org.meowcat.edxposed.manager.databinding.DialogInstallWarningBinding;
|
||||
|
|
@ -44,11 +45,11 @@ import java.util.Scanner;
|
|||
|
||||
public class LogsActivity extends BaseActivity {
|
||||
private boolean allLog = false;
|
||||
private final File fileErrorLog = new File(App.BASE_DIR + "log/error.log");
|
||||
private final File fileErrorLog = new File(Constants.getBaseDir() + "log/error.log");
|
||||
private final File fileErrorLogOld = new File(
|
||||
App.BASE_DIR + "log/error.log.old");
|
||||
private final File fileAllLog = new File(App.BASE_DIR + "log/all.log");
|
||||
private final File fileAllLogOld = new File(App.BASE_DIR + "log/all.log.old");
|
||||
Constants.getBaseDir() + "log/error.log.old");
|
||||
private final File fileAllLog = new File(Constants.getBaseDir() + "log/all.log");
|
||||
private final File fileAllLogOld = new File(Constants.getBaseDir() + "log/all.log.old");
|
||||
private LogsAdapter adapter;
|
||||
private final Handler handler = new Handler();
|
||||
private ActivityLogsBinding binding;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.core.content.ContextCompat;
|
|||
import com.bumptech.glide.Glide;
|
||||
|
||||
import org.meowcat.edxposed.manager.App;
|
||||
import org.meowcat.edxposed.manager.Constants;
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.adapters.AppHelper;
|
||||
import org.meowcat.edxposed.manager.adapters.BlackListAdapter;
|
||||
|
|
@ -86,18 +87,11 @@ public class MainActivity extends BaseActivity implements RepoLoader.RepoListene
|
|||
Glide.with(binding.appIcon)
|
||||
.load(GlideHelper.wrapApplicationInfoForIconLoader(getApplicationInfo()))
|
||||
.into(binding.appIcon);
|
||||
String installedXposedVersion;
|
||||
try {
|
||||
installedXposedVersion = App.getXposedProp().getVersion();
|
||||
} catch (NullPointerException e) {
|
||||
installedXposedVersion = null;
|
||||
}
|
||||
String installedXposedVersion = Constants.getXposedVersion();
|
||||
if (installedXposedVersion != null) {
|
||||
int installedXposedVersionInt = extractIntPart(installedXposedVersion);
|
||||
if (App.getActiveXposedVersion() != -1) {
|
||||
String installedXposedVersionStr = installedXposedVersionInt + ".0";
|
||||
if (Constants.getXposedApiVersion() != -1) {
|
||||
binding.statusTitle.setText(R.string.Activated);
|
||||
binding.statusSummary.setText(installedXposedVersion.replace(installedXposedVersionStr + "-", ""));
|
||||
binding.statusSummary.setText(installedXposedVersion + " (" + Constants.getXposedVariant() + ")");
|
||||
binding.status.setCardBackgroundColor(ContextCompat.getColor(this, R.color.download_status_update_available));
|
||||
binding.statusIcon.setImageResource(R.drawable.ic_check_circle);
|
||||
} else {
|
||||
|
|
@ -106,9 +100,9 @@ public class MainActivity extends BaseActivity implements RepoLoader.RepoListene
|
|||
binding.status.setCardBackgroundColor(ContextCompat.getColor(this, R.color.amber_500));
|
||||
binding.statusIcon.setImageResource(R.drawable.ic_warning);
|
||||
}
|
||||
} else if (App.getActiveXposedVersion() > 0) {
|
||||
} else if (Constants.getXposedApiVersion() > 0) {
|
||||
binding.statusTitle.setText(R.string.Activated);
|
||||
binding.statusSummary.setText(getString(R.string.version_x, App.getActiveXposedVersion()));
|
||||
binding.statusSummary.setText(getString(R.string.version_x, Constants.getXposedApiVersion()));
|
||||
binding.status.setCardBackgroundColor(ContextCompat.getColor(this, R.color.download_status_update_available));
|
||||
binding.statusIcon.setImageResource(R.drawable.ic_check_circle);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import com.google.android.material.snackbar.Snackbar;
|
|||
|
||||
import org.meowcat.edxposed.manager.App;
|
||||
import org.meowcat.edxposed.manager.BuildConfig;
|
||||
import org.meowcat.edxposed.manager.Constants;
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityModulesBinding;
|
||||
import org.meowcat.edxposed.manager.repo.Module;
|
||||
|
|
@ -191,7 +192,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
pm = getPackageManager();
|
||||
displayNameComparator = new ApplicationInfo.DisplayNameComparator(pm);
|
||||
cmp = displayNameComparator;
|
||||
installedXposedVersion = App.getActiveXposedVersion();
|
||||
installedXposedVersion = Constants.getXposedApiVersion();
|
||||
if (installedXposedVersion <= 0) {
|
||||
Snackbar.make(binding.snackbar, R.string.xposed_not_active, Snackbar.LENGTH_LONG).setAction(R.string.Settings, v -> {
|
||||
Intent intent = new Intent();
|
||||
|
|
@ -246,7 +247,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
return;
|
||||
}
|
||||
if (requestCode == 42) {
|
||||
File listModules = new File(App.ENABLED_MODULES_LIST_FILE);
|
||||
File listModules = new File(Constants.getEnabledModulesListFile());
|
||||
if (data != null) {
|
||||
Uri uri = data.getData();
|
||||
if (uri != null) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import com.takisoft.preferencex.PreferenceFragmentCompat;
|
|||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import org.meowcat.edxposed.manager.App;
|
||||
import org.meowcat.edxposed.manager.Constants;
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.adapters.AppHelper;
|
||||
import org.meowcat.edxposed.manager.adapters.BlackListAdapter;
|
||||
|
|
@ -114,18 +115,15 @@ public class SettingsActivity extends BaseActivity {
|
|||
|
||||
@SuppressWarnings({"ResultOfMethodCallIgnored", "deprecation"})
|
||||
public static class SettingsFragment extends PreferenceFragmentCompat {
|
||||
private static final File pretendXposedInstallerFlag = new File(App.BASE_DIR + "conf/pretend_xposed_installer");
|
||||
private static final File hideEdXposedManagerFlag = new File(App.BASE_DIR + "conf/hide_edxposed_manager");
|
||||
private static final File disableHiddenAPIBypassFlag = new File(App.BASE_DIR + "conf/disable_hidden_api_bypass");
|
||||
private static final File disableResourcesFlag = new File(App.BASE_DIR + "conf/disable_resources");
|
||||
private static final File dynamicModulesFlag = new File(App.BASE_DIR + "conf/dynamicmodules");
|
||||
private static final File deoptBootFlag = new File(App.BASE_DIR + "conf/deoptbootimage");
|
||||
private static final File whiteListModeFlag = new File(App.BASE_DIR + "conf/usewhitelist");
|
||||
private static final File blackWhiteListModeFlag = new File(App.BASE_DIR + "conf/blackwhitelist");
|
||||
private static final File disableVerboseLogsFlag = new File(App.BASE_DIR + "conf/disable_verbose_log");
|
||||
private static final File disableModulesLogsFlag = new File(App.BASE_DIR + "conf/disable_modules_log");
|
||||
private static final File verboseLogProcessID = new File(App.BASE_DIR + "log/all.pid");
|
||||
private static final File modulesLogProcessID = new File(App.BASE_DIR + "log/error.pid");
|
||||
private static final File disableResourcesFlag = new File(Constants.getBaseDir() + "conf/disable_resources");
|
||||
private static final File dynamicModulesFlag = new File(Constants.getBaseDir() + "conf/dynamicmodules");
|
||||
private static final File deoptBootFlag = new File(Constants.getBaseDir() + "conf/deoptbootimage");
|
||||
private static final File whiteListModeFlag = new File(Constants.getBaseDir() + "conf/usewhitelist");
|
||||
private static final File blackWhiteListModeFlag = new File(Constants.getBaseDir() + "conf/blackwhitelist");
|
||||
private static final File disableVerboseLogsFlag = new File(Constants.getBaseDir() + "conf/disable_verbose_log");
|
||||
private static final File disableModulesLogsFlag = new File(Constants.getBaseDir() + "conf/disable_modules_log");
|
||||
private static final File verboseLogProcessID = new File(Constants.getBaseDir() + "log/all.pid");
|
||||
private static final File modulesLogProcessID = new File(Constants.getBaseDir() + "log/error.pid");
|
||||
|
||||
@SuppressLint({"WorldReadableFiles", "WorldWriteableFiles"})
|
||||
static void setFilePermissionsFromMode(String name) {
|
||||
|
|
@ -492,105 +490,6 @@ public class SettingsActivity extends BaseActivity {
|
|||
return true;
|
||||
});
|
||||
updatePreference(!md2.isChecked());
|
||||
|
||||
Preference enhancement_status = findPreference("enhancement_status");
|
||||
Objects.requireNonNull(enhancement_status).setSummary(App.isEnhancementEnabled() ? R.string.settings_summary_enhancement_enabled : R.string.settings_summary_enhancement);
|
||||
SwitchPreferenceCompat prefPretendXposedInstaller = findPreference("pretend_xposed_installer");
|
||||
|
||||
Objects.requireNonNull(prefPretendXposedInstaller).setChecked(pretendXposedInstallerFlag.exists());
|
||||
prefPretendXposedInstaller.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
new BlackListAdapter(getContext(), AppHelper.isWhiteListMode()).generateCheckedList();
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(pretendXposedInstallerFlag.getPath());
|
||||
setFilePermissionsFromMode(pretendXposedInstallerFlag.getPath());
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
pretendXposedInstallerFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pretendXposedInstallerFlag.delete();
|
||||
}
|
||||
return (enabled == pretendXposedInstallerFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefHideEdXposedManager = findPreference("hide_edxposed_manager");
|
||||
Objects.requireNonNull(prefHideEdXposedManager).setChecked(hideEdXposedManagerFlag.exists());
|
||||
prefHideEdXposedManager.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
new BlackListAdapter(getContext(), AppHelper.isWhiteListMode()).generateCheckedList();
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(hideEdXposedManagerFlag.getPath());
|
||||
setFilePermissionsFromMode(hideEdXposedManagerFlag.getPath());
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
hideEdXposedManagerFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hideEdXposedManagerFlag.delete();
|
||||
}
|
||||
return (enabled == hideEdXposedManagerFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefDisableHiddenAPIBypass = findPreference("disable_hidden_api_bypass");
|
||||
Objects.requireNonNull(prefDisableHiddenAPIBypass).setChecked(disableHiddenAPIBypassFlag.exists());
|
||||
prefDisableHiddenAPIBypass.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(disableHiddenAPIBypassFlag.getPath());
|
||||
setFilePermissionsFromMode(disableHiddenAPIBypassFlag.getPath());
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
disableHiddenAPIBypassFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
disableHiddenAPIBypassFlag.delete();
|
||||
}
|
||||
return (enabled == disableHiddenAPIBypassFlag.exists());
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|||
|
||||
import org.meowcat.edxposed.manager.App;
|
||||
import org.meowcat.edxposed.manager.BuildConfig;
|
||||
import org.meowcat.edxposed.manager.Constants;
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.databinding.StatusInstallerBinding;
|
||||
|
||||
|
|
@ -99,25 +100,12 @@ public class StatusInstallerFragment extends Fragment {
|
|||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = StatusInstallerBinding.inflate(inflater, container, false);
|
||||
|
||||
String installedXposedVersion;
|
||||
try {
|
||||
installedXposedVersion = App.getXposedProp().getVersion();
|
||||
} catch (NullPointerException e) {
|
||||
installedXposedVersion = null;
|
||||
}
|
||||
|
||||
String mAppVer;
|
||||
if (App.isEnhancementEnabled()) {
|
||||
mAppVer = String.format("v%s (%s) (%s)", BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, getString(R.string.status_enhancement));
|
||||
} else {
|
||||
mAppVer = String.format("v%s (%s)", BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE);
|
||||
}
|
||||
String installedXposedVersion = Constants.getXposedVersion();
|
||||
String mAppVer = String.format("v%s (%s)", BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE);
|
||||
binding.manager.setText(mAppVer);
|
||||
if (installedXposedVersion != null) {
|
||||
int installedXposedVersionInt = extractIntPart(installedXposedVersion);
|
||||
String installedXposedVersionStr = installedXposedVersionInt + ".0";
|
||||
binding.api.setText(installedXposedVersionStr);
|
||||
binding.framework.setText(installedXposedVersion.replace(installedXposedVersionStr + "-", ""));
|
||||
binding.api.setText(Constants.getXposedApiVersion() + ".0");
|
||||
binding.framework.setText(installedXposedVersion + " (" + Constants.getXposedVariant() + ")");
|
||||
}
|
||||
|
||||
binding.androidVersion.setText(getString(R.string.android_sdk, getAndroidVersion(), Build.VERSION.RELEASE, Build.VERSION.SDK_INT));
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import androidx.annotation.NonNull;
|
|||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.meowcat.edxposed.manager.App;
|
||||
import org.meowcat.edxposed.manager.Constants;
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityModulesBinding;
|
||||
import org.meowcat.edxposed.manager.repo.ModuleVersion;
|
||||
|
|
@ -32,7 +33,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
public final class ModuleUtil {
|
||||
private static final String PLAY_STORE_PACKAGE = "com.android.vending";
|
||||
// xposedminversion below this
|
||||
public static String MODULES_LIST_FILE = App.BASE_DIR + "conf/modules.list";
|
||||
public static int MIN_MODULE_VERSION = 2; // reject modules with
|
||||
private static ModuleUtil instance = null;
|
||||
private final PackageManager pm;
|
||||
|
|
@ -212,7 +212,7 @@ public final class ModuleUtil {
|
|||
public synchronized void updateModulesList(boolean showToast, ActivityModulesBinding binding) {
|
||||
try {
|
||||
Log.i(App.TAG, "ModuleUtil -> updating modules.list");
|
||||
int installedXposedVersion = App.getActiveXposedVersion();
|
||||
int installedXposedVersion = Constants.getXposedApiVersion();
|
||||
if (!App.getPreferences().getBoolean("skip_xposedminversion_check", false) && installedXposedVersion <= 0 && showToast) {
|
||||
if (binding != null) {
|
||||
Snackbar.make(binding.snackbar, R.string.notinstalled, Snackbar.LENGTH_SHORT).show();
|
||||
|
|
@ -222,8 +222,8 @@ public final class ModuleUtil {
|
|||
return;
|
||||
}
|
||||
|
||||
PrintWriter modulesList = new PrintWriter(MODULES_LIST_FILE);
|
||||
PrintWriter enabledModulesList = new PrintWriter(App.ENABLED_MODULES_LIST_FILE);
|
||||
PrintWriter modulesList = new PrintWriter(Constants.getModulesListFile());
|
||||
PrintWriter enabledModulesList = new PrintWriter(Constants.getEnabledModulesListFile());
|
||||
List<InstalledModule> enabledModules = getEnabledModules();
|
||||
for (InstalledModule module : enabledModules) {
|
||||
|
||||
|
|
@ -248,8 +248,8 @@ public final class ModuleUtil {
|
|||
modulesList.close();
|
||||
enabledModulesList.close();
|
||||
|
||||
FileUtils.setPermissions(MODULES_LIST_FILE, 00664);
|
||||
FileUtils.setPermissions(App.ENABLED_MODULES_LIST_FILE, 00664);
|
||||
FileUtils.setPermissions(Constants.getEnabledModulesListFile(), 00664);
|
||||
FileUtils.setPermissions(Constants.getEnabledModulesListFile(), 00664);
|
||||
|
||||
if (showToast) {
|
||||
if (binding != null) {
|
||||
|
|
@ -259,11 +259,11 @@ public final class ModuleUtil {
|
|||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(App.TAG, "ModuleUtil -> cannot write " + MODULES_LIST_FILE, e);
|
||||
Log.e(App.TAG, "ModuleUtil -> cannot write " + Constants.getModulesListFile(), e);
|
||||
if (binding != null) {
|
||||
Snackbar.make(binding.snackbar, "cannot write " + MODULES_LIST_FILE + e, Snackbar.LENGTH_SHORT).show();
|
||||
Snackbar.make(binding.snackbar, "cannot write " + Constants.getModulesListFile() + e, Snackbar.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(App.getInstance(), "cannot write " + MODULES_LIST_FILE + e, Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(App.getInstance(), "cannot write " + Constants.getModulesListFile() + e, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -332,7 +332,7 @@ public final class ModuleUtil {
|
|||
this.minVersion = 0;
|
||||
this.description = "";
|
||||
} else {
|
||||
int version = App.getActiveXposedVersion();
|
||||
int version = Constants.getXposedApiVersion();
|
||||
if (version > 0 && App.getPreferences().getBoolean("skip_xposedminversion_check", false)) {
|
||||
this.minVersion = version;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,354 +0,0 @@
|
|||
package org.meowcat.edxposed.manager.xposed;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.FileObserver;
|
||||
import android.os.StrictMode;
|
||||
import android.os.UserHandle;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage;
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XC_MethodReplacement;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
import de.robv.android.xposed.installer.XposedApp;
|
||||
|
||||
import static de.robv.android.xposed.XposedHelpers.callMethod;
|
||||
import static de.robv.android.xposed.XposedHelpers.callStaticMethod;
|
||||
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
|
||||
import static java.util.Collections.binarySearch;
|
||||
import static org.meowcat.edxposed.manager.BuildConfig.APPLICATION_ID;
|
||||
|
||||
@Keep
|
||||
public class Enhancement implements IXposedHookLoadPackage {
|
||||
|
||||
private static final String mPretendXposedInstallerFlag = "pretend_xposed_installer";
|
||||
private static final String mHideEdXposedManagerFlag = "hide_edxposed_manager";
|
||||
|
||||
private static final String LEGACY_INSTALLER = "de.robv.android.xposed.installer";
|
||||
|
||||
private static final List<String> HIDE_WHITE_LIST = Arrays.asList( // TODO: more whitelist packages
|
||||
APPLICATION_ID, // Whitelist or crash
|
||||
LEGACY_INSTALLER, // for safety
|
||||
"com.android.providers.downloads", // For download modules
|
||||
"com.android.providers.downloads.ui",
|
||||
"com.android.packageinstaller", // For uninstall EdXposed Manager
|
||||
"com.google.android.packageinstaller",
|
||||
"com.android.systemui", // For notifications
|
||||
"com.android.permissioncontroller", // For permissions grant
|
||||
"com.topjohnwu.magisk", // For superuser root grant
|
||||
"eu.chainfire.supersu"
|
||||
); // UserHandle.isCore(uid) will auto pass
|
||||
|
||||
private static final SparseArray<List<String>> modulesList = new SparseArray<>();
|
||||
private static final SparseArray<FileObserver> modulesListObservers = new SparseArray<>();
|
||||
|
||||
static {
|
||||
Collections.sort(HIDE_WHITE_LIST);
|
||||
}
|
||||
|
||||
private static boolean getFlagState(int user, String flag) {
|
||||
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
|
||||
try {
|
||||
return new File(String.format("/data/user_de/%s/%s/conf/%s", user, APPLICATION_ID, flag)).exists();
|
||||
} finally {
|
||||
StrictMode.setThreadPolicy(oldPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> getModulesList(final int user) {
|
||||
final int index = modulesList.indexOfKey(user);
|
||||
if (index >= 0) {
|
||||
return modulesList.valueAt(index);
|
||||
}
|
||||
|
||||
final String filename = String.format("/data/user_de/%s/%s/conf/enabled_modules.list", user, APPLICATION_ID);
|
||||
final FileObserver observer = new FileObserver(filename) {
|
||||
@Override
|
||||
public void onEvent(int event, @Nullable String path) {
|
||||
switch (event) {
|
||||
case FileObserver.MODIFY:
|
||||
modulesList.put(user, readModulesList(filename));
|
||||
break;
|
||||
case FileObserver.MOVED_FROM:
|
||||
case FileObserver.MOVED_TO:
|
||||
case FileObserver.MOVE_SELF:
|
||||
case FileObserver.DELETE:
|
||||
case FileObserver.DELETE_SELF:
|
||||
modulesList.remove(user);
|
||||
modulesListObservers.remove(user);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
modulesListObservers.put(user, observer);
|
||||
final List<String> list = readModulesList(filename);
|
||||
modulesList.put(user, list);
|
||||
observer.startWatching();
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<String> readModulesList(final String filename) {
|
||||
XposedBridge.log("EdXposedManager: Reading modules list " + filename + "...");
|
||||
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
|
||||
try {
|
||||
final File listFile = new File(filename);
|
||||
final List<String> list = new ArrayList<>();
|
||||
try {
|
||||
final FileReader fileReader = new FileReader(listFile);
|
||||
final BufferedReader bufferedReader = new BufferedReader(fileReader);
|
||||
String str;
|
||||
while ((str = bufferedReader.readLine()) != null) {
|
||||
list.add(str);
|
||||
}
|
||||
bufferedReader.close();
|
||||
fileReader.close();
|
||||
} catch (IOException e) {
|
||||
XposedBridge.log(e);
|
||||
}
|
||||
Collections.sort(list);
|
||||
return list;
|
||||
} finally {
|
||||
StrictMode.setThreadPolicy(oldPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
private static void hookAllMethods(String className, ClassLoader classLoader, String methodName, XC_MethodHook callback) {
|
||||
try {
|
||||
final Class<?> hookClass = XposedHelpers.findClassIfExists(className, classLoader);
|
||||
if (hookClass == null || XposedBridge.hookAllMethods(hookClass, methodName, callback).size() == 0)
|
||||
XposedBridge.log("Failed to hook " + methodName + " method in " + className);
|
||||
} catch (Throwable t) {
|
||||
XposedBridge.log(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
|
||||
if (lpparam.packageName.equals("android")) {
|
||||
// com.android.server.pm.PackageManagerService.getInstalledApplications(int flag, int userId)
|
||||
findAndHookMethod("com.android.server.pm.PackageManagerService", lpparam.classLoader, "getInstalledApplications", int.class, int.class, new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) {
|
||||
if (param.args != null && param.args[0] != null) {
|
||||
final int packageUid = Binder.getCallingUid();
|
||||
if ((boolean) callStaticMethod(UserHandle.class, "isCore", packageUid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int userId = (int) param.args[1];
|
||||
boolean isXposedModule = false;
|
||||
final String[] packages = (String[]) callMethod(param.thisObject, "getPackagesForUid", packageUid);
|
||||
if (packages == null || packages.length == 0) {
|
||||
return;
|
||||
}
|
||||
for (String packageName : packages) {
|
||||
if (binarySearch(HIDE_WHITE_LIST, packageName) >= 0) {
|
||||
return;
|
||||
}
|
||||
if (binarySearch(getModulesList(userId), packageName) >= 0) {
|
||||
isXposedModule = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") final List<ApplicationInfo> applicationInfoList = (List<ApplicationInfo>) callMethod(param.getResult(), "getList");
|
||||
if (isXposedModule) {
|
||||
if (getFlagState(userId, mPretendXposedInstallerFlag)) {
|
||||
for (ApplicationInfo applicationInfo : applicationInfoList) {
|
||||
if (applicationInfo.packageName.equals(APPLICATION_ID)) {
|
||||
applicationInfo.packageName = LEGACY_INSTALLER;
|
||||
applicationInfoList.add(applicationInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (getFlagState(userId, mHideEdXposedManagerFlag)) {
|
||||
for (ApplicationInfo applicationInfo : applicationInfoList) {
|
||||
if (applicationInfo.packageName.equals(APPLICATION_ID) || applicationInfo.packageName.equals(LEGACY_INSTALLER)) {
|
||||
applicationInfoList.remove(applicationInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
param.setResult(param.getResult()); // "reset" the result to indicate that we handled it
|
||||
}
|
||||
}
|
||||
});
|
||||
// com.android.server.pm.PackageManagerService.getInstalledPackages(int flag, int userId)
|
||||
findAndHookMethod("com.android.server.pm.PackageManagerService", lpparam.classLoader, "getInstalledPackages", int.class, int.class, new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) {
|
||||
if (param.args != null && param.args[0] != null) {
|
||||
final int packageUid = Binder.getCallingUid();
|
||||
if ((boolean) callStaticMethod(UserHandle.class, "isCore", packageUid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int userId = (int) param.args[1];
|
||||
boolean isXposedModule = false;
|
||||
final String[] packages = (String[]) callMethod(param.thisObject, "getPackagesForUid", packageUid);
|
||||
if (packages == null || packages.length == 0) {
|
||||
return;
|
||||
}
|
||||
for (String packageName : packages) {
|
||||
if (binarySearch(HIDE_WHITE_LIST, packageName) >= 0) {
|
||||
return;
|
||||
}
|
||||
if (binarySearch(getModulesList(userId), packageName) >= 0) {
|
||||
isXposedModule = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") final List<PackageInfo> packageInfoList = (List<PackageInfo>) callMethod(param.getResult(), "getList");
|
||||
if (isXposedModule) {
|
||||
if (getFlagState(userId, mPretendXposedInstallerFlag)) {
|
||||
for (PackageInfo packageInfo : packageInfoList) {
|
||||
if (packageInfo.packageName.equals(APPLICATION_ID)) {
|
||||
packageInfo.packageName = LEGACY_INSTALLER;
|
||||
packageInfoList.add(packageInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (getFlagState(userId, mHideEdXposedManagerFlag)) {
|
||||
for (PackageInfo packageInfo : packageInfoList) {
|
||||
if (packageInfo.packageName.equals(APPLICATION_ID) || packageInfo.packageName.equals(LEGACY_INSTALLER)) {
|
||||
packageInfoList.remove(packageInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
param.setResult(param.getResult()); // "reset" the result to indicate that we handled it
|
||||
}
|
||||
}
|
||||
});
|
||||
// com.android.server.pm.PackageManagerService.getApplicationInfo(String packageName, int flag, int userId)
|
||||
hookAllMethods("com.android.server.pm.PackageManagerService", lpparam.classLoader, "getApplicationInfo", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
if (param.args != null && param.args[0] != null) {
|
||||
final int packageUid = Binder.getCallingUid();
|
||||
if ((boolean) callStaticMethod(UserHandle.class, "isCore", packageUid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int userId = (int) param.args[2];
|
||||
boolean isXposedModule = false;
|
||||
final String[] packages = (String[]) callMethod(param.thisObject, "getPackagesForUid", packageUid);
|
||||
if (packages == null || packages.length == 0) {
|
||||
return;
|
||||
}
|
||||
for (String packageName : packages) {
|
||||
if (binarySearch(HIDE_WHITE_LIST, packageName) >= 0) {
|
||||
return;
|
||||
}
|
||||
if (binarySearch(getModulesList(userId), packageName) >= 0) {
|
||||
isXposedModule = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isXposedModule) {
|
||||
if (getFlagState(userId, mPretendXposedInstallerFlag)) {
|
||||
if (param.args[0].equals(LEGACY_INSTALLER)) {
|
||||
param.args[0] = APPLICATION_ID;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (getFlagState(userId, mHideEdXposedManagerFlag)) {
|
||||
if (param.args[0].equals(APPLICATION_ID) || param.args[0].equals(LEGACY_INSTALLER)) {
|
||||
param.setResult(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// com.android.server.pm.PackageManagerService.getPackageInfo(String packageName, int flag, int userId)
|
||||
hookAllMethods("com.android.server.pm.PackageManagerService", lpparam.classLoader, "getPackageInfo", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
if (param.args != null && param.args[0] != null) {
|
||||
final int packageUid = Binder.getCallingUid();
|
||||
if ((boolean) callStaticMethod(UserHandle.class, "isCore", packageUid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int userId = (int) param.args[2];
|
||||
boolean isXposedModule = false;
|
||||
final String[] packages = (String[]) callMethod(param.thisObject, "getPackagesForUid", packageUid);
|
||||
if (packages == null || packages.length == 0) {
|
||||
return;
|
||||
}
|
||||
for (String packageName : packages) {
|
||||
if (binarySearch(HIDE_WHITE_LIST, packageName) >= 0) {
|
||||
return;
|
||||
}
|
||||
if (binarySearch(getModulesList(userId), packageName) >= 0) {
|
||||
isXposedModule = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isXposedModule) {
|
||||
if (getFlagState(userId, mPretendXposedInstallerFlag)) {
|
||||
if (param.args[0].equals(LEGACY_INSTALLER)) {
|
||||
param.args[0] = APPLICATION_ID;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (getFlagState(userId, mHideEdXposedManagerFlag)) {
|
||||
if (param.args[0].equals(APPLICATION_ID) || param.args[0].equals(LEGACY_INSTALLER)) {
|
||||
param.setResult(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// Hook AM to remove restrict of EdXposed Manager
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
final XC_MethodHook hook = new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) {
|
||||
if (param.args != null && param.args[1] != null) {
|
||||
if (param.args[1].equals(APPLICATION_ID)) {
|
||||
param.setResult(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
hookAllMethods("com.android.server.am.ActivityManagerService", lpparam.classLoader, "appRestrictedInBackgroundLocked", hook);
|
||||
hookAllMethods("com.android.server.am.ActivityManagerService", lpparam.classLoader, "appServicesRestrictedInBackgroundLocked", hook);
|
||||
hookAllMethods("com.android.server.am.ActivityManagerService", lpparam.classLoader, "getAppStartModeLocked", hook);
|
||||
}
|
||||
} else if (lpparam.packageName.equals(APPLICATION_ID)) {
|
||||
// Make sure Xposed work
|
||||
XposedHelpers.findAndHookMethod(XposedApp.class.getName(), lpparam.classLoader, "isEnhancementEnabled", XC_MethodReplacement.returnConstant(true));
|
||||
// XposedHelpers.findAndHookMethod(StatusInstallerFragment.class.getName(), lpparam.classLoader, "isSELinuxEnforced", XC_MethodReplacement.returnConstant(SELinuxHelper.isSELinuxEnforced()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -154,13 +154,6 @@
|
|||
android:title="@string/pref_title_enable_boot_image_deopt"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="disable_hidden_api_bypass"
|
||||
android:summary="@string/settings_summary_disable_hidden_api_bypass"
|
||||
android:title="@string/settings_title_disable_hidden_api_bypass"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="disable_resources"
|
||||
|
|
@ -188,32 +181,4 @@
|
|||
android:title="@string/pref_title_disable_modules_log"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="group_enhancement"
|
||||
android:title="@string/settings_group_enhancement"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<Preference
|
||||
android:key="enhancement_status"
|
||||
android:summary="@string/settings_summary_enhancement"
|
||||
android:title="@string/settings_title_enhancement"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="pretend_xposed_installer"
|
||||
android:summary="@string/settings_summary_pretend_xposed_installer"
|
||||
android:title="@string/settings_title_pretend_xposed_installer"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="hide_edxposed_manager"
|
||||
android:summary="@string/settings_summary_hide_edxposed_manager"
|
||||
android:title="@string/settings_title_hide_edxposed_manager"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
Loading…
Reference in New Issue