Fix remote preferences listener not working on system_server (#2794)

This commit is contained in:
Nullptr 2023-10-09 15:04:41 +08:00 committed by GitHub
parent 7fef809d01
commit dd66cf2b07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 13 deletions

View File

@ -10,10 +10,10 @@ import androidx.annotation.Nullable;
import org.lsposed.lspd.service.ILSPInjectedModuleService; import org.lsposed.lspd.service.ILSPInjectedModuleService;
import org.lsposed.lspd.service.IRemotePreferenceCallback; import org.lsposed.lspd.service.IRemotePreferenceCallback;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -21,8 +21,7 @@ public class LSPosedRemotePreferences implements SharedPreferences {
private final Map<String, Object> mMap = new ConcurrentHashMap<>(); private final Map<String, Object> mMap = new ConcurrentHashMap<>();
private static final Object CONTENT = new Object(); final HashSet<OnSharedPreferenceChangeListener> mListeners = new HashSet<>();
final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners = new WeakHashMap<>();
IRemotePreferenceCallback callback = new IRemotePreferenceCallback.Stub() { IRemotePreferenceCallback callback = new IRemotePreferenceCallback.Stub() {
@Override @Override
@ -42,7 +41,7 @@ public class LSPosedRemotePreferences implements SharedPreferences {
} }
synchronized (mListeners) { synchronized (mListeners) {
for (var key : changes) { for (var key : changes) {
mListeners.keySet().forEach(listener -> listener.onSharedPreferenceChanged(LSPosedRemotePreferences.this, key)); mListeners.forEach(listener -> listener.onSharedPreferenceChanged(LSPosedRemotePreferences.this, key));
} }
} }
} }
@ -117,7 +116,7 @@ public class LSPosedRemotePreferences implements SharedPreferences {
@Override @Override
public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
synchronized (mListeners) { synchronized (mListeners) {
mListeners.put(listener, CONTENT); mListeners.add(listener);
} }
} }

View File

@ -215,6 +215,11 @@ public class ConfigManager {
var module = new Module(); var module = new Module();
module.apkPath = cursor.getString(apkPathIdx); module.apkPath = cursor.getString(apkPathIdx);
module.packageName = cursor.getString(pkgNameIdx); module.packageName = cursor.getString(pkgNameIdx);
var cached = cachedModule.get(module.packageName);
if (cached != null) {
modules.add(cached);
continue;
}
var statPath = toGlobalNamespace("/data/user_de/0/" + module.packageName).getAbsolutePath(); var statPath = toGlobalNamespace("/data/user_de/0/" + module.packageName).getAbsolutePath();
try { try {
module.appId = Os.stat(statPath).st_uid; module.appId = Os.stat(statPath).st_uid;
@ -229,7 +234,7 @@ public class ConfigManager {
} catch (PackageParser.PackageParserException e) { } catch (PackageParser.PackageParserException e) {
Log.w(TAG, "failed to parse " + module.apkPath, e); Log.w(TAG, "failed to parse " + module.apkPath, e);
} }
module.service = new LSPInjectedModuleService(module); module.service = new LSPInjectedModuleService(module.packageName);
modules.add(module); modules.add(module);
} }
} }
@ -548,7 +553,6 @@ public class ConfigManager {
var module = new Module(); var module = new Module();
module.packageName = packageName; module.packageName = packageName;
module.apkPath = apkPath; module.apkPath = apkPath;
module.service = new LSPInjectedModuleService(module);
modules.add(module); modules.add(module);
} }
@ -590,6 +594,7 @@ public class ConfigManager {
} }
m.appId = pkgInfo.applicationInfo.uid; m.appId = pkgInfo.applicationInfo.uid;
m.applicationInfo = pkgInfo.applicationInfo; m.applicationInfo = pkgInfo.applicationInfo;
m.service = oldModule != null ? oldModule.service : new LSPInjectedModuleService(m.packageName);
return true; return true;
}).forEach(m -> { }).forEach(m -> {
var file = ConfigFileManager.loadModule(m.apkPath, dexObfuscate); var file = ConfigFileManager.loadModule(m.apkPath, dexObfuscate);

View File

@ -21,12 +21,12 @@ public class LSPInjectedModuleService extends ILSPInjectedModuleService.Stub {
private static final String TAG = "LSPosedInjectedModuleService"; private static final String TAG = "LSPosedInjectedModuleService";
private final Module loadedModule; private final String mPackageName;
Map<String, Set<IRemotePreferenceCallback>> callbacks = new ConcurrentHashMap<>(); Map<String, Set<IRemotePreferenceCallback>> callbacks = new ConcurrentHashMap<>();
LSPInjectedModuleService(Module module) { LSPInjectedModuleService(String packageName) {
loadedModule = module; mPackageName = packageName;
} }
@Override @Override
@ -38,7 +38,7 @@ public class LSPInjectedModuleService extends ILSPInjectedModuleService.Stub {
public Bundle requestRemotePreferences(String group, IRemotePreferenceCallback callback) { public Bundle requestRemotePreferences(String group, IRemotePreferenceCallback callback) {
var bundle = new Bundle(); var bundle = new Bundle();
var userId = Binder.getCallingUid() / PER_USER_RANGE; var userId = Binder.getCallingUid() / PER_USER_RANGE;
bundle.putSerializable("map", ConfigManager.getInstance().getModulePrefs(loadedModule.packageName, userId, group)); bundle.putSerializable("map", ConfigManager.getInstance().getModulePrefs(mPackageName, userId, group));
if (callback != null) { if (callback != null) {
var groupCallbacks = callbacks.computeIfAbsent(group, k -> ConcurrentHashMap.newKeySet()); var groupCallbacks = callbacks.computeIfAbsent(group, k -> ConcurrentHashMap.newKeySet());
groupCallbacks.add(callback); groupCallbacks.add(callback);
@ -56,7 +56,7 @@ public class LSPInjectedModuleService extends ILSPInjectedModuleService.Stub {
ConfigFileManager.ensureModuleFilePath(path); ConfigFileManager.ensureModuleFilePath(path);
var userId = Binder.getCallingUid() / PER_USER_RANGE; var userId = Binder.getCallingUid() / PER_USER_RANGE;
try { try {
var dir = ConfigFileManager.resolveModuleDir(loadedModule.packageName, FILES_DIR, userId, -1); var dir = ConfigFileManager.resolveModuleDir(mPackageName, FILES_DIR, userId, -1);
return ParcelFileDescriptor.open(dir.resolve(path).toFile(), ParcelFileDescriptor.MODE_READ_ONLY); return ParcelFileDescriptor.open(dir.resolve(path).toFile(), ParcelFileDescriptor.MODE_READ_ONLY);
} catch (Throwable e) { } catch (Throwable e) {
throw new RemoteException(e.getMessage()); throw new RemoteException(e.getMessage());
@ -67,7 +67,7 @@ public class LSPInjectedModuleService extends ILSPInjectedModuleService.Stub {
public String[] getRemoteFileList() throws RemoteException { public String[] getRemoteFileList() throws RemoteException {
var userId = Binder.getCallingUid() / PER_USER_RANGE; var userId = Binder.getCallingUid() / PER_USER_RANGE;
try { try {
var dir = ConfigFileManager.resolveModuleDir(loadedModule.packageName, FILES_DIR, userId, -1); var dir = ConfigFileManager.resolveModuleDir(mPackageName, FILES_DIR, userId, -1);
var files = dir.toFile().list(); var files = dir.toFile().list();
return files == null ? new String[0] : files; return files == null ? new String[0] : files;