Service for each module
This commit is contained in:
parent
4c54e36bf1
commit
acaf40ca44
|
|
@ -338,7 +338,7 @@ public class LSPosedContext extends XposedContext {
|
|||
|
||||
@Override
|
||||
public File getCacheDir() {
|
||||
throw new AbstractMethodError();
|
||||
return mBase.getCacheDir();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue