Implement module service
This commit is contained in:
parent
d29a3bf16e
commit
fb0ceca588
|
|
@ -57,15 +57,6 @@ public class ApplicationServiceClient implements ILSPApplicationService, IBinder
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder requestModuleBinder(String name) {
|
||||
try {
|
||||
return service.requestModuleBinder(name);
|
||||
} catch (RemoteException | NullPointerException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Module> getLegacyModulesList() {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import static org.lsposed.lspd.core.ApplicationServiceClient.serviceClient;
|
|||
import android.app.ActivityThread;
|
||||
import android.app.AndroidAppHelper;
|
||||
import android.app.LoadedApk;
|
||||
import android.os.IBinder;
|
||||
|
||||
import org.lsposed.lspd.impl.LSPosedContext;
|
||||
import org.lsposed.lspd.util.Hookers;
|
||||
|
|
@ -89,10 +88,7 @@ public class LoadedApkGetCLHooker extends XC_MethodHook {
|
|||
lpparam.appInfo = loadedApk.getApplicationInfo();
|
||||
lpparam.isFirstApplication = isFirstApplication;
|
||||
|
||||
IBinder moduleBinder = serviceClient.requestModuleBinder(lpparam.packageName);
|
||||
if (moduleBinder != null) {
|
||||
hookNewXSP(lpparam);
|
||||
}
|
||||
hookNewXSP(lpparam);
|
||||
|
||||
Hookers.logD("Call handleLoadedPackage: packageName=" + lpparam.packageName + " processName=" + lpparam.processName + " isFirstApplication=" + isFirstApplication + " classLoader=" + lpparam.classLoader + " appInfo=" + lpparam.appInfo);
|
||||
XC_LoadPackage.callAll(lpparam);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package io.github.libxposed.service;
|
||||
|
||||
import io.github.xposed.xposedservice.IXposedService;
|
||||
|
||||
public abstract class XposedService extends IXposedService.Stub {
|
||||
|
||||
public static final int API = 100;
|
||||
public static final String AUTHORITY_SUFFIX = ".XposedService";
|
||||
public static final String SEND_BINDER = "SendBinder";
|
||||
|
||||
@Override
|
||||
public final int getVersion() {
|
||||
return API;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ import android.annotation.SuppressLint;
|
|||
import android.app.IActivityManager;
|
||||
import android.app.IApplicationThread;
|
||||
import android.app.IServiceConnection;
|
||||
import android.app.IUidObserver;
|
||||
import android.app.ProfilerInfo;
|
||||
import android.content.Context;
|
||||
import android.content.IContentProvider;
|
||||
|
|
@ -194,4 +195,9 @@ public class ActivityManagerService {
|
|||
}
|
||||
}
|
||||
|
||||
public static void registerUidObserver(IUidObserver observer, int which, int cutpoint, String callingPackage) throws RemoteException {
|
||||
IActivityManager am = getActivityManager();
|
||||
if (am == null) return;
|
||||
am.registerUidObserver(observer, which, cutpoint, callingPackage);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,15 +151,6 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
|||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder requestModuleBinder(String name) throws RemoteException {
|
||||
var processInfo = ensureRegistered();
|
||||
if (ConfigManager.getInstance().isModule(processInfo.uid, name)) {
|
||||
ConfigManager.getInstance().ensureModulePrefsPermission(processInfo.uid, name);
|
||||
return ServiceManager.getModuleService(name);
|
||||
} else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor requestInjectedManagerBinder(List<IBinder> binder) throws RemoteException {
|
||||
var processInfo = ensureRegistered();
|
||||
|
|
|
|||
|
|
@ -19,27 +19,95 @@
|
|||
|
||||
package org.lsposed.lspd.service;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.app.IUidObserver;
|
||||
import android.content.AttributionSource;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import org.lsposed.daemon.BuildConfig;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import io.github.xposed.xposedservice.IXposedService;
|
||||
import hidden.HiddenApiBridge;
|
||||
import io.github.libxposed.service.XposedService;
|
||||
|
||||
public class LSPModuleService extends IXposedService.Stub {
|
||||
public class LSPModuleService extends XposedService {
|
||||
|
||||
final private String name;
|
||||
private static final String TAG = "LSPosedModuleService";
|
||||
|
||||
public LSPModuleService(String name) {
|
||||
this.name = name;
|
||||
private final Set<Integer> uidSet = ConcurrentHashMap.newKeySet();
|
||||
private final IUidObserver uidObserver = new IUidObserver.Stub() {
|
||||
@Override
|
||||
public void onUidActive(int uid) {
|
||||
uidStarts(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidCachedChanged(int uid, boolean cached) {
|
||||
if (!cached) uidStarts(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidIdle(int uid, boolean disabled) {
|
||||
uidStarts(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidGone(int uid, boolean disabled) {
|
||||
uidSet.remove(uid);
|
||||
}
|
||||
};
|
||||
|
||||
void registerObserver() {
|
||||
uidSet.clear();
|
||||
int flags = HiddenApiBridge.ActivityManager_UID_OBSERVER_ACTIVE()
|
||||
| HiddenApiBridge.ActivityManager_UID_OBSERVER_GONE()
|
||||
| HiddenApiBridge.ActivityManager_UID_OBSERVER_IDLE()
|
||||
| HiddenApiBridge.ActivityManager_UID_OBSERVER_CACHED();
|
||||
try {
|
||||
ActivityManagerService.registerUidObserver(uidObserver, flags, HiddenApiBridge.ActivityManager_PROCESS_STATE_UNKNOWN(), null);
|
||||
Log.i(TAG, "registered uid observer");
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "failed to register uid observer", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
return this;
|
||||
private void uidStarts(int uid) {
|
||||
if (!uidSet.contains(uid)) {
|
||||
uidSet.add(uid);
|
||||
var module = ConfigManager.getInstance().getModule(uid);
|
||||
if (module != null) sendBinder(uid, module);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return BuildConfig.API_CODE;
|
||||
private void sendBinder(int uid, String name) {
|
||||
try {
|
||||
int userId = uid / PackageService.PER_USER_RANGE;
|
||||
var authority = name + AUTHORITY_SUFFIX;
|
||||
var provider = ActivityManagerService.getContentProvider(authority, userId);
|
||||
if (provider == null) {
|
||||
Log.d(TAG, "no service provider for " + name);
|
||||
return;
|
||||
}
|
||||
var extra = new Bundle();
|
||||
extra.putBinder("binder", asBinder());
|
||||
Bundle reply = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
reply = provider.call(new AttributionSource.Builder(1000).setPackageName("android").build(),
|
||||
authority, SEND_BINDER, null, extra);
|
||||
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
|
||||
reply = provider.call("android", null, authority, SEND_BINDER, null, extra);
|
||||
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
|
||||
reply = provider.call("android", authority, SEND_BINDER, null, extra);
|
||||
}
|
||||
if (reply != null) {
|
||||
Log.d(TAG, "sent module binder to " + name);
|
||||
} else {
|
||||
Log.w(TAG, "failed to send module binder to " + name);
|
||||
}
|
||||
} catch (RemoteException | NoSuchMethodError e) {
|
||||
Log.w(TAG, "failed to send module binder for uid " + uid, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ import com.android.internal.os.BinderInternal;
|
|||
import org.lsposed.daemon.BuildConfig;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
|
|
@ -44,12 +43,12 @@ import hidden.HiddenApiBridge;
|
|||
|
||||
public class ServiceManager {
|
||||
public static final String TAG = "LSPosedService";
|
||||
private static final ConcurrentHashMap<String, LSPModuleService> moduleServices = new ConcurrentHashMap<>();
|
||||
private static final File globalNamespace = new File("/proc/1/root");
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private static LSPosedService mainService = null;
|
||||
private static LSPApplicationService applicationService = null;
|
||||
private static LSPManagerService managerService = null;
|
||||
private static LSPModuleService moduleService = null;
|
||||
private static LSPSystemServerService systemServerService = null;
|
||||
private static LogcatService logcatService = null;
|
||||
private static Dex2OatService dex2OatService = null;
|
||||
|
|
@ -114,6 +113,7 @@ public class ServiceManager {
|
|||
mainService = new LSPosedService();
|
||||
applicationService = new LSPApplicationService();
|
||||
managerService = new LSPManagerService();
|
||||
moduleService = new LSPModuleService();
|
||||
systemServerService = new LSPSystemServerService(systemServerMaxRetry);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
dex2OatService = new Dex2OatService();
|
||||
|
|
@ -142,6 +142,7 @@ public class ServiceManager {
|
|||
@Override
|
||||
public void onSystemServerRestarted() {
|
||||
Log.w(TAG, "system restarted...");
|
||||
moduleService.registerObserver();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -152,6 +153,7 @@ public class ServiceManager {
|
|||
Log.w(TAG, "no response from bridge");
|
||||
}
|
||||
systemServerService.maybeRetryInject();
|
||||
moduleService.registerObserver();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -171,10 +173,6 @@ public class ServiceManager {
|
|||
throw new RuntimeException("Main thread loop unexpectedly exited");
|
||||
}
|
||||
|
||||
public static LSPModuleService getModuleService(String module) {
|
||||
return moduleServices.computeIfAbsent(module, LSPModuleService::new);
|
||||
}
|
||||
|
||||
public static LSPApplicationService getApplicationService() {
|
||||
return applicationService;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package hidden;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
|
@ -127,4 +128,24 @@ public class HiddenApiBridge {
|
|||
return Os.ioctlInt(fd, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public static int ActivityManager_UID_OBSERVER_GONE() {
|
||||
return ActivityManager.UID_OBSERVER_GONE;
|
||||
}
|
||||
|
||||
public static int ActivityManager_UID_OBSERVER_ACTIVE() {
|
||||
return ActivityManager.UID_OBSERVER_ACTIVE;
|
||||
}
|
||||
|
||||
public static int ActivityManager_UID_OBSERVER_IDLE() {
|
||||
return ActivityManager.UID_OBSERVER_IDLE;
|
||||
}
|
||||
|
||||
public static int ActivityManager_UID_OBSERVER_CACHED() {
|
||||
return ActivityManager.UID_OBSERVER_CACHED;
|
||||
}
|
||||
|
||||
public static int ActivityManager_PROCESS_STATE_UNKNOWN() {
|
||||
return ActivityManager.PROCESS_STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package android.app;
|
||||
|
||||
public class ActivityManager {
|
||||
public static int UID_OBSERVER_GONE;
|
||||
public static int UID_OBSERVER_ACTIVE;
|
||||
public static int UID_OBSERVER_IDLE;
|
||||
public static int UID_OBSERVER_CACHED;
|
||||
public static int PROCESS_STATE_UNKNOWN;
|
||||
}
|
||||
|
|
@ -40,6 +40,7 @@ public interface IActivityManager extends IInterface {
|
|||
String[] requiredPermissions, String[] excludedPermissions,
|
||||
String[] excludePackages, int appOp, Bundle bOptions,
|
||||
boolean serialized, boolean sticky, int userId) throws RemoteException;
|
||||
|
||||
@RequiresApi(31)
|
||||
int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId,
|
||||
Intent intent, String resolvedType, IIntentReceiver resultTo,
|
||||
|
|
@ -122,6 +123,8 @@ public interface IActivityManager extends IInterface {
|
|||
|
||||
Configuration getConfiguration() throws RemoteException;
|
||||
|
||||
void registerUidObserver(IUidObserver observer, int which, int cutpoint, String callingPackage) throws RemoteException;
|
||||
|
||||
abstract class Stub extends Binder implements IActivityManager {
|
||||
public static int TRANSACTION_setActivityController;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
package android.app;
|
||||
|
||||
import android.os.Binder;
|
||||
|
||||
public interface IUidObserver {
|
||||
|
||||
void onUidGone(int uid, boolean disabled);
|
||||
|
||||
void onUidActive(int uid);
|
||||
|
||||
void onUidIdle(int uid, boolean disabled);
|
||||
|
||||
void onUidCachedChanged(int uid, boolean cached);
|
||||
|
||||
abstract class Stub extends Binder implements IUidObserver {
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,6 @@ package org.lsposed.lspd.service;
|
|||
import org.lsposed.lspd.models.Module;
|
||||
|
||||
interface ILSPApplicationService {
|
||||
IBinder requestModuleBinder(String name);
|
||||
|
||||
List<Module> getLegacyModulesList();
|
||||
|
||||
List<Module> getModulesList();
|
||||
|
|
|
|||
Loading…
Reference in New Issue