It did not work. FF3 still crashes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import java.lang.reflect.Method; import de.robv.android.xposed.IXposedHookCmdInit; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class Mypackage implements IXposedHookCmdInit { @Override public void initCmdApp(StartupParam startupParam) throws Throwable { if (!startupParam.startClassName.equals("com.android.commands.pm.Pm")) { return; } //XposedBridge.log("startup:" + startupParam.startClassName); /* Final Fantasy 3 has a native library lib__57d5__.so that tries to clear the data for all apk files in /data/app/. We do not know why. It fails to do this for root-owned packages like this xposed module. See https://forum.xda-developers.com/xposed/framework-xposed-rom-modding-modifying-t1574401/page170#1700 We simply prevent it from doing that. https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-4.1.2_r1/core/java/android/app/ActivityManagerNative.java#2880 public boolean clearApplicationUserData( String packageName, IPackageDataObserver observer, final int userId ) */ XposedHelpers.findAndHookMethod( "android.app.ActivityManagerProxy", null, "clearApplicationUserData", String.class, "android.content.pm.IPackageDataObserver", int.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { String packageName = (String) param.args[0]; XposedBridge.log("clearApplicationUserData: " + packageName); if (!packageName.equals("mypackage")) { return; } param.setResult(true); //we do not have direct access to IPackageDataObserver, so we have to dance Object observer = param.args[1]; if(observer != null) { Class<?> iPackageDataObserverClass = Class.forName("android.content.pm.IPackageDataObserver"); Class<?>[] paramTypes = {String.class, boolean.class}; Method onRemoveCompletedMethod = iPackageDataObserverClass.getMethod("onRemoveCompleted", paramTypes); Object[] params = {packageName, true}; try { onRemoveCompletedMethod.invoke(observer, params); //observer.onRemoveCompleted(packageName, true); } catch (Exception e) { XposedBridge.log("Observer no longer exists."); } } //end dance } } ); } } |