fix: improve service fallback and module loading
This commit is contained in:
parent
9804125d1f
commit
dbacad9876
|
|
@ -83,6 +83,7 @@ public class LSPApplication {
|
||||||
|
|
||||||
Log.d(TAG, "Initialize service client");
|
Log.d(TAG, "Initialize service client");
|
||||||
ILSPApplicationService service;
|
ILSPApplicationService service;
|
||||||
|
|
||||||
if (config.useManager) {
|
if (config.useManager) {
|
||||||
try {
|
try {
|
||||||
service = new RemoteApplicationService(context);
|
service = new RemoteApplicationService(context);
|
||||||
|
|
@ -95,14 +96,14 @@ public class LSPApplication {
|
||||||
moduleArr.put(moduleObj);
|
moduleArr.put(moduleObj);
|
||||||
}
|
}
|
||||||
SharedPreferences shared = context.getSharedPreferences("npatch", Context.MODE_PRIVATE);
|
SharedPreferences shared = context.getSharedPreferences("npatch", Context.MODE_PRIVATE);
|
||||||
shared.edit().putString("modules",moduleArr.toString()).commit();
|
shared.edit().putString("modules",moduleArr.toString()).apply();
|
||||||
Log.e(TAG, "Success update module scope");
|
Log.i(TAG, "Success update module scope from Manager");
|
||||||
}catch (Exception e){
|
}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);
|
service = new NeoLocalApplicationService(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
Log.i(TAG, "Manager is disabled, using remote service (NLAS)");
|
||||||
service = new NeoLocalApplicationService(context);
|
service = new NeoLocalApplicationService(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,39 +17,50 @@ import org.lsposed.lspd.service.ILSPApplicationService;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class NeoLocalApplicationService extends ILSPApplicationService.Stub {
|
public class NeoLocalApplicationService extends ILSPApplicationService.Stub {
|
||||||
private static final String TAG = "NPatch";
|
private static final String TAG = "NPatch";
|
||||||
private final List<Module> cachedModule;
|
private final List<Module> cachedModule;
|
||||||
public NeoLocalApplicationService(Context context) {
|
public NeoLocalApplicationService(Context context) {
|
||||||
SharedPreferences shared = context.getSharedPreferences("npatch", Context.MODE_PRIVATE);
|
cachedModule = Collections.synchronizedList(new ArrayList<>());
|
||||||
cachedModule = new ArrayList<>();
|
loadModulesFromSharedPreferences(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadModulesFromSharedPreferences(Context context) {
|
||||||
|
var shared = context.getSharedPreferences("npatch", Context.MODE_PRIVATE);
|
||||||
try {
|
try {
|
||||||
JSONArray mArr = new JSONArray(shared.getString("modules", "{}"));
|
String modulesJsonString = shared.getString("modules", "[]");
|
||||||
Log.i(TAG,"use fixed local application service:"+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++) {
|
for (int i = 0; i < mArr.length(); i++) {
|
||||||
JSONObject mObj = mArr.getJSONObject(i);
|
var mObj = mArr.getJSONObject(i);
|
||||||
Module m = new Module();
|
var m = new Module();
|
||||||
String path = mObj.getString("path");
|
m.apkPath = mObj.getString("path");
|
||||||
String packageName = mObj.getString("packageName");
|
m.packageName = mObj.getString("packageName");
|
||||||
m.apkPath = path;
|
|
||||||
m.packageName = packageName;
|
if (m.apkPath == null || !new File(m.apkPath).exists()) {
|
||||||
if (!new File(m.apkPath).exists()){
|
Log.w(TAG, "Module:" + m.packageName + " path not available, attempting reset.");
|
||||||
Log.i("NPatch","Module:" + m.packageName + " path not available, reset.");
|
|
||||||
try {
|
try {
|
||||||
ApplicationInfo info = context.getPackageManager().getApplicationInfo(m.packageName, 0);
|
ApplicationInfo info = context.getPackageManager().getApplicationInfo(m.packageName, 0);
|
||||||
m.apkPath = info.sourceDir;
|
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) {
|
} 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);
|
m.file = ModuleLoader.loadModule(m.apkPath);
|
||||||
cachedModule.add(m);
|
cachedModule.add(m);
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
} catch (Throwable e) {
|
||||||
Log.e(TAG,Log.getStackTraceString(e));
|
Log.e(TAG, "Error loading modules from SharedPreferences.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ public class RemoteApplicationService implements ILSPApplicationService {
|
||||||
|
|
||||||
@SuppressLint("DiscouragedPrivateApi")
|
@SuppressLint("DiscouragedPrivateApi")
|
||||||
public RemoteApplicationService(Context context) throws RemoteException {
|
public RemoteApplicationService(Context context) throws RemoteException {
|
||||||
try {
|
|
||||||
var intent = new Intent()
|
var intent = new Intent()
|
||||||
.setComponent(new ComponentName(Constants.MANAGER_PACKAGE_NAME, MODULE_SERVICE))
|
.setComponent(new ComponentName(Constants.MANAGER_PACKAGE_NAME, MODULE_SERVICE))
|
||||||
.putExtra("packageName", context.getPackageName());
|
.putExtra("packageName", context.getPackageName());
|
||||||
|
|
@ -58,6 +57,7 @@ public class RemoteApplicationService implements ILSPApplicationService {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Log.i(TAG, "Request manager binder");
|
Log.i(TAG, "Request manager binder");
|
||||||
|
try {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
context.bindService(intent, Context.BIND_AUTO_CREATE, Executors.newSingleThreadExecutor(), conn);
|
context.bindService(intent, Context.BIND_AUTO_CREATE, Executors.newSingleThreadExecutor(), conn);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -72,7 +72,16 @@ public class RemoteApplicationService implements ILSPApplicationService {
|
||||||
bindServiceAsUserMethod.invoke(context, intent, conn, Context.BIND_AUTO_CREATE, handler, userHandle);
|
bindServiceAsUserMethod.invoke(context, intent, conn, Context.BIND_AUTO_CREATE, handler, userHandle);
|
||||||
}
|
}
|
||||||
boolean success = latch.await(1, TimeUnit.SECONDS);
|
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 |
|
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException |
|
||||||
InterruptedException | TimeoutException e) {
|
InterruptedException | TimeoutException e) {
|
||||||
var r = new RemoteException("Failed to get manager binder");
|
var r = new RemoteException("Failed to get manager binder");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue