(no commit message) master
authorChristian Weiske <cweiske@cweiske.de>
Thu, 30 Jan 2020 20:36:29 +0000 (21:36 +0100)
committerwww-cweiske <www-cweiske@ahso3>
Thu, 30 Jan 2020 20:36:29 +0000 (21:36 +0100)
README.rst [new file with mode: 0644]
xposed.java [new file with mode: 0644]

diff --git a/README.rst b/README.rst
new file mode 100644 (file)
index 0000000..c841727
--- /dev/null
@@ -0,0 +1 @@
+It did not work. FF3 still crashes.
\ No newline at end of file
diff --git a/xposed.java b/xposed.java
new file mode 100644 (file)
index 0000000..fc63f6c
--- /dev/null
@@ -0,0 +1,72 @@
+import java.lang.reflect.Method;\r
+\r
+import de.robv.android.xposed.IXposedHookCmdInit;\r
+import de.robv.android.xposed.XC_MethodHook;\r
+import de.robv.android.xposed.XposedBridge;\r
+import de.robv.android.xposed.XposedHelpers;\r
+import de.robv.android.xposed.callbacks.XC_LoadPackage;\r
+\r
+public class Mypackage implements IXposedHookCmdInit\r
+{\r
+    @Override\r
+    public void initCmdApp(StartupParam startupParam) throws Throwable {\r
+        if (!startupParam.startClassName.equals("com.android.commands.pm.Pm")) {\r
+            return;\r
+        }\r
+        //XposedBridge.log("startup:" + startupParam.startClassName);\r
+\r
+        /*\r
+         Final Fantasy 3 has a native library lib__57d5__.so that tries to clear the data\r
+         for all apk files in /data/app/. We do not know why.\r
+\r
+         It fails to do this for root-owned packages like this xposed module.\r
+         See\r
+         https://forum.xda-developers.com/xposed/framework-xposed-rom-modding-modifying-t1574401/page170#1700\r
+\r
+         We simply prevent it from doing that.\r
+\r
+         https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-4.1.2_r1/core/java/android/app/ActivityManagerNative.java#2880\r
+\r
+         public boolean clearApplicationUserData(\r
+             String packageName, IPackageDataObserver observer, final int userId\r
+         )\r
+         */\r
+        XposedHelpers.findAndHookMethod(\r
+            "android.app.ActivityManagerProxy",\r
+            null,\r
+            "clearApplicationUserData",\r
+            String.class,\r
+            "android.content.pm.IPackageDataObserver",\r
+            int.class,\r
+            new XC_MethodHook() {\r
+                @Override\r
+                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {\r
+                    String packageName = (String) param.args[0];\r
+                    XposedBridge.log("clearApplicationUserData: " + packageName);\r
+                    if (!packageName.equals("mypackage")) {\r
+                        return;\r
+                    }\r
+\r
+                    param.setResult(true);\r
+\r
+                    //we do not have direct access to IPackageDataObserver, so we have to dance\r
+                    Object observer = param.args[1];\r
+                    if(observer != null) {\r
+                        Class<?> iPackageDataObserverClass = Class.forName("android.content.pm.IPackageDataObserver");\r
+                        Class<?>[] paramTypes = {String.class, boolean.class};\r
+                        Method onRemoveCompletedMethod = iPackageDataObserverClass.getMethod("onRemoveCompleted", paramTypes);\r
+                        Object[] params = {packageName, true};\r
+                        try {\r
+                            onRemoveCompletedMethod.invoke(observer, params);\r
+                            //observer.onRemoveCompleted(packageName, true);\r
+                        } catch (Exception e) {\r
+                            XposedBridge.log("Observer no longer exists.");\r
+                        }\r
+                    }\r
+                    //end dance\r
+                }\r
+            }\r
+        );\r
+\r
+    }\r
+}\r