Service for each module

This commit is contained in:
LoveSy 2023-01-02 22:59:55 +08:00 committed by LoveSy
parent 4c54e36bf1
commit acaf40ca44
6 changed files with 85 additions and 75 deletions

View File

@ -338,7 +338,7 @@ public class LSPosedContext extends XposedContext {
@Override
public File getCacheDir() {
throw new AbstractMethodError();
return mBase.getCacheDir();
}
@Override

View File

@ -23,65 +23,40 @@ 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 java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import hidden.HiddenApiBridge;
import io.github.libxposed.service.XposedService;
import io.github.libxposed.service.IXposedService;
public class LSPModuleService extends XposedService {
public class LSPModuleService extends IXposedService.Stub {
private static final String TAG = "LSPosedModuleService";
private final static String TAG = "LSPosedModuleService";
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);
}
private final static Set<Integer> uidSet = ConcurrentHashMap.newKeySet();
private final static Map<Integer, LSPModuleService> serviceMap = new ConcurrentHashMap<>();
@Override
public void onUidIdle(int uid, boolean disabled) {
uidStarts(uid);
}
private final int uid;
private final String packageName;
@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);
}
}
private void uidStarts(int uid) {
static void uidStarts(int uid) {
if (!uidSet.contains(uid)) {
uidSet.add(uid);
var module = ConfigManager.getInstance().getModule(uid);
if (module != null) sendBinder(uid, module);
sendBinder(getService(uid));
}
}
private void sendBinder(int uid, String name) {
static void uidGone(int uid) {
uidSet.remove(uid);
}
private static void sendBinder(LSPModuleService service) {
if (service == null) return;
var uid = service.uid;
var name = service.packageName;
try {
int userId = uid / PackageService.PER_USER_RANGE;
var authority = name + AUTHORITY_SUFFIX;
@ -91,7 +66,7 @@ public class LSPModuleService extends XposedService {
return;
}
var extra = new Bundle();
extra.putBinder("binder", asBinder());
extra.putBinder("binder", service.asBinder());
Bundle reply = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
reply = provider.call(new AttributionSource.Builder(1000).setPackageName("android").build(),
@ -106,8 +81,28 @@ public class LSPModuleService extends XposedService {
} else {
Log.w(TAG, "failed to send module binder to " + name);
}
} catch (RemoteException | NoSuchMethodError e) {
} catch (Throwable e) {
Log.w(TAG, "failed to send module binder for uid " + uid, e);
}
}
public static LSPModuleService getService(int uid) {
var module = ConfigManager.getInstance().getModule(uid);
if (module == null) return null;
return serviceMap.computeIfAbsent(uid, __ -> new LSPModuleService(module, uid));
}
public static void removeService(int uid) {
serviceMap.remove(uid);
}
private LSPModuleService(String name, int uid) {
this.uid = uid;
this.packageName = name;
}
@Override
public long getAPIVersion() {
return API;
}
}

View File

@ -19,11 +19,14 @@
package org.lsposed.lspd.service;
import static android.content.Intent.EXTRA_UID;
import static org.lsposed.lspd.service.PackageService.PER_USER_RANGE;
import static org.lsposed.lspd.service.ServiceManager.TAG;
import static org.lsposed.lspd.service.ServiceManager.getExecutorService;
import android.app.ActivityManager;
import android.app.IApplicationThread;
import android.app.IUidObserver;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.IntentFilter;
@ -45,6 +48,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import hidden.HiddenApiBridge;
public class LSPosedService extends ILSPosedService.Stub {
private static final int AID_NOBODY = 9999;
private static final int USER_NULL = -10000;
@ -63,8 +68,7 @@ public class LSPosedService extends ILSPosedService.Stub {
Log.d(TAG, "Skipped duplicated request for uid " + uid + " pid " + pid);
return null;
}
if (!ServiceManager.getManagerService().shouldStartManager(pid, uid, processName) &&
ConfigManager.getInstance().shouldSkipProcess(new ConfigManager.ProcessScope(processName, uid))) {
if (!ServiceManager.getManagerService().shouldStartManager(pid, uid, processName) && ConfigManager.getInstance().shouldSkipProcess(new ConfigManager.ProcessScope(processName, uid))) {
Log.d(TAG, "Skipped " + processName + "/" + uid);
return null;
}
@ -85,7 +89,7 @@ public class LSPosedService extends ILSPosedService.Stub {
private void dispatchPackageChanged(Intent intent) {
if (intent == null) return;
int uid = intent.getIntExtra(Intent.EXTRA_UID, AID_NOBODY);
int uid = intent.getIntExtra(EXTRA_UID, AID_NOBODY);
if (uid == AID_NOBODY || uid <= 0) return;
int userId = intent.getIntExtra("android.intent.extra.user_handle", USER_NULL);
var intentAction = intent.getAction();
@ -102,9 +106,7 @@ public class LSPosedService extends ILSPosedService.Stub {
}
}
boolean isXposedModule = applicationInfo != null &&
applicationInfo.metaData != null &&
applicationInfo.metaData.containsKey("xposedminversion");
boolean isXposedModule = applicationInfo != null && applicationInfo.metaData != null && applicationInfo.metaData.containsKey("xposedminversion");
switch (intentAction) {
case Intent.ACTION_PACKAGE_FULLY_REMOVED: {
@ -160,8 +162,7 @@ public class LSPosedService extends ILSPosedService.Stub {
break;
}
}
boolean removed = Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(intentAction) ||
Intent.ACTION_UID_REMOVED.equals(intentAction);
boolean removed = Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(intentAction) || Intent.ACTION_UID_REMOVED.equals(intentAction);
Log.d(TAG, "Package changed: uid=" + uid + " userId=" + userId + " action=" + intentAction + " isXposedModule=" + isXposedModule + " isAllUsers=" + allUsers);
@ -182,8 +183,7 @@ public class LSPosedService extends ILSPosedService.Stub {
if (isXposedModule) {
var enabledModules = ConfigManager.getInstance().enabledModules();
var scope = ConfigManager.getInstance().getModuleScope(packageName);
boolean systemModule = scope != null &&
scope.parallelStream().anyMatch(app -> app.packageName.equals("android"));
boolean systemModule = scope != null && scope.parallelStream().anyMatch(app -> app.packageName.equals("android"));
boolean enabled = Arrays.asList(enabledModules).contains(packageName);
if (!(Intent.ACTION_UID_REMOVED.equals(action) || Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action) || allUsers))
LSPNotificationManager.notifyModuleUpdated(packageName, userId, enabled, systemModule);
@ -314,11 +314,38 @@ public class LSPosedService extends ILSPosedService.Stub {
var moduleFilter = new IntentFilter(intentFilter);
moduleFilter.addDataScheme("module");
registerReceiver(List.of(intentFilter, moduleFilter),
"android.permission.BRICK", 0, this::dispatchOpenManager);
registerReceiver(List.of(intentFilter, moduleFilter), "android.permission.BRICK", 0, this::dispatchOpenManager);
Log.d(TAG, "registered open manager receiver");
}
private void registerUidObserver() {
try {
ActivityManagerService.registerUidObserver(new IUidObserver.Stub() {
@Override
public void onUidActive(int uid) {
LSPModuleService.uidStarts(uid);
}
@Override
public void onUidCachedChanged(int uid, boolean cached) {
if (!cached) LSPModuleService.uidStarts(uid);
}
@Override
public void onUidIdle(int uid, boolean disabled) {
LSPModuleService.uidStarts(uid);
}
@Override
public void onUidGone(int uid, boolean disabled) {
LSPModuleService.uidGone(uid);
}
}, HiddenApiBridge.ActivityManager_UID_OBSERVER_ACTIVE() | HiddenApiBridge.ActivityManager_UID_OBSERVER_GONE() | HiddenApiBridge.ActivityManager_UID_OBSERVER_IDLE() | HiddenApiBridge.ActivityManager_UID_OBSERVER_CACHED(), HiddenApiBridge.ActivityManager_PROCESS_STATE_UNKNOWN(), null);
} catch (RemoteException e) {
Log.e(TAG, "registerUidObserver", e);
}
}
@Override
public void dispatchSystemServerContext(IBinder activityThread, IBinder activityToken, String api) {
Log.d(TAG, "received system context");
@ -330,6 +357,7 @@ public class LSPosedService extends ILSPosedService.Stub {
registerBootCompleteReceiver();
registerUserChangeReceiver();
registerOpenManagerReceiver();
registerUidObserver();
}
@Override

View File

@ -48,7 +48,6 @@ public class ServiceManager {
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;
@ -113,7 +112,6 @@ 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,7 +140,6 @@ public class ServiceManager {
@Override
public void onSystemServerRestarted() {
Log.w(TAG, "system restarted...");
moduleService.registerObserver();
}
@Override
@ -153,7 +150,6 @@ public class ServiceManager {
Log.w(TAG, "no response from bridge");
}
systemServerService.maybeRetryInject();
moduleService.registerObserver();
}
@Override

View File

@ -1,5 +1,9 @@
package io.github.libxposed.service;
interface IXposedService {
const int API = 100;
const String AUTHORITY_SUFFIX = ".XposedService";
const String SEND_BINDER = "SendBinder";
long getAPIVersion() = 1;
}

View File

@ -1,13 +0,0 @@
package io.github.libxposed.service;
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 long getAPIVersion() {
return API;
}
}