1 import java.lang.reflect.Method;
\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
9 public class Mypackage implements IXposedHookCmdInit
\r
12 public void initCmdApp(StartupParam startupParam) throws Throwable {
\r
13 if (!startupParam.startClassName.equals("com.android.commands.pm.Pm")) {
\r
16 //XposedBridge.log("startup:" + startupParam.startClassName);
\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
22 It fails to do this for root-owned packages like this xposed module.
\r
24 https://forum.xda-developers.com/xposed/framework-xposed-rom-modding-modifying-t1574401/page170#1700
\r
26 We simply prevent it from doing that.
\r
28 https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-4.1.2_r1/core/java/android/app/ActivityManagerNative.java#2880
\r
30 public boolean clearApplicationUserData(
\r
31 String packageName, IPackageDataObserver observer, final int userId
\r
34 XposedHelpers.findAndHookMethod(
\r
35 "android.app.ActivityManagerProxy",
\r
37 "clearApplicationUserData",
\r
39 "android.content.pm.IPackageDataObserver",
\r
41 new XC_MethodHook() {
\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
50 param.setResult(true);
\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
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