From acaf40ca449e4ab0fd9d1fd70dbf54820f63f5a1 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Mon, 2 Jan 2023 22:59:55 +0800 Subject: [PATCH] Service for each module --- .../org/lsposed/lspd/impl/LSPosedContext.java | 2 +- .../lspd/service/LSPModuleService.java | 85 +++++++++---------- .../lsposed/lspd/service/LSPosedService.java | 52 +++++++++--- .../lsposed/lspd/service/ServiceManager.java | 4 - .../libxposed/service/IXposedService.aidl | 4 + .../libxposed/service/XposedService.java | 13 --- 6 files changed, 85 insertions(+), 75 deletions(-) delete mode 100644 libxposed/service/src/main/java/io/github/libxposed/service/XposedService.java diff --git a/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java b/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java index 58b42428..8777cf05 100644 --- a/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java +++ b/core/src/main/java/org/lsposed/lspd/impl/LSPosedContext.java @@ -338,7 +338,7 @@ public class LSPosedContext extends XposedContext { @Override public File getCacheDir() { - throw new AbstractMethodError(); + return mBase.getCacheDir(); } @Override diff --git a/daemon/src/main/java/org/lsposed/lspd/service/LSPModuleService.java b/daemon/src/main/java/org/lsposed/lspd/service/LSPModuleService.java index 195c75a0..c655dca0 100644 --- a/daemon/src/main/java/org/lsposed/lspd/service/LSPModuleService.java +++ b/daemon/src/main/java/org/lsposed/lspd/service/LSPModuleService.java @@ -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 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 uidSet = ConcurrentHashMap.newKeySet(); + private final static Map 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; + } } diff --git a/daemon/src/main/java/org/lsposed/lspd/service/LSPosedService.java b/daemon/src/main/java/org/lsposed/lspd/service/LSPosedService.java index 55750498..86b20458 100644 --- a/daemon/src/main/java/org/lsposed/lspd/service/LSPosedService.java +++ b/daemon/src/main/java/org/lsposed/lspd/service/LSPosedService.java @@ -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 diff --git a/daemon/src/main/java/org/lsposed/lspd/service/ServiceManager.java b/daemon/src/main/java/org/lsposed/lspd/service/ServiceManager.java index b7d32f75..6982cd82 100644 --- a/daemon/src/main/java/org/lsposed/lspd/service/ServiceManager.java +++ b/daemon/src/main/java/org/lsposed/lspd/service/ServiceManager.java @@ -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 diff --git a/libxposed/service/src/main/aidl/io/github/libxposed/service/IXposedService.aidl b/libxposed/service/src/main/aidl/io/github/libxposed/service/IXposedService.aidl index 44392f87..bc1f1d4a 100644 --- a/libxposed/service/src/main/aidl/io/github/libxposed/service/IXposedService.aidl +++ b/libxposed/service/src/main/aidl/io/github/libxposed/service/IXposedService.aidl @@ -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; } diff --git a/libxposed/service/src/main/java/io/github/libxposed/service/XposedService.java b/libxposed/service/src/main/java/io/github/libxposed/service/XposedService.java deleted file mode 100644 index 7fcde5b5..00000000 --- a/libxposed/service/src/main/java/io/github/libxposed/service/XposedService.java +++ /dev/null @@ -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; - } -}