Refactor ApplicationService (#1775)
This commit is contained in:
parent
3049dbb29b
commit
416167a226
|
|
@ -1,6 +1,6 @@
|
|||
package de.robv.android.xposed;
|
||||
|
||||
import static org.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient;
|
||||
import static org.lsposed.lspd.core.ApplicationServiceClient.serviceClient;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
package de.robv.android.xposed;
|
||||
|
||||
import static org.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient;
|
||||
import static org.lsposed.lspd.core.ApplicationServiceClient.serviceClient;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
package de.robv.android.xposed;
|
||||
|
||||
import static org.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient;
|
||||
import static org.lsposed.lspd.core.ApplicationServiceClient.serviceClient;
|
||||
import static org.lsposed.lspd.deopt.PrebuiltMethodsDeopter.deoptResourceMethods;
|
||||
import static de.robv.android.xposed.XposedBridge.hookAllMethods;
|
||||
import static de.robv.android.xposed.XposedHelpers.callMethod;
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
package org.lsposed.lspd.config;
|
||||
|
||||
import android.os.IBinder;
|
||||
|
||||
import org.lsposed.lspd.models.Module;
|
||||
import org.lsposed.lspd.service.ILSPApplicationService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
abstract public class ApplicationServiceClient implements ILSPApplicationService {
|
||||
|
||||
public static ApplicationServiceClient serviceClient = null;
|
||||
|
||||
@Override
|
||||
abstract public IBinder requestModuleBinder(String name);
|
||||
|
||||
@Override
|
||||
abstract public List<Module> getModulesList(String processName);
|
||||
|
||||
abstract public List<Module> getModulesList();
|
||||
|
||||
@Override
|
||||
abstract public String getPrefsPath(String packageName);
|
||||
}
|
||||
|
|
@ -17,13 +17,15 @@
|
|||
* Copyright (C) 2021 LSPosed Contributors
|
||||
*/
|
||||
|
||||
package org.lsposed.lspd.config;
|
||||
package org.lsposed.lspd.core;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.lsposed.lspd.models.Module;
|
||||
import org.lsposed.lspd.service.ILSPApplicationService;
|
||||
import org.lsposed.lspd.util.Utils;
|
||||
|
|
@ -31,32 +33,27 @@ import org.lsposed.lspd.util.Utils;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class LSPApplicationServiceClient extends ApplicationServiceClient {
|
||||
static ILSPApplicationService service = null;
|
||||
static IBinder serviceBinder = null;
|
||||
public class ApplicationServiceClient implements ILSPApplicationService, IBinder.DeathRecipient {
|
||||
public static ApplicationServiceClient serviceClient = null;
|
||||
|
||||
static String processName = null;
|
||||
final ILSPApplicationService service;
|
||||
|
||||
private static final IBinder.DeathRecipient recipient = new IBinder.DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
serviceBinder.unlinkToDeath(this, 0);
|
||||
serviceBinder = null;
|
||||
service = null;
|
||||
}
|
||||
};
|
||||
final String processName;
|
||||
|
||||
public static void Init(IBinder binder, String niceName) {
|
||||
if (serviceClient == null && binder != null && serviceBinder == null && service == null) {
|
||||
serviceBinder = binder;
|
||||
processName = niceName;
|
||||
private ApplicationServiceClient(@NonNull ILSPApplicationService service, @NonNull String processName) throws RemoteException {
|
||||
this.service = service;
|
||||
this.processName = processName;
|
||||
this.service.asBinder().linkToDeath(this, 0);
|
||||
}
|
||||
|
||||
synchronized static void Init(ILSPApplicationService service, String niceName) {
|
||||
var binder = service.asBinder();
|
||||
if (serviceClient == null && binder != null) {
|
||||
try {
|
||||
serviceBinder.linkToDeath(recipient, 0);
|
||||
serviceClient = new ApplicationServiceClient(service, niceName);
|
||||
} catch (RemoteException e) {
|
||||
Utils.logE("link to death error: ", e);
|
||||
}
|
||||
service = ILSPApplicationService.Stub.asInterface(binder);
|
||||
serviceClient = new LSPApplicationServiceClient();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,18 +67,14 @@ public class LSPApplicationServiceClient extends ApplicationServiceClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Module> getModulesList(String processName) {
|
||||
public List<Module> getModulesList() {
|
||||
try {
|
||||
return service.getModulesList(processName);
|
||||
return service.getModulesList();
|
||||
} catch (RemoteException | NullPointerException ignored) {
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public List<Module> getModulesList() {
|
||||
return getModulesList(processName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefsPath(String packageName) {
|
||||
try {
|
||||
|
|
@ -107,6 +100,12 @@ public class LSPApplicationServiceClient extends ApplicationServiceClient {
|
|||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
return serviceBinder;
|
||||
return service.asBinder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void binderDied() {
|
||||
service.asBinder().unlinkToDeath(this, 0);
|
||||
serviceClient = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ import android.app.ActivityThread;
|
|||
import android.app.LoadedApk;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.os.Process;
|
||||
|
||||
import com.android.internal.os.ZygoteInit;
|
||||
|
||||
|
|
@ -33,6 +32,7 @@ import org.lsposed.lspd.hooker.CrashDumpHooker;
|
|||
import org.lsposed.lspd.hooker.HandleBindAppHooker;
|
||||
import org.lsposed.lspd.hooker.HandleSystemServerProcessHooker;
|
||||
import org.lsposed.lspd.hooker.LoadedApkCstrHooker;
|
||||
import org.lsposed.lspd.service.ILSPApplicationService;
|
||||
import org.lsposed.lspd.util.Utils;
|
||||
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
|
|
@ -58,19 +58,19 @@ public class Startup {
|
|||
new LoadedApkCstrHooker());
|
||||
}
|
||||
|
||||
public static void bootstrapXposed(String niceName) {
|
||||
public static void bootstrapXposed() {
|
||||
// Initialize the Xposed framework
|
||||
try {
|
||||
startBootstrapHook(XposedInit.startsSystemServer);
|
||||
Utils.logI("Loading modules for " + niceName + "/" + Process.myUid());
|
||||
XposedInit.loadModules();
|
||||
} catch (Throwable t) {
|
||||
Utils.logE("error during Xposed initialization", t);
|
||||
}
|
||||
}
|
||||
|
||||
public static void initXposed(boolean isSystem) {
|
||||
public static void initXposed(boolean isSystem, String processName, ILSPApplicationService service) {
|
||||
// init logger
|
||||
ApplicationServiceClient.Init(service, processName);
|
||||
XposedBridge.initXResources();
|
||||
XposedInit.startsSystemServer = isSystem;
|
||||
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
package org.lsposed.lspd.hooker;
|
||||
|
||||
import static org.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient;
|
||||
import static org.lsposed.lspd.core.ApplicationServiceClient.serviceClient;
|
||||
|
||||
import android.app.LoadedApk;
|
||||
import android.os.IBinder;
|
||||
|
|
|
|||
|
|
@ -29,20 +29,54 @@ import android.os.RemoteException;
|
|||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.lsposed.lspd.models.Module;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class LSPApplicationService extends ILSPApplicationService.Stub {
|
||||
final static int DEX_TRANSACTION_CODE = 1310096052;
|
||||
// <uid, pid>
|
||||
private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet();
|
||||
private final static Map<Integer, IBinder> handles = new ConcurrentHashMap<>();
|
||||
private final static Set<IBinder.DeathRecipient> recipients = ConcurrentHashMap.newKeySet();
|
||||
// key: <uid, pid>
|
||||
private final static Map<Pair<Integer, Integer>, ProcessInfo> processes = new ConcurrentHashMap<>();
|
||||
|
||||
static class ProcessInfo implements DeathRecipient {
|
||||
int uid;
|
||||
int pid;
|
||||
String processName;
|
||||
IBinder heartBeat;
|
||||
|
||||
ProcessInfo(int uid, int pid, String processName, IBinder heartBeat) throws RemoteException {
|
||||
this.uid = uid;
|
||||
this.pid = pid;
|
||||
this.processName = processName;
|
||||
this.heartBeat = heartBeat;
|
||||
heartBeat.linkToDeath(this, 0);
|
||||
Log.d(TAG, "register " + this);
|
||||
processes.put(new Pair<>(uid, pid), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void binderDied() {
|
||||
Log.d(TAG, this + " is dead");
|
||||
heartBeat.unlinkToDeath(this, 0);
|
||||
processes.remove(new Pair<>(uid, pid), this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProcessInfo{" +
|
||||
"uid=" + uid +
|
||||
", pid=" + pid +
|
||||
", processName='" + processName + '\'' +
|
||||
", heartBeat=" + heartBeat +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
||||
|
|
@ -57,40 +91,24 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
|||
return super.onTransact(code, data, reply, flags);
|
||||
}
|
||||
|
||||
public boolean registerHeartBeat(int uid, int pid, IBinder handle) {
|
||||
public boolean registerHeartBeat(int uid, int pid, String processName, IBinder heartBeat) {
|
||||
try {
|
||||
var recipient = new DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
Log.d(TAG, "pid=" + pid + " uid=" + uid + " is dead.");
|
||||
cache.remove(new Pair<>(uid, pid));
|
||||
handles.remove(pid, handle);
|
||||
handle.unlinkToDeath(this, 0);
|
||||
recipients.remove(this);
|
||||
}
|
||||
};
|
||||
recipients.add(recipient);
|
||||
handle.linkToDeath(recipient, 0);
|
||||
handles.put(pid, handle);
|
||||
cache.add(new Pair<>(uid, pid));
|
||||
new ProcessInfo(uid, pid, processName, heartBeat);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, Log.getStackTraceString(e));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Module> getModulesList(String processName) throws RemoteException {
|
||||
ensureRegistered();
|
||||
int pid = getCallingPid();
|
||||
int uid = getCallingUid();
|
||||
if (uid == 1000 && processName.equals("android")) {
|
||||
public List<Module> getModulesList() throws RemoteException {
|
||||
var processInfo = ensureRegistered();
|
||||
if (processInfo.uid == 1000 && processInfo.processName.equals("android")) {
|
||||
return ConfigManager.getInstance().getModulesForSystemServer();
|
||||
}
|
||||
if (ServiceManager.getManagerService().isRunningManager(pid, uid))
|
||||
if (ServiceManager.getManagerService().isRunningManager(processInfo.pid, processInfo.uid))
|
||||
return Collections.emptyList();
|
||||
return ConfigManager.getInstance().getModulesForProcess(processName, uid);
|
||||
return ConfigManager.getInstance().getModulesForProcess(processInfo.processName, processInfo.uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -107,35 +125,38 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
|||
|
||||
@Override
|
||||
public IBinder requestModuleBinder(String name) throws RemoteException {
|
||||
ensureRegistered();
|
||||
if (ConfigManager.getInstance().isModule(getCallingUid(), name)) {
|
||||
ConfigManager.getInstance().ensureModulePrefsPermission(getCallingUid(), name);
|
||||
var processInfo = ensureRegistered();
|
||||
if (ConfigManager.getInstance().isModule(processInfo.uid, name)) {
|
||||
ConfigManager.getInstance().ensureModulePrefsPermission(processInfo.pid, name);
|
||||
return ServiceManager.getModuleService(name);
|
||||
} else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor requestInjectedManagerBinder(List<IBinder> binder) throws RemoteException {
|
||||
ensureRegistered();
|
||||
var pid = getCallingPid();
|
||||
var uid = getCallingUid();
|
||||
if (ServiceManager.getManagerService().postStartManager(pid, uid) ||
|
||||
ConfigManager.getInstance().isManager(uid)) {
|
||||
var heartbeat = handles.get(pid);
|
||||
if (heartbeat != null) {
|
||||
binder.add(ServiceManager.getManagerService().obtainManagerBinder(heartbeat, pid, uid));
|
||||
}
|
||||
|
||||
var processInfo = ensureRegistered();
|
||||
if (ServiceManager.getManagerService().postStartManager(processInfo.pid, processInfo.uid) ||
|
||||
ConfigManager.getInstance().isManager(processInfo.uid)) {
|
||||
binder.add(ServiceManager.getManagerService().obtainManagerBinder(processInfo.heartBeat, processInfo.pid, processInfo.uid));
|
||||
}
|
||||
return ConfigManager.getInstance().getManagerApk();
|
||||
}
|
||||
|
||||
public boolean hasRegister(int uid, int pid) {
|
||||
return cache.contains(new Pair<>(uid, pid));
|
||||
return processes.containsKey(new Pair<>(uid, pid));
|
||||
}
|
||||
|
||||
private void ensureRegistered() throws RemoteException {
|
||||
if (!hasRegister(getCallingUid(), getCallingPid()))
|
||||
@NonNull
|
||||
private ProcessInfo ensureRegistered() throws RemoteException {
|
||||
var uid = getCallingUid();
|
||||
var pid = getCallingPid();
|
||||
var key = new Pair<>(uid, pid);
|
||||
ProcessInfo processInfo = processes.getOrDefault(key, null);
|
||||
if (processInfo == null || uid != processInfo.uid || pid != processInfo.pid) {
|
||||
processes.remove(key, processInfo);
|
||||
Log.w(TAG, "non-authorized: info=" + processInfo + " uid=" + uid + " pid=" + pid);
|
||||
throw new RemoteException("Not registered");
|
||||
}
|
||||
return processInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme
|
|||
if (ConfigManager.getInstance().shouldSkipSystemServer() || uid != 1000 || heartBeat == null || !"android".equals(processName))
|
||||
return null;
|
||||
else
|
||||
return ServiceManager.requestApplicationService(uid, pid, heartBeat);
|
||||
return ServiceManager.requestApplicationService(uid, pid, processName, heartBeat);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class LSPosedService extends ILSPosedService.Stub {
|
|||
return null;
|
||||
}
|
||||
Log.d(TAG, "returned service");
|
||||
return ServiceManager.requestApplicationService(uid, pid, heartBeat);
|
||||
return ServiceManager.requestApplicationService(uid, pid, processName, heartBeat);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ public class ServiceManager {
|
|||
return applicationService;
|
||||
}
|
||||
|
||||
public static LSPApplicationService requestApplicationService(int uid, int pid, IBinder heartBeat) {
|
||||
if (applicationService.registerHeartBeat(uid, pid, heartBeat))
|
||||
public static LSPApplicationService requestApplicationService(int uid, int pid, String processName, IBinder heartBeat) {
|
||||
if (applicationService.registerHeartBeat(uid, pid, processName, heartBeat))
|
||||
return applicationService;
|
||||
else return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ fun afterEval() = android.applicationVariants.forEach { variant ->
|
|||
into(magiskDir)
|
||||
from("${rootProject.projectDir}/README.md")
|
||||
from("$projectDir/magisk_module") {
|
||||
exclude("riru.sh", "module.prop", "customize.sh", "sepolicy.rule", "post-fs-data.sh")
|
||||
exclude("riru.sh", "module.prop", "customize.sh", "sepolicy.rule", "daemon")
|
||||
}
|
||||
from("$projectDir/magisk_module") {
|
||||
include("module.prop")
|
||||
|
|
@ -163,13 +163,16 @@ fun afterEval() = android.applicationVariants.forEach { variant ->
|
|||
"zygisk" -> "Requires Magisk 24.0+ and Zygisk enabled"
|
||||
else -> "No further requirements"
|
||||
},
|
||||
"api" to flavorCapped
|
||||
"api" to flavorCapped,
|
||||
)
|
||||
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
|
||||
}
|
||||
from("$projectDir/magisk_module") {
|
||||
include("customize.sh", "post-fs-data.sh")
|
||||
val tokens = mapOf("FLAVOR" to flavorLowered)
|
||||
include("customize.sh", "daemon")
|
||||
val tokens = mapOf(
|
||||
"FLAVOR" to flavorLowered,
|
||||
"DEBUG" to if (buildTypeLowered == "debug") "true" else "false"
|
||||
)
|
||||
filter<ReplaceTokens>("tokens" to tokens)
|
||||
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
|
||||
}
|
||||
|
|
@ -181,7 +184,6 @@ fun afterEval() = android.applicationVariants.forEach { variant ->
|
|||
"RIRU_MODULE_API_VERSION" to moduleMaxRiruApiVersion.toString(),
|
||||
"RIRU_MODULE_MIN_API_VERSION" to moduleMinRiruApiVersion.toString(),
|
||||
"RIRU_MODULE_MIN_RIRU_VERSION_NAME" to moduleMinRiruVersionName,
|
||||
"RIRU_MODULE_DEBUG" to if (buildTypeLowered == "debug") "true" else "false",
|
||||
)
|
||||
filter<ReplaceTokens>("tokens" to tokens)
|
||||
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
dir=${0%/*}
|
||||
tmpLspdApk="/data/local/tmp/daemon.apk"
|
||||
debug="false"
|
||||
debug=@DEBUG@
|
||||
flavor=@FLAVOR@
|
||||
|
||||
if [ -r $tmpLspdApk ]; then
|
||||
java_options="-Djava.class.path=$tmpLspdApk"
|
||||
|
|
@ -27,12 +28,15 @@ fi
|
|||
mount tmpfs -t tmpfs /data/resource-cache
|
||||
|
||||
if [ ! -S "/dev/socket/zygote" ]; then
|
||||
timeout 1 inotifyd - /dev/socket:near | while read -r; do
|
||||
timeout 0.5 inotifyd - /dev/socket:near | while read -r line; do
|
||||
$debug && log -p v -t "LSPosed" "inotify: $line"
|
||||
if [ -S "/dev/socket/zygote" ]; then
|
||||
$debug && log -p v -t "LSPosed" "zygote started"
|
||||
touch /dev/socket&
|
||||
exit
|
||||
fi
|
||||
done
|
||||
fi
|
||||
$debug && log -p d -t "LSPosed" "start $flavor daemon $*"
|
||||
# shellcheck disable=SC2086
|
||||
exec /system/bin/app_process $java_options /system/bin --nice-name=lspd org.lsposed.lspd.Main "$@" >/dev/null 2>&1
|
||||
|
|
|
|||
|
|
@ -20,22 +20,23 @@
|
|||
package org.lsposed.lspd.core;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
|
||||
import org.lsposed.lspd.BuildConfig;
|
||||
import org.lsposed.lspd.config.LSPApplicationServiceClient;
|
||||
import org.lsposed.lspd.service.ILSPApplicationService;
|
||||
import org.lsposed.lspd.util.ParasiticManagerHooker;
|
||||
import org.lsposed.lspd.util.Utils;
|
||||
import org.lsposed.lspd.BuildConfig;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void forkCommon(boolean isSystem, String niceName, IBinder binder) {
|
||||
LSPApplicationServiceClient.Init(binder, niceName);
|
||||
Startup.initXposed(isSystem);
|
||||
Startup.initXposed(isSystem, niceName, ILSPApplicationService.Stub.asInterface(binder));
|
||||
if ((niceName.equals(BuildConfig.MANAGER_INJECTED_PKG_NAME) || niceName.equals(BuildConfig.DEFAULT_MANAGER_PACKAGE_NAME))
|
||||
&& ParasiticManagerHooker.start()) {
|
||||
Utils.logI("Loaded manager, skipping next steps");
|
||||
return;
|
||||
}
|
||||
Startup.bootstrapXposed(niceName);
|
||||
Utils.logI("Loading xposed for " + niceName + "/" + Process.myUid());
|
||||
Startup.bootstrapXposed();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package org.lsposed.lspd.util;
|
||||
|
||||
import static org.lsposed.lspd.config.ApplicationServiceClient.serviceClient;
|
||||
import static org.lsposed.lspd.core.ApplicationServiceClient.serviceClient;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.app.LoadedApk;
|
||||
|
|
@ -24,8 +24,8 @@ import android.webkit.WebViewDelegate;
|
|||
import android.webkit.WebViewFactory;
|
||||
import android.webkit.WebViewFactoryProvider;
|
||||
|
||||
import org.lsposed.lspd.BuildConfig;
|
||||
import org.lsposed.lspd.ILSPManagerService;
|
||||
import org.lsposed.lspd.BuildConfig;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import org.lsposed.lspd.models.Module;
|
|||
interface ILSPApplicationService {
|
||||
IBinder requestModuleBinder(String name);
|
||||
|
||||
List<Module> getModulesList(String processName);
|
||||
List<Module> getModulesList();
|
||||
|
||||
String getPrefsPath(String packageName);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue