Implement RemotePreferences edit
This commit is contained in:
parent
cfe15100c0
commit
87db036fdf
|
|
@ -2,7 +2,6 @@ package org.lsposed.lspd.impl;
|
|||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
|
@ -53,8 +52,10 @@ public class LSPosedRemotePreferences implements SharedPreferences {
|
|||
public LSPosedRemotePreferences(ILSPInjectedModuleService service, String group) {
|
||||
try {
|
||||
Bundle output = service.requestRemotePreferences(group, callback);
|
||||
callback.onUpdate(output);
|
||||
} catch (RemoteException e) {
|
||||
if (output.containsKey("map")) {
|
||||
mMap.putAll((Map<String, Object>) output.getSerializable("map"));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
XposedBridge.log(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import android.content.res.AssetManager;
|
|||
import android.content.res.Resources;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SELinux;
|
||||
import android.os.SharedMemory;
|
||||
import android.system.ErrnoException;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import android.os.SystemClock;
|
|||
import android.permission.IPermissionManager;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
|
|
@ -447,21 +448,35 @@ public class ConfigManager {
|
|||
}
|
||||
|
||||
public void updateModulePrefs(String moduleName, int userId, String group, String key, Object value) {
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put(key, value);
|
||||
updateModulePrefs(moduleName, userId, group, values);
|
||||
}
|
||||
|
||||
public void updateModulePrefs(String moduleName, int userId, String group, Map<String, Object> values) {
|
||||
var config = cachedConfig.computeIfAbsent(new Pair<>(moduleName, userId), module -> fetchModuleConfig(module.first, module.second));
|
||||
var prefs = config.computeIfAbsent(group, g -> new ConcurrentHashMap<>());
|
||||
if (value instanceof Serializable) {
|
||||
prefs.put(key, value);
|
||||
var values = new ContentValues();
|
||||
values.put("`group`", group);
|
||||
values.put("`key`", key);
|
||||
values.put("data", SerializationUtils.serialize((Serializable) value));
|
||||
values.put("module_pkg_name", moduleName);
|
||||
values.put("user_id", String.valueOf(userId));
|
||||
db.insertWithOnConflict("configs", null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
} else {
|
||||
prefs.remove(key);
|
||||
db.delete("configs", "module_pkg_name=? and user_id=? and `group`=? and `key`=?", new String[]{moduleName, String.valueOf(userId), group, key});
|
||||
}
|
||||
executeInTransaction(() -> {
|
||||
var contents = new ContentValues();
|
||||
for (var entry : values.entrySet()) {
|
||||
var key = entry.getKey();
|
||||
var value = entry.getValue();
|
||||
if (value instanceof Serializable) {
|
||||
prefs.put(key, value);
|
||||
contents.put("`group`", group);
|
||||
contents.put("`key`", key);
|
||||
contents.put("data", SerializationUtils.serialize((Serializable) value));
|
||||
contents.put("module_pkg_name", moduleName);
|
||||
contents.put("user_id", String.valueOf(userId));
|
||||
} else {
|
||||
prefs.remove(key);
|
||||
db.delete("configs", "module_pkg_name=? and user_id=? and `group`=? and `key`=?", new String[]{moduleName, String.valueOf(userId), group, key});
|
||||
}
|
||||
if (contents.size() > 0) {
|
||||
db.insertWithOnConflict("configs", null, contents, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<String, Object> getModulePrefs(String moduleName, int userId, String group) {
|
||||
|
|
|
|||
|
|
@ -19,19 +19,26 @@
|
|||
|
||||
package org.lsposed.lspd.service;
|
||||
|
||||
import static org.lsposed.lspd.service.PackageService.PER_USER_RANGE;
|
||||
|
||||
import android.content.AttributionSource;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.lsposed.daemon.BuildConfig;
|
||||
import org.lsposed.lspd.models.Module;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
|
@ -44,7 +51,8 @@ public class LSPModuleService extends IXposedService.Stub {
|
|||
|
||||
private final static Set<Integer> uidSet = ConcurrentHashMap.newKeySet();
|
||||
|
||||
private final Module loadedModule;
|
||||
private final @NonNull
|
||||
Module loadedModule;
|
||||
|
||||
static void uidStarts(int uid) {
|
||||
if (!uidSet.contains(uid)) {
|
||||
|
|
@ -90,32 +98,44 @@ public class LSPModuleService extends IXposedService.Stub {
|
|||
}
|
||||
}
|
||||
|
||||
LSPModuleService(Module module) {
|
||||
LSPModuleService(@NonNull Module module) {
|
||||
loadedModule = module;
|
||||
}
|
||||
|
||||
private void ensureModule() throws RemoteException {
|
||||
var appId = Binder.getCallingUid() % PackageService.PER_USER_RANGE;
|
||||
if (loadedModule.appId != appId) {
|
||||
throw new RemoteException("Module " + loadedModule.packageName + " is not for uid " + Binder.getCallingUid());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAPIVersion() {
|
||||
public int getAPIVersion() throws RemoteException {
|
||||
ensureModule();
|
||||
return API;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFrameworkName() {
|
||||
public String getFrameworkName() throws RemoteException {
|
||||
ensureModule();
|
||||
return "LSPosed";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFrameworkVersion() {
|
||||
public String getFrameworkVersion() throws RemoteException {
|
||||
ensureModule();
|
||||
return BuildConfig.VERSION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFrameworkVersionCode() {
|
||||
public long getFrameworkVersionCode() throws RemoteException {
|
||||
ensureModule();
|
||||
return BuildConfig.VERSION_CODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getScope() {
|
||||
public List<String> getScope() throws RemoteException {
|
||||
ensureModule();
|
||||
ArrayList<String> res = new ArrayList<>();
|
||||
var scope = ConfigManager.getInstance().getModuleScope(loadedModule.packageName);
|
||||
if (scope == null) return res;
|
||||
|
|
@ -126,19 +146,42 @@ public class LSPModuleService extends IXposedService.Stub {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void requestScope(String packageName) {
|
||||
public void requestScope(String packageName) throws RemoteException {
|
||||
ensureModule();
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle requestRemotePreferences(String group) {
|
||||
// TODO
|
||||
return null;
|
||||
public Bundle requestRemotePreferences(String group) throws RemoteException {
|
||||
ensureModule();
|
||||
var bundle = new Bundle();
|
||||
var userId = Binder.getCallingUid() % PER_USER_RANGE;
|
||||
bundle.putSerializable("map", ConfigManager.getInstance().getModulePrefs(loadedModule.packageName, userId, group));
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRemotePreferences(String group, Bundle diff) {
|
||||
// TODO
|
||||
public void updateRemotePreferences(String group, Bundle diff) throws RemoteException {
|
||||
ensureModule();
|
||||
var userId = Binder.getCallingUid() / PackageService.PER_USER_RANGE;
|
||||
Map<String, Object> values = new ArrayMap<>();
|
||||
if (diff.containsKey("delete")) {
|
||||
var deletes = diff.getStringArrayList("delete");
|
||||
for (var key : deletes) {
|
||||
values.put(key, null);
|
||||
}
|
||||
}
|
||||
if (diff.containsKey("put")) {
|
||||
try {
|
||||
var puts = (Map<?, ?>) diff.getSerializable("put");
|
||||
for (var entry : puts.entrySet()) {
|
||||
values.put((String) entry.getKey(), entry.getValue());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, "updateRemotePreferences: ", e);
|
||||
}
|
||||
}
|
||||
ConfigManager.getInstance().updateModulePrefs(loadedModule.packageName, userId, group, values);
|
||||
((LSPInjectedModuleService) loadedModule.service).onUpdateRemotePreferences(group, diff);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue