fix: improve service fallback and module loading

This commit is contained in:
NkBe 2025-10-01 17:51:27 +08:00
parent 9804125d1f
commit dbacad9876
No known key found for this signature in database
GPG Key ID: 75EF144ED8F4D7B8
3 changed files with 64 additions and 43 deletions

View File

@ -83,6 +83,7 @@ public class LSPApplication {
Log.d(TAG, "Initialize service client");
ILSPApplicationService service;
if (config.useManager) {
try {
service = new RemoteApplicationService(context);
@ -95,14 +96,14 @@ public class LSPApplication {
moduleArr.put(moduleObj);
}
SharedPreferences shared = context.getSharedPreferences("npatch", Context.MODE_PRIVATE);
shared.edit().putString("modules",moduleArr.toString()).commit();
Log.e(TAG, "Success update module scope");
shared.edit().putString("modules",moduleArr.toString()).apply();
Log.i(TAG, "Success update module scope from Manager");
}catch (Exception e){
Log.e(TAG, "Failed to connect to manager, fallback to fixed local service");
Log.e(TAG, "Failed to connect to manager, fallback to fixed local service (NLAS)");
service = new NeoLocalApplicationService(context);
}
} else {
Log.i(TAG, "Manager is disabled, using remote service (NLAS)");
service = new NeoLocalApplicationService(context);
}

View File

@ -17,39 +17,50 @@ import org.lsposed.lspd.service.ILSPApplicationService;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class NeoLocalApplicationService extends ILSPApplicationService.Stub {
private static final String TAG = "NPatch";
private final List<Module> cachedModule;
public NeoLocalApplicationService(Context context) {
SharedPreferences shared = context.getSharedPreferences("npatch", Context.MODE_PRIVATE);
cachedModule = new ArrayList<>();
cachedModule = Collections.synchronizedList(new ArrayList<>());
loadModulesFromSharedPreferences(context);
}
private void loadModulesFromSharedPreferences(Context context) {
var shared = context.getSharedPreferences("npatch", Context.MODE_PRIVATE);
try {
JSONArray mArr = new JSONArray(shared.getString("modules", "{}"));
Log.i(TAG,"use fixed local application service:"+shared.getString("modules", "{}"));
String modulesJsonString = shared.getString("modules", "[]");
Log.i(TAG, "using local application service with modules:" + modulesJsonString);
if (modulesJsonString.equals("{}")) {
modulesJsonString = "[]";
}
var mArr = new JSONArray(modulesJsonString);
for (int i = 0; i < mArr.length(); i++) {
JSONObject mObj = mArr.getJSONObject(i);
Module m = new Module();
String path = mObj.getString("path");
String packageName = mObj.getString("packageName");
m.apkPath = path;
m.packageName = packageName;
if (!new File(m.apkPath).exists()){
Log.i("NPatch","Module:" + m.packageName + " path not available, reset.");
var mObj = mArr.getJSONObject(i);
var m = new Module();
m.apkPath = mObj.getString("path");
m.packageName = mObj.getString("packageName");
if (m.apkPath == null || !new File(m.apkPath).exists()) {
Log.w(TAG, "Module:" + m.packageName + " path not available, attempting reset.");
try {
ApplicationInfo info = context.getPackageManager().getApplicationInfo(m.packageName, 0);
m.apkPath = info.sourceDir;
Log.i("NPatch","Module:" + m.packageName + " path reset to " + m.apkPath);
Log.i(TAG, "Module:" + m.packageName + " path reset to " + m.apkPath);
} catch (Exception e) {
Log.e("NPatch",Log.getStackTraceString(e));
Log.e(TAG, "Failed to get ApplicationInfo for module: " + m.packageName, e);
continue;
}
}
m.file = ModuleLoader.loadModule(m.apkPath);
cachedModule.add(m);
}
}catch (Exception e){
Log.e(TAG,Log.getStackTraceString(e));
} catch (Throwable e) {
Log.e(TAG, "Error loading modules from SharedPreferences.", e);
}
}

View File

@ -37,7 +37,6 @@ public class RemoteApplicationService implements ILSPApplicationService {
@SuppressLint("DiscouragedPrivateApi")
public RemoteApplicationService(Context context) throws RemoteException {
try {
var intent = new Intent()
.setComponent(new ComponentName(Constants.MANAGER_PACKAGE_NAME, MODULE_SERVICE))
.putExtra("packageName", context.getPackageName());
@ -58,6 +57,7 @@ public class RemoteApplicationService implements ILSPApplicationService {
}
};
Log.i(TAG, "Request manager binder");
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
context.bindService(intent, Context.BIND_AUTO_CREATE, Executors.newSingleThreadExecutor(), conn);
} else {
@ -72,7 +72,16 @@ public class RemoteApplicationService implements ILSPApplicationService {
bindServiceAsUserMethod.invoke(context, intent, conn, Context.BIND_AUTO_CREATE, handler, userHandle);
}
boolean success = latch.await(1, TimeUnit.SECONDS);
if (!success) throw new TimeoutException("Bind service timeout");
if (!success) {
// Attempt to unbind the service before throwing a timeout for cleanup
try {
context.unbindService(conn);
} catch (IllegalArgumentException | IllegalStateException ignored) {
// Ignored
}
throw new TimeoutException("Bind service timeout");
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException |
InterruptedException | TimeoutException e) {
var r = new RemoteException("Failed to get manager binder");