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