[core] Add more manager service interfaces
This commit is contained in:
parent
374c8cac11
commit
e7e32351ea
|
|
@ -11,7 +11,7 @@ interface ILSPApplicationService {
|
||||||
|
|
||||||
boolean isResourcesHookEnabled() = 5;
|
boolean isResourcesHookEnabled() = 5;
|
||||||
|
|
||||||
List<String> getModulesList() = 6;
|
String[] getModulesList() = 6;
|
||||||
|
|
||||||
String getPrefsPath(String packageName) = 7;
|
String getPrefsPath(String packageName) = 7;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -353,7 +353,7 @@ public final class XposedInit {
|
||||||
topClassLoader = parent;
|
topClassLoader = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> moduleList = serviceClient.getModulesList();
|
String[] moduleList = serviceClient.getModulesList();
|
||||||
ArraySet<String> newLoadedApk = new ArraySet<>();
|
ArraySet<String> newLoadedApk = new ArraySet<>();
|
||||||
for (String apk : moduleList)
|
for (String apk : moduleList)
|
||||||
if (loadedModules.contains(apk)) {
|
if (loadedModules.contains(apk)) {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,14 @@ public class LSPApplicationServiceClient implements ILSPApplicationService {
|
||||||
if (serviceClient == null && binder != null && serviceBinder == null && service == null) {
|
if (serviceClient == null && binder != null && serviceBinder == null && service == null) {
|
||||||
serviceBinder = binder;
|
serviceBinder = binder;
|
||||||
try {
|
try {
|
||||||
serviceBinder.linkToDeath(() -> {
|
serviceBinder.linkToDeath(
|
||||||
|
new IBinder.DeathRecipient() {
|
||||||
|
@Override
|
||||||
|
public void binderDied() {
|
||||||
|
serviceBinder.unlinkToDeath(this, 0);
|
||||||
serviceBinder = null;
|
serviceBinder = null;
|
||||||
service = null;
|
service = null;
|
||||||
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Utils.logE("link to death error: ", e);
|
Utils.logE("link to death error: ", e);
|
||||||
|
|
@ -84,12 +89,12 @@ public class LSPApplicationServiceClient implements ILSPApplicationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getModulesList() {
|
public String[] getModulesList() {
|
||||||
try {
|
try {
|
||||||
return service.getModulesList();
|
return service.getModulesList();
|
||||||
} catch (RemoteException | NullPointerException ignored) {
|
} catch (RemoteException | NullPointerException ignored) {
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -23,30 +23,12 @@ package io.github.lsposed.lspd.hooker;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedHelpers;
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
import io.github.lsposed.lspd.core.EdxpImpl;
|
|
||||||
import io.github.lsposed.lspd.core.Main;
|
|
||||||
import io.github.lsposed.lspd.util.Utils;
|
import io.github.lsposed.lspd.util.Utils;
|
||||||
|
|
||||||
public class XposedInstallerHooker {
|
public class XposedInstallerHooker {
|
||||||
|
|
||||||
public static void hookXposedInstaller(final ClassLoader classLoader, IBinder binder) {
|
public static void hookXposedInstaller(final ClassLoader classLoader, IBinder binder) {
|
||||||
final String variant;
|
|
||||||
switch (Main.getEdxpVariant()) {
|
|
||||||
case EdxpImpl.YAHFA:
|
|
||||||
variant = "YAHFA";
|
|
||||||
break;
|
|
||||||
case EdxpImpl.SANDHOOK:
|
|
||||||
variant = "SandHook";
|
|
||||||
break;
|
|
||||||
case EdxpImpl.NONE:
|
|
||||||
default:
|
|
||||||
variant = "Unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils.logI("Found LSPosed Manager, hooking it");
|
Utils.logI("Found LSPosed Manager, hooking it");
|
||||||
|
|
||||||
// LSPosed Manager R
|
|
||||||
try {
|
try {
|
||||||
Class<?> serviceClass = XposedHelpers.findClass("io.github.lsposed.manager.receivers.LSPosedManagerServiceClient", classLoader);
|
Class<?> serviceClass = XposedHelpers.findClass("io.github.lsposed.manager.receivers.LSPosedManagerServiceClient", classLoader);
|
||||||
XposedHelpers.setStaticObjectField(serviceClass, "binder", binder);
|
XposedHelpers.setStaticObjectField(serviceClass, "binder", binder);
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ package io.github.lsposed.lspd.service;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteQueryBuilder;
|
import android.database.sqlite.SQLiteQueryBuilder;
|
||||||
import android.database.sqlite.SQLiteStatement;
|
import android.database.sqlite.SQLiteStatement;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.os.FileObserver;
|
import android.os.FileObserver;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
@ -21,8 +21,6 @@ import java.nio.file.Files;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import static io.github.lsposed.lspd.service.ServiceManager.TAG;
|
import static io.github.lsposed.lspd.service.ServiceManager.TAG;
|
||||||
|
|
@ -130,10 +128,12 @@ public class ConfigManager {
|
||||||
updateManager();
|
updateManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final SQLiteStatement createEnabledModulesTable = db.compileStatement("CREATE TABLE IF NOT EXISTS enabled_modules (" +
|
private final SQLiteStatement createModulesTable = db.compileStatement("CREATE TABLE IF NOT EXISTS modules (" +
|
||||||
"mid integer PRIMARY KEY AUTOINCREMENT," +
|
"mid integer PRIMARY KEY AUTOINCREMENT," +
|
||||||
"package_name text NOT NULL UNIQUE," +
|
"package_name text NOT NULL UNIQUE," +
|
||||||
"apk_path text NOT NULL" +
|
"apk_path text NOT NULL, " +
|
||||||
|
"enabled BOOLEAN DEFAULT 0 " +
|
||||||
|
"CHECK (enabled IN (0, 1))" +
|
||||||
");");
|
");");
|
||||||
private final SQLiteStatement createScopeTable = db.compileStatement("CREATE TABLE IF NOT EXISTS scope (" +
|
private final SQLiteStatement createScopeTable = db.compileStatement("CREATE TABLE IF NOT EXISTS scope (" +
|
||||||
"mid integer," +
|
"mid integer," +
|
||||||
|
|
@ -154,96 +154,104 @@ public class ConfigManager {
|
||||||
updateConfig();
|
updateConfig();
|
||||||
isPermissive = readInt(selinuxPath, 1) == 0;
|
isPermissive = readInt(selinuxPath, 1) == 0;
|
||||||
configObserver.startWatching();
|
configObserver.startWatching();
|
||||||
|
cacheScopes();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTables() {
|
private void createTables() {
|
||||||
createEnabledModulesTable.execute();
|
createModulesTable.execute();
|
||||||
createScopeTable.execute();
|
createScopeTable.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void cacheScopes() {
|
private synchronized void cacheScopes() {
|
||||||
modulesForUid.clear();
|
modulesForUid.clear();
|
||||||
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
|
try (Cursor cursor = db.query("scope INNER JOIN modules ON scope.mid = modules.mid", new String[]{"uid", "apk_path"},
|
||||||
builder.setTables("scope INNER JOIN enabled_modules ON scope.mid = enabled_modules.mid");
|
"enabled = ?", new String[]{"1"}, null, null, null)) {
|
||||||
Cursor cursor = builder.query(db, new String[]{"scope.uid", "enabled_modules.apk_path"},
|
|
||||||
null, null, null, null, null);
|
|
||||||
if (cursor == null) {
|
if (cursor == null) {
|
||||||
Log.e(TAG, "db cache failed");
|
Log.e(TAG, "db cache failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int uid_idx = cursor.getColumnIndex("scope.uid");
|
int uid_idx = cursor.getColumnIndex("uid");
|
||||||
int apk_path_idx = cursor.getColumnIndex("enabled_modules.apk_path");
|
int apk_path_idx = cursor.getColumnIndex("apk_path");
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
int uid = cursor.getInt(uid_idx);
|
int uid = cursor.getInt(uid_idx);
|
||||||
String apk_path = cursor.getString(apk_path_idx);
|
String apk_path = cursor.getString(apk_path_idx);
|
||||||
modulesForUid.computeIfAbsent(uid, ignored -> new ArrayList<>()).add(apk_path);
|
modulesForUid.computeIfAbsent(uid, ignored -> new ArrayList<>()).add(apk_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This is called when a new process created, use the cached result
|
// This is called when a new process created, use the cached result
|
||||||
public List<String> getModulesPathForUid(int uid) {
|
public String[] getModulesPathForUid(int uid) {
|
||||||
return isManager(uid) ? new ArrayList<>() : modulesForUid.getOrDefault(uid, null);
|
return isManager(uid) ? new String[0] : modulesForUid.getOrDefault(uid, new ArrayList<>()).toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is called when a new process created, use the cached result
|
// This is called when a new process created, use the cached result
|
||||||
// The signature matches Riru's
|
// The signature matches Riru's
|
||||||
public boolean shouldSkipUid(int uid) {
|
public boolean shouldSkipUid(int uid) {
|
||||||
|
Log.d(TAG, modulesForUid.keySet().size() + "");
|
||||||
|
for (Integer id : modulesForUid.keySet()) {
|
||||||
|
Log.d(TAG, id.toString());
|
||||||
|
}
|
||||||
return !modulesForUid.containsKey(uid) && !isManager(uid);
|
return !modulesForUid.containsKey(uid) && !isManager(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should only be called by manager, so we don't need to cache it
|
// This should only be called by manager, so we don't need to cache it
|
||||||
public Set<Integer> getModuleScope(String packageName) {
|
public int[] getModuleScope(String packageName) {
|
||||||
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
|
int mid = getModuleId(packageName);
|
||||||
builder.setTables("scope INNER JOIN enabled_modules ON scope.mid = enabled_modules.mid");
|
if (mid == -1) return null;
|
||||||
Cursor cursor = builder.query(db, new String[]{"scope.uid"},
|
try (Cursor cursor = db.query("scope INNER JOIN modules ON scope.mid = modules.mid", new String[]{"uid"},
|
||||||
null, null, null, null, null);
|
"scope.mid = ?", new String[]{String.valueOf(mid)}, null, null, null)) {
|
||||||
if (cursor == null) {
|
if (cursor == null) {
|
||||||
Log.e(TAG, "db cache failed");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int uid_idx = cursor.getColumnIndex("scope.uid");
|
int uid_idx = cursor.getColumnIndex("uid");
|
||||||
HashSet<Integer> result = new HashSet<>();
|
HashSet<Integer> result = new HashSet<>();
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
int uid = cursor.getInt(uid_idx);
|
int uid = cursor.getInt(uid_idx);
|
||||||
result.add(uid);
|
result.add(uid);
|
||||||
}
|
}
|
||||||
return result;
|
return result.stream().mapToInt(i -> i).toArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean updateModuleApkPath(String packageName, String apkPath) {
|
public boolean updateModuleApkPath(String packageName, String apkPath) {
|
||||||
|
if (db.inTransaction()) {
|
||||||
|
Log.w(TAG, "update module apk path should not be called inside transaction");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
values.put("package_name", packageName);
|
||||||
values.put("apk_path", apkPath);
|
values.put("apk_path", apkPath);
|
||||||
int count = db.updateWithOnConflict("enabled_modules", values, "package_name = ?", new String[]{packageName}, SQLiteDatabase.CONFLICT_REPLACE);
|
int count = (int) db.insertWithOnConflict("modules", null, values, SQLiteDatabase.CONFLICT_IGNORE);
|
||||||
|
if (count < 0) {
|
||||||
|
count = db.updateWithOnConflict("modules", values, "package_name=?", new String[]{packageName}, SQLiteDatabase.CONFLICT_IGNORE);
|
||||||
|
}
|
||||||
if (count >= 1) {
|
if (count >= 1) {
|
||||||
cacheScopes();
|
cacheScopes();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return count >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only be called before updating modules. No need to cache.
|
// Only be called before updating modules. No need to cache.
|
||||||
private int getModuleId(String packageName) {
|
private int getModuleId(String packageName) {
|
||||||
try {
|
if (db.inTransaction()) {
|
||||||
db.beginTransaction();
|
Log.w(TAG, "get module id should not be called inside transaction");
|
||||||
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
|
return -1;
|
||||||
Cursor cursor = builder.query(db, new String[]{"mid"}, "package_name = ?", new String[]{packageName}, null, null, null);
|
}
|
||||||
|
try (Cursor cursor = db.query("modules", new String[]{"mid"}, "package_name=?", new String[]{packageName}, null, null, null)) {
|
||||||
if (cursor == null) return -1;
|
if (cursor == null) return -1;
|
||||||
if (cursor.getCount() != 1) return -1;
|
if (cursor.getCount() != 1) return -1;
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
return cursor.getInt(cursor.getColumnIndex("mid"));
|
return cursor.getInt(cursor.getColumnIndex("mid"));
|
||||||
} finally {
|
|
||||||
db.setTransactionSuccessful();
|
|
||||||
db.endTransaction();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setModuleScope(String packageName, String apkPath, List<Integer> uid) {
|
public boolean setModuleScope(String packageName, int[] uid) {
|
||||||
if (uid == null || uid.isEmpty()) return false;
|
if (uid == null || uid.length == 0) return false;
|
||||||
updateModuleApkPath(packageName, apkPath);
|
|
||||||
try {
|
|
||||||
db.beginTransaction();
|
|
||||||
int mid = getModuleId(packageName);
|
int mid = getModuleId(packageName);
|
||||||
if (mid == -1) return false;
|
if (mid == -1) return false;
|
||||||
|
try {
|
||||||
|
db.beginTransaction();
|
||||||
db.delete("scope", "mid = ?", new String[]{String.valueOf(mid)});
|
db.delete("scope", "mid = ?", new String[]{String.valueOf(mid)});
|
||||||
for (int id : uid) {
|
for (int id : uid) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
|
@ -259,12 +267,27 @@ public class ConfigManager {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String[] enabledModules() {
|
||||||
|
try (Cursor cursor = db.query("modules", new String[]{"package_name"}, "enabled = ?", new String[]{"1"}, null, null, null)) {
|
||||||
|
if (cursor == null) {
|
||||||
|
Log.e(TAG, "db cache failed");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int pkg_idx = cursor.getColumnIndex("package_name");
|
||||||
|
HashSet<String> result = new HashSet<>();
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
result.add(cursor.getString(pkg_idx));
|
||||||
|
}
|
||||||
|
return result.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean removeModule(String packageName) {
|
public boolean removeModule(String packageName) {
|
||||||
try {
|
|
||||||
db.beginTransaction();
|
|
||||||
int mid = getModuleId(packageName);
|
int mid = getModuleId(packageName);
|
||||||
if (mid == -1) return false;
|
if (mid == -1) return false;
|
||||||
db.delete("enabled_modules", "mid = ?", new String[]{String.valueOf(mid)});
|
try {
|
||||||
|
db.beginTransaction();
|
||||||
|
db.delete("modules", "mid = ?", new String[]{String.valueOf(mid)});
|
||||||
db.delete("scope", "mid = ?", new String[]{String.valueOf(mid)});
|
db.delete("scope", "mid = ?", new String[]{String.valueOf(mid)});
|
||||||
} finally {
|
} finally {
|
||||||
db.setTransactionSuccessful();
|
db.setTransactionSuccessful();
|
||||||
|
|
@ -274,6 +297,39 @@ public class ConfigManager {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean disableModule(String packageName) {
|
||||||
|
int mid = getModuleId(packageName);
|
||||||
|
if (mid == -1) return false;
|
||||||
|
try {
|
||||||
|
db.beginTransaction();
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put("enabled", 0);
|
||||||
|
db.update("modules", values, "mid = ?", new String[]{String.valueOf(mid)});
|
||||||
|
} finally {
|
||||||
|
db.setTransactionSuccessful();
|
||||||
|
db.endTransaction();
|
||||||
|
}
|
||||||
|
cacheScopes();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean enableModule(String packageName, String apkPath) {
|
||||||
|
if (!updateModuleApkPath(packageName, apkPath)) return false;
|
||||||
|
int mid = getModuleId(packageName);
|
||||||
|
if (mid == -1) return false;
|
||||||
|
try {
|
||||||
|
db.beginTransaction();
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put("enabled", 1);
|
||||||
|
db.update("modules", values, "mid = ?", new String[]{String.valueOf(mid)});
|
||||||
|
} finally {
|
||||||
|
db.setTransactionSuccessful();
|
||||||
|
db.endTransaction();
|
||||||
|
}
|
||||||
|
cacheScopes();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean removeApp(int uid) {
|
public boolean removeApp(int uid) {
|
||||||
int count = db.delete("scope", "uid = ?", new String[]{String.valueOf(uid)});
|
int count = db.delete("scope", "uid = ?", new String[]{String.valueOf(uid)});
|
||||||
if (count >= 1) {
|
if (count >= 1) {
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,14 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
||||||
int uid = Binder.getCallingUid();
|
int uid = Binder.getCallingUid();
|
||||||
int pid = Binder.getCallingPid();
|
int pid = Binder.getCallingPid();
|
||||||
cache.add(new Pair<>(uid, pid));
|
cache.add(new Pair<>(uid, pid));
|
||||||
handle.linkToDeath(() -> {
|
handle.linkToDeath(new DeathRecipient() {
|
||||||
|
@Override
|
||||||
|
public void binderDied() {
|
||||||
Log.d(TAG, "pid=" + pid + " uid=" + uid + " is dead.");
|
Log.d(TAG, "pid=" + pid + " uid=" + uid + " is dead.");
|
||||||
cache.remove(new Pair<>(uid, pid));
|
cache.remove(new Pair<>(uid, pid));
|
||||||
handles.remove(handle);
|
handles.remove(handle);
|
||||||
|
handle.unlinkToDeath(this, 0);
|
||||||
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,7 +47,7 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getModulesList() throws RemoteException {
|
public String[] getModulesList() throws RemoteException {
|
||||||
ensureRegistered();
|
ensureRegistered();
|
||||||
return ConfigManager.getInstance().getModulesPathForUid(Binder.getCallingUid());
|
return ConfigManager.getInstance().getModulesPathForUid(Binder.getCallingUid());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@ package io.github.lsposed.lspd.service;
|
||||||
|
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
import io.github.lsposed.lspd.ILSPManagerService;
|
import io.github.lsposed.lspd.ILSPManagerService;
|
||||||
import io.github.lsposed.lspd.utils.ParceledListSlice;
|
import io.github.lsposed.lspd.utils.ParceledListSlice;
|
||||||
|
|
@ -27,4 +30,76 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
public ParceledListSlice<PackageInfo> getInstalledPackagesFromAllUsers(int flags) throws RemoteException {
|
public ParceledListSlice<PackageInfo> getInstalledPackagesFromAllUsers(int flags) throws RemoteException {
|
||||||
return PackageService.getInstalledPackagesFromAllUsers(flags);
|
return PackageService.getInstalledPackagesFromAllUsers(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] enabledModules() {
|
||||||
|
return ConfigManager.getInstance().enabledModules();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean enableModule(String packageName) throws RemoteException {
|
||||||
|
PackageInfo pkgInfo = PackageService.getPackageInfo(packageName, 0, 0);
|
||||||
|
if (pkgInfo == null) return false;
|
||||||
|
return ConfigManager.getInstance().enableModule(packageName, pkgInfo.applicationInfo.sourceDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setModuleScope(String packageName, int[] uid) {
|
||||||
|
return ConfigManager.getInstance().setModuleScope(packageName, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getModuleScope(String packageName) {
|
||||||
|
return ConfigManager.getInstance().getModuleScope(packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean disableModule(String packageName) {
|
||||||
|
return ConfigManager.getInstance().disableModule(packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResourceHook() {
|
||||||
|
return ConfigManager.getInstance().resourceHook();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceHook(boolean enabled) {
|
||||||
|
ConfigManager.getInstance().setResourceHook(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVerboseLog() {
|
||||||
|
return ConfigManager.getInstance().verboseLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVerboseLog(boolean enabled) {
|
||||||
|
ConfigManager.getInstance().setVerboseLog(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getVariant() {
|
||||||
|
return ConfigManager.getInstance().variant();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVariant(int variant) {
|
||||||
|
ConfigManager.getInstance().setVariant(variant);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPermissive() {
|
||||||
|
return ConfigManager.getInstance().isPermissive();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParcelFileDescriptor getVerboseLog() {
|
||||||
|
return ConfigManager.getInstance().getVerboseLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParcelFileDescriptor getModulesLog() {
|
||||||
|
return ConfigManager.getInstance().getModulesLog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,34 @@ import io.github.lsposed.lspd.utils.ParceledListSlice;
|
||||||
|
|
||||||
interface ILSPManagerService {
|
interface ILSPManagerService {
|
||||||
int getVersion() = 1;
|
int getVersion() = 1;
|
||||||
|
|
||||||
ParceledListSlice<PackageInfo> getInstalledPackagesFromAllUsers(int flags) = 2;
|
ParceledListSlice<PackageInfo> getInstalledPackagesFromAllUsers(int flags) = 2;
|
||||||
|
|
||||||
|
String[] enabledModules() = 3;
|
||||||
|
|
||||||
|
boolean enableModule(String packageName) = 4;
|
||||||
|
|
||||||
|
boolean disableModule(String packageName) = 5;
|
||||||
|
|
||||||
|
boolean setModuleScope(String packageName, in int[] uid) = 6;
|
||||||
|
|
||||||
|
int[] getModuleScope(String packageName) = 7;
|
||||||
|
|
||||||
|
boolean isResourceHook() = 9;
|
||||||
|
|
||||||
|
void setResourceHook(boolean enabled) = 10;
|
||||||
|
|
||||||
|
boolean isVerboseLog() = 11;
|
||||||
|
|
||||||
|
void setVerboseLog(boolean enabled) = 12;
|
||||||
|
|
||||||
|
int getVariant() = 13;
|
||||||
|
|
||||||
|
void setVariant(int variant) = 14;
|
||||||
|
|
||||||
|
boolean isPermissive() = 15;
|
||||||
|
|
||||||
|
ParcelFileDescriptor getVerboseLog() = 16;
|
||||||
|
|
||||||
|
ParcelFileDescriptor getModulesLog() = 17;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue