[core] Remove useless codes (#505)
* [core] Replace tabs with spaces * [core] Remove useless codes
This commit is contained in:
parent
86304f11ce
commit
d7897b67d9
|
|
@ -30,19 +30,27 @@ package de.robv.android.xposed;
|
||||||
public interface IXposedHookCmdInit extends IXposedMod {
|
public interface IXposedHookCmdInit extends IXposedMod {
|
||||||
/**
|
/**
|
||||||
* Called very early during startup of a command-line tool.
|
* Called very early during startup of a command-line tool.
|
||||||
|
*
|
||||||
* @param startupParam Details about the module itself and the started process.
|
* @param startupParam Details about the module itself and the started process.
|
||||||
* @throws Throwable Everything is caught, but it will prevent further initialization of the module.
|
* @throws Throwable Everything is caught, but it will prevent further initialization of the module.
|
||||||
*/
|
*/
|
||||||
void initCmdApp(StartupParam startupParam) throws Throwable;
|
void initCmdApp(StartupParam startupParam) throws Throwable;
|
||||||
|
|
||||||
/** Data holder for {@link #initCmdApp}. */
|
/**
|
||||||
|
* Data holder for {@link #initCmdApp}.
|
||||||
|
*/
|
||||||
final class StartupParam {
|
final class StartupParam {
|
||||||
/*package*/ StartupParam() {}
|
/*package*/ StartupParam() {
|
||||||
|
}
|
||||||
|
|
||||||
/** The path to the module's APK. */
|
/**
|
||||||
|
* The path to the module's APK.
|
||||||
|
*/
|
||||||
public String modulePath;
|
public String modulePath;
|
||||||
|
|
||||||
/** The class name of the tools that the hook was invoked for. */
|
/**
|
||||||
|
* The class name of the tools that the hook was invoked for.
|
||||||
|
*/
|
||||||
public String startClassName;
|
public String startClassName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,9 @@ public interface IXposedHookInitPackageResources extends IXposedMod {
|
||||||
*/
|
*/
|
||||||
void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable;
|
void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable;
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
final class Wrapper extends XC_InitPackageResources {
|
final class Wrapper extends XC_InitPackageResources {
|
||||||
private final IXposedHookInitPackageResources instance;
|
private final IXposedHookInitPackageResources instance;
|
||||||
private final String apkPath;
|
private final String apkPath;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,9 @@ public interface IXposedHookLoadPackage extends IXposedMod {
|
||||||
*/
|
*/
|
||||||
void handleLoadPackage(LoadPackageParam lpparam) throws Throwable;
|
void handleLoadPackage(LoadPackageParam lpparam) throws Throwable;
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
final class Wrapper extends XC_LoadPackage {
|
final class Wrapper extends XC_LoadPackage {
|
||||||
private final IXposedHookLoadPackage instance;
|
private final IXposedHookLoadPackage instance;
|
||||||
private final String apkPath;
|
private final String apkPath;
|
||||||
|
|
@ -52,6 +54,7 @@ public interface IXposedHookLoadPackage extends IXposedMod {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
this.apkPath = apkPath;
|
this.apkPath = apkPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
|
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
|
||||||
instance.handleLoadPackage(lpparam);
|
instance.handleLoadPackage(lpparam);
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,18 @@ import de.robv.android.xposed.callbacks.XCallback;
|
||||||
public interface IXposedHookZygoteInit extends IXposedMod {
|
public interface IXposedHookZygoteInit extends IXposedMod {
|
||||||
/**
|
/**
|
||||||
* Called very early during startup of Zygote.
|
* Called very early during startup of Zygote.
|
||||||
|
*
|
||||||
* @param startupParam Details about the module itself and the started process.
|
* @param startupParam Details about the module itself and the started process.
|
||||||
* @throws Throwable everything is caught, but will prevent further initialization of the module.
|
* @throws Throwable everything is caught, but will prevent further initialization of the module.
|
||||||
*/
|
*/
|
||||||
void initZygote(StartupParam startupParam) throws Throwable;
|
void initZygote(StartupParam startupParam) throws Throwable;
|
||||||
|
|
||||||
/** Data holder for {@link #initZygote}. */
|
/**
|
||||||
|
* Data holder for {@link #initZygote}.
|
||||||
|
*/
|
||||||
final class StartupParam extends XCallback.Param {
|
final class StartupParam extends XCallback.Param {
|
||||||
/*package*/ StartupParam() {}
|
/*package*/ StartupParam() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param callbacks
|
* @param callbacks
|
||||||
|
|
@ -54,7 +58,9 @@ public interface IXposedHookZygoteInit extends IXposedMod {
|
||||||
super(callbacks);
|
super(callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The path to the module's APK. */
|
/**
|
||||||
|
* The path to the module's APK.
|
||||||
|
*/
|
||||||
public String modulePath;
|
public String modulePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,8 @@
|
||||||
|
|
||||||
package de.robv.android.xposed;
|
package de.robv.android.xposed;
|
||||||
|
|
||||||
/** Marker interface for Xposed modules. Cannot be implemented directly. */
|
/**
|
||||||
/* package */ interface IXposedMod {}
|
* Marker interface for Xposed modules. Cannot be implemented directly.
|
||||||
|
*/
|
||||||
|
/* package */ interface IXposedMod {
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@ import de.robv.android.xposed.services.DirectAccessService;
|
||||||
* A helper to work with (or without) SELinux, abstracting much of its big complexity.
|
* A helper to work with (or without) SELinux, abstracting much of its big complexity.
|
||||||
*/
|
*/
|
||||||
public final class SELinuxHelper {
|
public final class SELinuxHelper {
|
||||||
private SELinuxHelper() {}
|
private SELinuxHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether SELinux is disabled or enabled.
|
* Determines whether SELinux is disabled or enabled.
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,8 @@ public abstract class XC_MethodHook extends XCallback {
|
||||||
* @param param Information about the method call.
|
* @param param Information about the method call.
|
||||||
* @throws Throwable Everything the callback throws is caught and logged.
|
* @throws Throwable Everything the callback throws is caught and logged.
|
||||||
*/
|
*/
|
||||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {}
|
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
|
}
|
||||||
|
|
||||||
public void callBeforeHookedMethod(MethodHookParam param) throws Throwable {
|
public void callBeforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
beforeHookedMethod(param);
|
beforeHookedMethod(param);
|
||||||
|
|
@ -82,7 +83,8 @@ public abstract class XC_MethodHook extends XCallback {
|
||||||
* @param param Information about the method call.
|
* @param param Information about the method call.
|
||||||
* @throws Throwable Everything the callback throws is caught and logged.
|
* @throws Throwable Everything the callback throws is caught and logged.
|
||||||
*/
|
*/
|
||||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {}
|
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
|
}
|
||||||
|
|
||||||
public void callAfterHookedMethod(MethodHookParam param) throws Throwable {
|
public void callAfterHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
afterHookedMethod(param);
|
afterHookedMethod(param);
|
||||||
|
|
@ -92,26 +94,36 @@ public abstract class XC_MethodHook extends XCallback {
|
||||||
* Wraps information about the method call and allows to influence it.
|
* Wraps information about the method call and allows to influence it.
|
||||||
*/
|
*/
|
||||||
public static final class MethodHookParam extends XCallback.Param {
|
public static final class MethodHookParam extends XCallback.Param {
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public MethodHookParam() {
|
public MethodHookParam() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The hooked method/constructor. */
|
/**
|
||||||
|
* The hooked method/constructor.
|
||||||
|
*/
|
||||||
public Member method;
|
public Member method;
|
||||||
|
|
||||||
/** The {@code this} reference for an instance method, or {@code null} for static methods. */
|
/**
|
||||||
|
* The {@code this} reference for an instance method, or {@code null} for static methods.
|
||||||
|
*/
|
||||||
public Object thisObject;
|
public Object thisObject;
|
||||||
|
|
||||||
/** Arguments to the method call. */
|
/**
|
||||||
|
* Arguments to the method call.
|
||||||
|
*/
|
||||||
public Object[] args;
|
public Object[] args;
|
||||||
|
|
||||||
private Object result = null;
|
private Object result = null;
|
||||||
private Throwable throwable = null;
|
private Throwable throwable = null;
|
||||||
public boolean returnEarly = false;
|
public boolean returnEarly = false;
|
||||||
|
|
||||||
/** Returns the result of the method call. */
|
/**
|
||||||
|
* Returns the result of the method call.
|
||||||
|
*/
|
||||||
public Object getResult() {
|
public Object getResult() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -127,12 +139,16 @@ public abstract class XC_MethodHook extends XCallback {
|
||||||
this.returnEarly = true;
|
this.returnEarly = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the {@link Throwable} thrown by the method, or {@code null}. */
|
/**
|
||||||
|
* Returns the {@link Throwable} thrown by the method, or {@code null}.
|
||||||
|
*/
|
||||||
public Throwable getThrowable() {
|
public Throwable getThrowable() {
|
||||||
return throwable;
|
return throwable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if an exception was thrown by the method. */
|
/**
|
||||||
|
* Returns true if an exception was thrown by the method.
|
||||||
|
*/
|
||||||
public boolean hasThrowable() {
|
public boolean hasThrowable() {
|
||||||
return throwable != null;
|
return throwable != null;
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +164,9 @@ public abstract class XC_MethodHook extends XCallback {
|
||||||
this.returnEarly = true;
|
this.returnEarly = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the result of the method call, or throws the Throwable caused by it. */
|
/**
|
||||||
|
* Returns the result of the method call, or throws the Throwable caused by it.
|
||||||
|
*/
|
||||||
public Object getResultOrThrowable() throws Throwable {
|
public Object getResultOrThrowable() throws Throwable {
|
||||||
if (throwable != null)
|
if (throwable != null)
|
||||||
throw throwable;
|
throw throwable;
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,9 @@ public abstract class XC_MethodReplacement extends XC_MethodHook {
|
||||||
super(priority);
|
super(priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected final void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
protected final void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
try {
|
try {
|
||||||
|
|
@ -54,10 +56,13 @@ public abstract class XC_MethodReplacement extends XC_MethodHook {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("EmptyMethod")
|
@SuppressWarnings("EmptyMethod")
|
||||||
protected final void afterHookedMethod(MethodHookParam param) throws Throwable {}
|
protected final void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut for replacing a method completely. Whatever is returned/thrown here is taken
|
* Shortcut for replacing a method completely. Whatever is returned/thrown here is taken
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.util.XmlUtils;
|
import com.android.internal.util.XmlUtils;
|
||||||
|
|
||||||
import org.lsposed.lspd.BuildConfig;
|
import org.lsposed.lspd.BuildConfig;
|
||||||
import org.lsposed.lspd.util.MetaDataReader;
|
import org.lsposed.lspd.util.MetaDataReader;
|
||||||
|
|
||||||
|
|
@ -99,7 +100,8 @@ public final class XSharedPreferences implements SharedPreferences {
|
||||||
Path dir = (Path) key.watchable();
|
Path dir = (Path) key.watchable();
|
||||||
Path path = dir.resolve((Path) event.context());
|
Path path = dir.resolve((Path) event.context());
|
||||||
String pathStr = path.toString();
|
String pathStr = path.toString();
|
||||||
if (BuildConfig.DEBUG) Log.v(TAG, "File " + path.toString() + " event: " + kind.name());
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.v(TAG, "File " + path.toString() + " event: " + kind.name());
|
||||||
// We react to both real and backup files due to rare race conditions
|
// We react to both real and backup files due to rare race conditions
|
||||||
if (pathStr.endsWith(".bak")) {
|
if (pathStr.endsWith(".bak")) {
|
||||||
if (kind != StandardWatchEventKinds.ENTRY_DELETE) {
|
if (kind != StandardWatchEventKinds.ENTRY_DELETE) {
|
||||||
|
|
@ -114,7 +116,8 @@ public final class XSharedPreferences implements SharedPreferences {
|
||||||
try {
|
try {
|
||||||
l.onSharedPreferenceChanged(data.mPrefs, null);
|
l.onSharedPreferenceChanged(data.mPrefs, null);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (BuildConfig.DEBUG) Log.e(TAG, "Fail in preference change listener", t);
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.e(TAG, "Fail in preference change listener", t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -209,7 +212,8 @@ public final class XSharedPreferences implements SharedPreferences {
|
||||||
if (sWatcherDaemon == null || !sWatcherDaemon.isAlive()) {
|
if (sWatcherDaemon == null || !sWatcherDaemon.isAlive()) {
|
||||||
initWatcherDaemon();
|
initWatcherDaemon();
|
||||||
}
|
}
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, "tryRegisterWatcher: registered file watcher for " + path);
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.d(TAG, "tryRegisterWatcher: registered file watcher for " + path);
|
||||||
} catch (AccessDeniedException accDeniedEx) {
|
} catch (AccessDeniedException accDeniedEx) {
|
||||||
if (BuildConfig.DEBUG) Log.e(TAG, "tryRegisterWatcher: access denied to " + path);
|
if (BuildConfig.DEBUG) Log.e(TAG, "tryRegisterWatcher: access denied to " + path);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -232,7 +236,8 @@ public final class XSharedPreferences implements SharedPreferences {
|
||||||
if (!atLeastOneValid) {
|
if (!atLeastOneValid) {
|
||||||
try {
|
try {
|
||||||
sWatcher.close();
|
sWatcher.close();
|
||||||
} catch (Exception ignore) { }
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,16 @@
|
||||||
|
|
||||||
package de.robv.android.xposed;
|
package de.robv.android.xposed;
|
||||||
|
|
||||||
|
import static de.robv.android.xposed.XposedHelpers.setObjectField;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.lsposed.lspd.BuildConfig;
|
import org.lsposed.lspd.BuildConfig;
|
||||||
|
import org.lsposed.lspd.nativebridge.ModuleLogger;
|
||||||
|
import org.lsposed.lspd.nativebridge.ResourcesHook;
|
||||||
|
import org.lsposed.lspd.yahfa.hooker.YahfaHooker;
|
||||||
|
|
||||||
import java.lang.reflect.AccessibleObject;
|
import java.lang.reflect.AccessibleObject;
|
||||||
import java.lang.reflect.Executable;
|
import java.lang.reflect.Executable;
|
||||||
|
|
@ -43,12 +48,6 @@ import java.util.Set;
|
||||||
import de.robv.android.xposed.callbacks.XC_InitPackageResources;
|
import de.robv.android.xposed.callbacks.XC_InitPackageResources;
|
||||||
import de.robv.android.xposed.callbacks.XC_InitZygote;
|
import de.robv.android.xposed.callbacks.XC_InitZygote;
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||||
import org.lsposed.lspd.nativebridge.ModuleLogger;
|
|
||||||
import org.lsposed.lspd.nativebridge.ResourcesHook;
|
|
||||||
import org.lsposed.lspd.yahfa.dexmaker.DynamicBridge;
|
|
||||||
import org.lsposed.lspd.yahfa.hooker.YahfaHooker;
|
|
||||||
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.setObjectField;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains most of Xposed's central logic, such as initialization and callbacks used by
|
* This class contains most of Xposed's central logic, such as initialization and callbacks used by
|
||||||
|
|
@ -64,18 +63,17 @@ public final class XposedBridge {
|
||||||
*/
|
*/
|
||||||
public static final ClassLoader BOOTCLASSLOADER = XposedBridge.class.getClassLoader();
|
public static final ClassLoader BOOTCLASSLOADER = XposedBridge.class.getClassLoader();
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public static final String TAG = "LSPosed-Bridge";
|
public static final String TAG = "LSPosed-Bridge";
|
||||||
|
|
||||||
/** @deprecated Use {@link #getXposedVersion()} instead. */
|
/**
|
||||||
|
* @deprecated Use {@link #getXposedVersion()} instead.
|
||||||
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static int XPOSED_BRIDGE_VERSION;
|
public static int XPOSED_BRIDGE_VERSION;
|
||||||
|
|
||||||
/*package*/ static boolean isZygote = true; // ed: RuntimeInit.main() tool process not supported yet
|
|
||||||
|
|
||||||
// This field is set "magically" on MIUI.
|
|
||||||
/*package*/ static long BOOT_START_TIME;
|
|
||||||
|
|
||||||
private static final Object[] EMPTY_ARRAY = new Object[0];
|
private static final Object[] EMPTY_ARRAY = new Object[0];
|
||||||
|
|
||||||
// built-in handlers
|
// built-in handlers
|
||||||
|
|
@ -84,7 +82,8 @@ public final class XposedBridge {
|
||||||
/*package*/ static final CopyOnWriteSortedSet<XC_InitPackageResources> sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>();
|
/*package*/ static final CopyOnWriteSortedSet<XC_InitPackageResources> sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>();
|
||||||
/*package*/ static final CopyOnWriteSortedSet<XC_InitZygote> sInitZygoteCallbacks = new CopyOnWriteSortedSet<>();
|
/*package*/ static final CopyOnWriteSortedSet<XC_InitZygote> sInitZygoteCallbacks = new CopyOnWriteSortedSet<>();
|
||||||
|
|
||||||
private XposedBridge() {}
|
private XposedBridge() {
|
||||||
|
}
|
||||||
|
|
||||||
public static volatile ClassLoader dummyClassLoader = null;
|
public static volatile ClassLoader dummyClassLoader = null;
|
||||||
|
|
||||||
|
|
@ -158,7 +157,6 @@ public final class XposedBridge {
|
||||||
* @param hookMethod The method to be hooked.
|
* @param hookMethod The method to be hooked.
|
||||||
* @param callback The callback to be executed when the hooked method is called.
|
* @param callback The callback to be executed when the hooked method is called.
|
||||||
* @return An object that can be used to remove the hook.
|
* @return An object that can be used to remove the hook.
|
||||||
*
|
|
||||||
* @see XposedHelpers#findAndHookMethod(String, ClassLoader, String, Object...)
|
* @see XposedHelpers#findAndHookMethod(String, ClassLoader, String, Object...)
|
||||||
* @see XposedHelpers#findAndHookMethod(Class, String, Object...)
|
* @see XposedHelpers#findAndHookMethod(Class, String, Object...)
|
||||||
* @see #hookAllMethods
|
* @see #hookAllMethods
|
||||||
|
|
@ -211,11 +209,10 @@ public final class XposedBridge {
|
||||||
/**
|
/**
|
||||||
* Removes the callback for a hooked method/constructor.
|
* Removes the callback for a hooked method/constructor.
|
||||||
*
|
*
|
||||||
* @deprecated Use {@link XC_MethodHook.Unhook#unhook} instead. An instance of the {@code Unhook}
|
|
||||||
* class is returned when you hook the method.
|
|
||||||
*
|
|
||||||
* @param hookMethod The method for which the callback should be removed.
|
* @param hookMethod The method for which the callback should be removed.
|
||||||
* @param callback The reference to the callback as specified in {@link #hookMethod}.
|
* @param callback The reference to the callback as specified in {@link #hookMethod}.
|
||||||
|
* @deprecated Use {@link XC_MethodHook.Unhook#unhook} instead. An instance of the {@code Unhook}
|
||||||
|
* class is returned when you hook the method.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void unhookMethod(Member hookMethod, XC_MethodHook callback) {
|
public static void unhookMethod(Member hookMethod, XC_MethodHook callback) {
|
||||||
|
|
@ -318,16 +315,12 @@ public final class XposedBridge {
|
||||||
* @param thisObject For non-static calls, the "this" pointer, otherwise {@code null}.
|
* @param thisObject For non-static calls, the "this" pointer, otherwise {@code null}.
|
||||||
* @param args Arguments for the method call as Object[] array.
|
* @param args Arguments for the method call as Object[] array.
|
||||||
* @return The result returned from the invoked method.
|
* @return The result returned from the invoked method.
|
||||||
* @throws NullPointerException
|
* @throws NullPointerException if {@code receiver == null} for a non-static method
|
||||||
* if {@code receiver == null} for a non-static method
|
* @throws IllegalAccessException if this method is not accessible (see {@link AccessibleObject})
|
||||||
* @throws IllegalAccessException
|
* @throws IllegalArgumentException if the number of arguments doesn't match the number of parameters, the receiver
|
||||||
* if this method is not accessible (see {@link AccessibleObject})
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* if the number of arguments doesn't match the number of parameters, the receiver
|
|
||||||
* is incompatible with the declaring class, or an argument could not be unboxed
|
* is incompatible with the declaring class, or an argument could not be unboxed
|
||||||
* or converted by a widening conversion to the corresponding parameter type
|
* or converted by a widening conversion to the corresponding parameter type
|
||||||
* @throws InvocationTargetException
|
* @throws InvocationTargetException if an exception was thrown by the invoked method
|
||||||
* if an exception was thrown by the invoked method
|
|
||||||
*/
|
*/
|
||||||
public static Object invokeOriginalMethod(Member method, Object thisObject, Object[] args)
|
public static Object invokeOriginalMethod(Member method, Object thisObject, Object[] args)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
|
|
@ -374,7 +367,9 @@ public final class XposedBridge {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public static final class CopyOnWriteSortedSet<E> {
|
public static final class CopyOnWriteSortedSet<E> {
|
||||||
private transient volatile Object[] elements = EMPTY_ARRAY;
|
private transient volatile Object[] elements = EMPTY_ARRAY;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ import org.apache.commons.lang3.reflect.MemberUtilsX;
|
||||||
* Helpers that simplify hooking and calling methods/constructors, getting and settings fields, ...
|
* Helpers that simplify hooking and calling methods/constructors, getting and settings fields, ...
|
||||||
*/
|
*/
|
||||||
public final class XposedHelpers {
|
public final class XposedHelpers {
|
||||||
private XposedHelpers() {}
|
private XposedHelpers() {
|
||||||
|
}
|
||||||
|
|
||||||
private static final HashMap<String, Field> fieldCache = new HashMap<>();
|
private static final HashMap<String, Field> fieldCache = new HashMap<>();
|
||||||
private static final HashMap<String, Method> methodCache = new HashMap<>();
|
private static final HashMap<String, Method> methodCache = new HashMap<>();
|
||||||
|
|
@ -157,7 +158,8 @@ public final class XposedHelpers {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return clazz.getDeclaredField(fieldName);
|
return clazz.getDeclaredField(fieldName);
|
||||||
} catch (NoSuchFieldException ignored) {}
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
@ -265,9 +267,9 @@ public final class XposedHelpers {
|
||||||
* @param classLoader The class loader for resolving the target and parameter classes.
|
* @param classLoader The class loader for resolving the target and parameter classes.
|
||||||
* @param methodName The target method name.
|
* @param methodName The target method name.
|
||||||
* @param parameterTypesAndCallback The parameter types of the target method, plus the callback.
|
* @param parameterTypesAndCallback The parameter types of the target method, plus the callback.
|
||||||
|
* @return An object which can be used to remove the callback again.
|
||||||
* @throws NoSuchMethodError In case the method was not found.
|
* @throws NoSuchMethodError In case the method was not found.
|
||||||
* @throws ClassNotFoundError In case the target class or one of the parameter types couldn't be resolved.
|
* @throws ClassNotFoundError In case the target class or one of the parameter types couldn't be resolved.
|
||||||
* @return An object which can be used to remove the callback again.
|
|
||||||
*/
|
*/
|
||||||
public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {
|
public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {
|
||||||
return findAndHookMethod(findClass(className, classLoader), methodName, parameterTypesAndCallback);
|
return findAndHookMethod(findClass(className, classLoader), methodName, parameterTypesAndCallback);
|
||||||
|
|
@ -304,9 +306,9 @@ public final class XposedHelpers {
|
||||||
* @param classLoader The class loader for resolving the target and parameter classes.
|
* @param classLoader The class loader for resolving the target and parameter classes.
|
||||||
* @param methodName The target method name.
|
* @param methodName The target method name.
|
||||||
* @param parameterTypes The parameter types of the target method.
|
* @param parameterTypes The parameter types of the target method.
|
||||||
|
* @return A reference to the method.
|
||||||
* @throws NoSuchMethodError In case the method was not found.
|
* @throws NoSuchMethodError In case the method was not found.
|
||||||
* @throws ClassNotFoundError In case the target class or one of the parameter types couldn't be resolved.
|
* @throws ClassNotFoundError In case the target class or one of the parameter types couldn't be resolved.
|
||||||
* @return A reference to the method.
|
|
||||||
*/
|
*/
|
||||||
public static Method findMethodExact(String className, ClassLoader classLoader, String methodName, Object... parameterTypes) {
|
public static Method findMethodExact(String className, ClassLoader classLoader, String methodName, Object... parameterTypes) {
|
||||||
return findMethodExact(findClass(className, classLoader), methodName, getParameterClasses(classLoader, parameterTypes));
|
return findMethodExact(findClass(className, classLoader), methodName, getParameterClasses(classLoader, parameterTypes));
|
||||||
|
|
@ -423,7 +425,8 @@ public final class XposedHelpers {
|
||||||
Method method = findMethodExact(clazz, methodName, parameterTypes);
|
Method method = findMethodExact(clazz, methodName, parameterTypes);
|
||||||
methodCache.put(fullMethodName, method);
|
methodCache.put(fullMethodName, method);
|
||||||
return method;
|
return method;
|
||||||
} catch (NoSuchMethodError ignored) {}
|
} catch (NoSuchMethodError ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
Method bestMatch = null;
|
Method bestMatch = null;
|
||||||
Class<?> clz = clazz;
|
Class<?> clz = clazz;
|
||||||
|
|
@ -663,7 +666,8 @@ public final class XposedHelpers {
|
||||||
Constructor<?> constructor = findConstructorExact(clazz, parameterTypes);
|
Constructor<?> constructor = findConstructorExact(clazz, parameterTypes);
|
||||||
constructorCache.put(fullConstructorName, constructor);
|
constructorCache.put(fullConstructorName, constructor);
|
||||||
return constructor;
|
return constructor;
|
||||||
} catch (NoSuchMethodError ignored) {}
|
} catch (NoSuchMethodError ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
Constructor<?> bestMatch = null;
|
Constructor<?> bestMatch = null;
|
||||||
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
|
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
|
||||||
|
|
@ -728,12 +732,16 @@ public final class XposedHelpers {
|
||||||
public static final class ClassNotFoundError extends Error {
|
public static final class ClassNotFoundError extends Error {
|
||||||
private static final long serialVersionUID = -1070936889459514628L;
|
private static final long serialVersionUID = -1070936889459514628L;
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public ClassNotFoundError(Throwable cause) {
|
public ClassNotFoundError(Throwable cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public ClassNotFoundError(String detailMessage, Throwable cause) {
|
public ClassNotFoundError(String detailMessage, Throwable cause) {
|
||||||
super(detailMessage, cause);
|
super(detailMessage, cause);
|
||||||
}
|
}
|
||||||
|
|
@ -783,7 +791,10 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################################################################################
|
//#################################################################################################
|
||||||
/** Sets the value of an object field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
|
||||||
|
/**
|
||||||
|
* Sets the value of an object field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setObjectField(Object obj, String fieldName, Object value) {
|
public static void setObjectField(Object obj, String fieldName, Object value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).set(obj, value);
|
findField(obj.getClass(), fieldName).set(obj, value);
|
||||||
|
|
@ -796,7 +807,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a {@code boolean} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a {@code boolean} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setBooleanField(Object obj, String fieldName, boolean value) {
|
public static void setBooleanField(Object obj, String fieldName, boolean value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).setBoolean(obj, value);
|
findField(obj.getClass(), fieldName).setBoolean(obj, value);
|
||||||
|
|
@ -809,7 +822,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a {@code byte} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a {@code byte} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setByteField(Object obj, String fieldName, byte value) {
|
public static void setByteField(Object obj, String fieldName, byte value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).setByte(obj, value);
|
findField(obj.getClass(), fieldName).setByte(obj, value);
|
||||||
|
|
@ -822,7 +837,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a {@code char} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a {@code char} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setCharField(Object obj, String fieldName, char value) {
|
public static void setCharField(Object obj, String fieldName, char value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).setChar(obj, value);
|
findField(obj.getClass(), fieldName).setChar(obj, value);
|
||||||
|
|
@ -835,7 +852,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a {@code double} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a {@code double} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setDoubleField(Object obj, String fieldName, double value) {
|
public static void setDoubleField(Object obj, String fieldName, double value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).setDouble(obj, value);
|
findField(obj.getClass(), fieldName).setDouble(obj, value);
|
||||||
|
|
@ -848,7 +867,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a {@code float} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a {@code float} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setFloatField(Object obj, String fieldName, float value) {
|
public static void setFloatField(Object obj, String fieldName, float value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).setFloat(obj, value);
|
findField(obj.getClass(), fieldName).setFloat(obj, value);
|
||||||
|
|
@ -861,7 +882,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of an {@code int} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of an {@code int} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setIntField(Object obj, String fieldName, int value) {
|
public static void setIntField(Object obj, String fieldName, int value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).setInt(obj, value);
|
findField(obj.getClass(), fieldName).setInt(obj, value);
|
||||||
|
|
@ -874,7 +897,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a {@code long} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a {@code long} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setLongField(Object obj, String fieldName, long value) {
|
public static void setLongField(Object obj, String fieldName, long value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).setLong(obj, value);
|
findField(obj.getClass(), fieldName).setLong(obj, value);
|
||||||
|
|
@ -887,7 +912,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a {@code short} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a {@code short} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setShortField(Object obj, String fieldName, short value) {
|
public static void setShortField(Object obj, String fieldName, short value) {
|
||||||
try {
|
try {
|
||||||
findField(obj.getClass(), fieldName).setShort(obj, value);
|
findField(obj.getClass(), fieldName).setShort(obj, value);
|
||||||
|
|
@ -901,7 +928,10 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################################################################################
|
//#################################################################################################
|
||||||
/** Returns the value of an object field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
|
||||||
|
/**
|
||||||
|
* Returns the value of an object field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static Object getObjectField(Object obj, String fieldName) {
|
public static Object getObjectField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(obj.getClass(), fieldName).get(obj);
|
return findField(obj.getClass(), fieldName).get(obj);
|
||||||
|
|
@ -914,12 +944,16 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For inner classes, returns the surrounding instance, i.e. the {@code this} reference of the surrounding class. */
|
/**
|
||||||
|
* For inner classes, returns the surrounding instance, i.e. the {@code this} reference of the surrounding class.
|
||||||
|
*/
|
||||||
public static Object getSurroundingThis(Object obj) {
|
public static Object getSurroundingThis(Object obj) {
|
||||||
return getObjectField(obj, "this$0");
|
return getObjectField(obj, "this$0");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of a {@code boolean} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of a {@code boolean} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||||
public static boolean getBooleanField(Object obj, String fieldName) {
|
public static boolean getBooleanField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -933,7 +967,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of a {@code byte} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of a {@code byte} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static byte getByteField(Object obj, String fieldName) {
|
public static byte getByteField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(obj.getClass(), fieldName).getByte(obj);
|
return findField(obj.getClass(), fieldName).getByte(obj);
|
||||||
|
|
@ -946,7 +982,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of a {@code char} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of a {@code char} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static char getCharField(Object obj, String fieldName) {
|
public static char getCharField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(obj.getClass(), fieldName).getChar(obj);
|
return findField(obj.getClass(), fieldName).getChar(obj);
|
||||||
|
|
@ -959,7 +997,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of a {@code double} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of a {@code double} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static double getDoubleField(Object obj, String fieldName) {
|
public static double getDoubleField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(obj.getClass(), fieldName).getDouble(obj);
|
return findField(obj.getClass(), fieldName).getDouble(obj);
|
||||||
|
|
@ -972,7 +1012,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of a {@code float} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of a {@code float} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static float getFloatField(Object obj, String fieldName) {
|
public static float getFloatField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(obj.getClass(), fieldName).getFloat(obj);
|
return findField(obj.getClass(), fieldName).getFloat(obj);
|
||||||
|
|
@ -985,7 +1027,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of an {@code int} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of an {@code int} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static int getIntField(Object obj, String fieldName) {
|
public static int getIntField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(obj.getClass(), fieldName).getInt(obj);
|
return findField(obj.getClass(), fieldName).getInt(obj);
|
||||||
|
|
@ -998,7 +1042,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of a {@code long} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of a {@code long} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static long getLongField(Object obj, String fieldName) {
|
public static long getLongField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(obj.getClass(), fieldName).getLong(obj);
|
return findField(obj.getClass(), fieldName).getLong(obj);
|
||||||
|
|
@ -1011,7 +1057,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of a {@code short} field in the given object instance. A class reference is not sufficient! See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of a {@code short} field in the given object instance. A class reference is not sufficient! See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static short getShortField(Object obj, String fieldName) {
|
public static short getShortField(Object obj, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(obj.getClass(), fieldName).getShort(obj);
|
return findField(obj.getClass(), fieldName).getShort(obj);
|
||||||
|
|
@ -1025,7 +1073,10 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################################################################################
|
//#################################################################################################
|
||||||
/** Sets the value of a static object field in the given class. See also {@link #findField}. */
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a static object field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticObjectField(Class<?> clazz, String fieldName, Object value) {
|
public static void setStaticObjectField(Class<?> clazz, String fieldName, Object value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).set(null, value);
|
findField(clazz, fieldName).set(null, value);
|
||||||
|
|
@ -1038,7 +1089,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code boolean} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code boolean} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticBooleanField(Class<?> clazz, String fieldName, boolean value) {
|
public static void setStaticBooleanField(Class<?> clazz, String fieldName, boolean value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).setBoolean(null, value);
|
findField(clazz, fieldName).setBoolean(null, value);
|
||||||
|
|
@ -1051,7 +1104,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code byte} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code byte} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticByteField(Class<?> clazz, String fieldName, byte value) {
|
public static void setStaticByteField(Class<?> clazz, String fieldName, byte value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).setByte(null, value);
|
findField(clazz, fieldName).setByte(null, value);
|
||||||
|
|
@ -1064,7 +1119,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code char} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code char} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticCharField(Class<?> clazz, String fieldName, char value) {
|
public static void setStaticCharField(Class<?> clazz, String fieldName, char value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).setChar(null, value);
|
findField(clazz, fieldName).setChar(null, value);
|
||||||
|
|
@ -1077,7 +1134,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code double} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code double} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticDoubleField(Class<?> clazz, String fieldName, double value) {
|
public static void setStaticDoubleField(Class<?> clazz, String fieldName, double value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).setDouble(null, value);
|
findField(clazz, fieldName).setDouble(null, value);
|
||||||
|
|
@ -1090,7 +1149,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code float} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code float} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticFloatField(Class<?> clazz, String fieldName, float value) {
|
public static void setStaticFloatField(Class<?> clazz, String fieldName, float value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).setFloat(null, value);
|
findField(clazz, fieldName).setFloat(null, value);
|
||||||
|
|
@ -1103,7 +1164,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code int} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code int} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticIntField(Class<?> clazz, String fieldName, int value) {
|
public static void setStaticIntField(Class<?> clazz, String fieldName, int value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).setInt(null, value);
|
findField(clazz, fieldName).setInt(null, value);
|
||||||
|
|
@ -1116,7 +1179,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code long} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code long} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticLongField(Class<?> clazz, String fieldName, long value) {
|
public static void setStaticLongField(Class<?> clazz, String fieldName, long value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).setLong(null, value);
|
findField(clazz, fieldName).setLong(null, value);
|
||||||
|
|
@ -1129,7 +1194,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code short} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code short} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static void setStaticShortField(Class<?> clazz, String fieldName, short value) {
|
public static void setStaticShortField(Class<?> clazz, String fieldName, short value) {
|
||||||
try {
|
try {
|
||||||
findField(clazz, fieldName).setShort(null, value);
|
findField(clazz, fieldName).setShort(null, value);
|
||||||
|
|
@ -1143,7 +1210,10 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################################################################################
|
//#################################################################################################
|
||||||
/** Returns the value of a static object field in the given class. See also {@link #findField}. */
|
|
||||||
|
/**
|
||||||
|
* Returns the value of a static object field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static Object getStaticObjectField(Class<?> clazz, String fieldName) {
|
public static Object getStaticObjectField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).get(null);
|
return findField(clazz, fieldName).get(null);
|
||||||
|
|
@ -1156,7 +1226,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the value of a static {@code boolean} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Returns the value of a static {@code boolean} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static boolean getStaticBooleanField(Class<?> clazz, String fieldName) {
|
public static boolean getStaticBooleanField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).getBoolean(null);
|
return findField(clazz, fieldName).getBoolean(null);
|
||||||
|
|
@ -1169,7 +1241,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code byte} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code byte} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static byte getStaticByteField(Class<?> clazz, String fieldName) {
|
public static byte getStaticByteField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).getByte(null);
|
return findField(clazz, fieldName).getByte(null);
|
||||||
|
|
@ -1182,7 +1256,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code char} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code char} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static char getStaticCharField(Class<?> clazz, String fieldName) {
|
public static char getStaticCharField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).getChar(null);
|
return findField(clazz, fieldName).getChar(null);
|
||||||
|
|
@ -1195,7 +1271,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code double} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code double} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static double getStaticDoubleField(Class<?> clazz, String fieldName) {
|
public static double getStaticDoubleField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).getDouble(null);
|
return findField(clazz, fieldName).getDouble(null);
|
||||||
|
|
@ -1208,7 +1286,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code float} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code float} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static float getStaticFloatField(Class<?> clazz, String fieldName) {
|
public static float getStaticFloatField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).getFloat(null);
|
return findField(clazz, fieldName).getFloat(null);
|
||||||
|
|
@ -1221,7 +1301,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code int} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code int} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static int getStaticIntField(Class<?> clazz, String fieldName) {
|
public static int getStaticIntField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).getInt(null);
|
return findField(clazz, fieldName).getInt(null);
|
||||||
|
|
@ -1234,7 +1316,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code long} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code long} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static long getStaticLongField(Class<?> clazz, String fieldName) {
|
public static long getStaticLongField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).getLong(null);
|
return findField(clazz, fieldName).getLong(null);
|
||||||
|
|
@ -1247,7 +1331,9 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the value of a static {@code short} field in the given class. See also {@link #findField}. */
|
/**
|
||||||
|
* Sets the value of a static {@code short} field in the given class. See also {@link #findField}.
|
||||||
|
*/
|
||||||
public static short getStaticShortField(Class<?> clazz, String fieldName) {
|
public static short getStaticShortField(Class<?> clazz, String fieldName) {
|
||||||
try {
|
try {
|
||||||
return findField(clazz, fieldName).getShort(null);
|
return findField(clazz, fieldName).getShort(null);
|
||||||
|
|
@ -1261,6 +1347,7 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################################################################################
|
//#################################################################################################
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls an instance or static method of the given object.
|
* Calls an instance or static method of the given object.
|
||||||
* The method is resolved using {@link #findMethodBestMatch(Class, String, Object...)}.
|
* The method is resolved using {@link #findMethodBestMatch(Class, String, Object...)}.
|
||||||
|
|
@ -1361,13 +1448,16 @@ public final class XposedHelpers {
|
||||||
public static final class InvocationTargetError extends Error {
|
public static final class InvocationTargetError extends Error {
|
||||||
private static final long serialVersionUID = -1070936889459514628L;
|
private static final long serialVersionUID = -1070936889459514628L;
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public InvocationTargetError(Throwable cause) {
|
public InvocationTargetError(Throwable cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################################################################################
|
//#################################################################################################
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of the given class.
|
* Creates a new instance of the given class.
|
||||||
* The constructor is resolved using {@link #findConstructorBestMatch(Class, Object...)}.
|
* The constructor is resolved using {@link #findConstructorBestMatch(Class, Object...)}.
|
||||||
|
|
@ -1498,37 +1588,50 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like {@link #setAdditionalInstanceField}, but the value is stored for the class of {@code obj}. */
|
/**
|
||||||
|
* Like {@link #setAdditionalInstanceField}, but the value is stored for the class of {@code obj}.
|
||||||
|
*/
|
||||||
public static Object setAdditionalStaticField(Object obj, String key, Object value) {
|
public static Object setAdditionalStaticField(Object obj, String key, Object value) {
|
||||||
return setAdditionalInstanceField(obj.getClass(), key, value);
|
return setAdditionalInstanceField(obj.getClass(), key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like {@link #getAdditionalInstanceField}, but the value is returned for the class of {@code obj}. */
|
/**
|
||||||
|
* Like {@link #getAdditionalInstanceField}, but the value is returned for the class of {@code obj}.
|
||||||
|
*/
|
||||||
public static Object getAdditionalStaticField(Object obj, String key) {
|
public static Object getAdditionalStaticField(Object obj, String key) {
|
||||||
return getAdditionalInstanceField(obj.getClass(), key);
|
return getAdditionalInstanceField(obj.getClass(), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like {@link #removeAdditionalInstanceField}, but the value is removed and returned for the class of {@code obj}. */
|
/**
|
||||||
|
* Like {@link #removeAdditionalInstanceField}, but the value is removed and returned for the class of {@code obj}.
|
||||||
|
*/
|
||||||
public static Object removeAdditionalStaticField(Object obj, String key) {
|
public static Object removeAdditionalStaticField(Object obj, String key) {
|
||||||
return removeAdditionalInstanceField(obj.getClass(), key);
|
return removeAdditionalInstanceField(obj.getClass(), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like {@link #setAdditionalInstanceField}, but the value is stored for {@code clazz}. */
|
/**
|
||||||
|
* Like {@link #setAdditionalInstanceField}, but the value is stored for {@code clazz}.
|
||||||
|
*/
|
||||||
public static Object setAdditionalStaticField(Class<?> clazz, String key, Object value) {
|
public static Object setAdditionalStaticField(Class<?> clazz, String key, Object value) {
|
||||||
return setAdditionalInstanceField(clazz, key, value);
|
return setAdditionalInstanceField(clazz, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like {@link #setAdditionalInstanceField}, but the value is returned for {@code clazz}. */
|
/**
|
||||||
|
* Like {@link #setAdditionalInstanceField}, but the value is returned for {@code clazz}.
|
||||||
|
*/
|
||||||
public static Object getAdditionalStaticField(Class<?> clazz, String key) {
|
public static Object getAdditionalStaticField(Class<?> clazz, String key) {
|
||||||
return getAdditionalInstanceField(clazz, key);
|
return getAdditionalInstanceField(clazz, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like {@link #setAdditionalInstanceField}, but the value is removed and returned for {@code clazz}. */
|
/**
|
||||||
|
* Like {@link #setAdditionalInstanceField}, but the value is removed and returned for {@code clazz}.
|
||||||
|
*/
|
||||||
public static Object removeAdditionalStaticField(Class<?> clazz, String key) {
|
public static Object removeAdditionalStaticField(Class<?> clazz, String key) {
|
||||||
return removeAdditionalInstanceField(clazz, key);
|
return removeAdditionalInstanceField(clazz, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################################################################################
|
//#################################################################################################
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads an asset from a resource object and returns the content as {@code byte} array.
|
* Loads an asset from a resource object and returns the content as {@code byte} array.
|
||||||
*
|
*
|
||||||
|
|
@ -1540,7 +1643,8 @@ public final class XposedHelpers {
|
||||||
return inputStreamToByteArray(res.getAssets().open(path));
|
return inputStreamToByteArray(res.getAssets().open(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ static byte[] inputStreamToByteArray(InputStream is) throws IOException {
|
/*package*/
|
||||||
|
static byte[] inputStreamToByteArray(InputStream is) throws IOException {
|
||||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||||
byte[] temp = new byte[1024];
|
byte[] temp = new byte[1024];
|
||||||
int read;
|
int read;
|
||||||
|
|
@ -1555,11 +1659,13 @@ public final class XposedHelpers {
|
||||||
/**
|
/**
|
||||||
* Invokes the {@link Closeable#close()} method, ignoring IOExceptions.
|
* Invokes the {@link Closeable#close()} method, ignoring IOExceptions.
|
||||||
*/
|
*/
|
||||||
/*package*/ static void closeSilently(Closeable c) {
|
/*package*/
|
||||||
|
static void closeSilently(Closeable c) {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
try {
|
try {
|
||||||
c.close();
|
c.close();
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1585,6 +1691,7 @@ public final class XposedHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################################################################################
|
//#################################################################################################
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the depth counter for the given method.
|
* Increments the depth counter for the given method.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,18 @@
|
||||||
|
|
||||||
package de.robv.android.xposed;
|
package de.robv.android.xposed;
|
||||||
|
|
||||||
|
import static org.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient;
|
||||||
|
import static de.robv.android.xposed.XposedBridge.hookAllMethods;
|
||||||
|
import static de.robv.android.xposed.XposedBridge.sInitPackageResourcesCallbacks;
|
||||||
|
import static de.robv.android.xposed.XposedBridge.sInitZygoteCallbacks;
|
||||||
|
import static de.robv.android.xposed.XposedBridge.sLoadedPackageCallbacks;
|
||||||
|
import static de.robv.android.xposed.XposedHelpers.callMethod;
|
||||||
|
import static de.robv.android.xposed.XposedHelpers.closeSilently;
|
||||||
|
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
|
||||||
|
import static de.robv.android.xposed.XposedHelpers.getObjectField;
|
||||||
|
import static de.robv.android.xposed.XposedHelpers.getParameterIndexByType;
|
||||||
|
import static de.robv.android.xposed.XposedHelpers.setStaticObjectField;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
|
@ -32,7 +44,8 @@ import android.os.Process;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.os.ZygoteInit;
|
import org.lsposed.lspd.nativebridge.NativeAPI;
|
||||||
|
import org.lsposed.lspd.nativebridge.ResourcesHook;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -52,56 +65,14 @@ import de.robv.android.xposed.callbacks.XC_InitZygote;
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||||
import de.robv.android.xposed.callbacks.XCallback;
|
import de.robv.android.xposed.callbacks.XCallback;
|
||||||
import hidden.HiddenApiBridge;
|
import hidden.HiddenApiBridge;
|
||||||
import org.lsposed.lspd.nativebridge.NativeAPI;
|
|
||||||
import org.lsposed.lspd.nativebridge.ResourcesHook;
|
|
||||||
|
|
||||||
import static de.robv.android.xposed.XposedBridge.hookAllMethods;
|
|
||||||
import static de.robv.android.xposed.XposedBridge.sInitPackageResourcesCallbacks;
|
|
||||||
import static de.robv.android.xposed.XposedBridge.sInitZygoteCallbacks;
|
|
||||||
import static de.robv.android.xposed.XposedBridge.sLoadedPackageCallbacks;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.callMethod;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.closeSilently;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.findClass;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.findFieldIfExists;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.getObjectField;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.getParameterIndexByType;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.setStaticBooleanField;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.setStaticLongField;
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.setStaticObjectField;
|
|
||||||
import static org.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient;
|
|
||||||
|
|
||||||
public final class XposedInit {
|
public final class XposedInit {
|
||||||
private static final String TAG = XposedBridge.TAG;
|
private static final String TAG = XposedBridge.TAG;
|
||||||
public static boolean startsSystemServer = false;
|
public static boolean startsSystemServer = false;
|
||||||
private static final String startClassName = ""; // ed: no support for tool process anymore
|
|
||||||
|
|
||||||
public static volatile boolean disableResources = false;
|
public static volatile boolean disableResources = false;
|
||||||
|
|
||||||
private XposedInit() {
|
public static void hookResources() throws Throwable {
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook some methods which we want to create an easier interface for developers.
|
|
||||||
*/
|
|
||||||
/*package*/
|
|
||||||
public static void initForZygote() throws Throwable {
|
|
||||||
// TODO Are these still needed for us?
|
|
||||||
// MIUI
|
|
||||||
if (findFieldIfExists(ZygoteInit.class, "BOOT_START_TIME") != null) {
|
|
||||||
setStaticLongField(ZygoteInit.class, "BOOT_START_TIME", XposedBridge.BOOT_START_TIME);
|
|
||||||
}
|
|
||||||
// Samsung
|
|
||||||
Class<?> zygote = findClass("com.android.internal.os.Zygote", null);
|
|
||||||
try {
|
|
||||||
setStaticBooleanField(zygote, "isEnhancedZygoteASLREnabled", false);
|
|
||||||
} catch (NoSuchFieldError ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
hookResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void hookResources() throws Throwable {
|
|
||||||
if (!serviceClient.isResourcesHookEnabled() || disableResources) {
|
if (!serviceClient.isResourcesHookEnabled() || disableResources) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -242,7 +213,7 @@ public final class XposedInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean loadModules(boolean callInitZygote) throws IOException {
|
public static boolean loadModules() throws IOException {
|
||||||
boolean hasLoaded = !modulesLoaded.compareAndSet(false, true);
|
boolean hasLoaded = !modulesLoaded.compareAndSet(false, true);
|
||||||
if (hasLoaded) {
|
if (hasLoaded) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -256,7 +227,7 @@ public final class XposedInit {
|
||||||
newLoadedApk.add(apk);
|
newLoadedApk.add(apk);
|
||||||
} else {
|
} else {
|
||||||
loadedModules.add(apk); // temporarily add it for XSharedPreference
|
loadedModules.add(apk); // temporarily add it for XSharedPreference
|
||||||
boolean loadSuccess = loadModule(apk, callInitZygote);
|
boolean loadSuccess = loadModule(apk);
|
||||||
if (loadSuccess) {
|
if (loadSuccess) {
|
||||||
newLoadedApk.add(apk);
|
newLoadedApk.add(apk);
|
||||||
}
|
}
|
||||||
|
|
@ -326,7 +297,7 @@ public final class XposedInit {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean initModule(ClassLoader mcl, String apk, boolean callInitZygote) {
|
private static boolean initModule(ClassLoader mcl, String apk) {
|
||||||
InputStream is = mcl.getResourceAsStream("assets/xposed_init");
|
InputStream is = mcl.getResourceAsStream("assets/xposed_init");
|
||||||
if (is == null) {
|
if (is == null) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -359,10 +330,8 @@ public final class XposedInit {
|
||||||
|
|
||||||
XposedBridge.hookInitZygote(new IXposedHookZygoteInit.Wrapper(
|
XposedBridge.hookInitZygote(new IXposedHookZygoteInit.Wrapper(
|
||||||
(IXposedHookZygoteInit) moduleInstance, param));
|
(IXposedHookZygoteInit) moduleInstance, param));
|
||||||
if (callInitZygote) {
|
|
||||||
((IXposedHookZygoteInit) moduleInstance).initZygote(param);
|
((IXposedHookZygoteInit) moduleInstance).initZygote(param);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (moduleInstance instanceof IXposedHookLoadPackage)
|
if (moduleInstance instanceof IXposedHookLoadPackage)
|
||||||
XposedBridge.hookLoadPackage(new IXposedHookLoadPackage.Wrapper(
|
XposedBridge.hookLoadPackage(new IXposedHookLoadPackage.Wrapper(
|
||||||
|
|
@ -390,7 +359,7 @@ public final class XposedInit {
|
||||||
* in <code>assets/xposed_init</code>.
|
* in <code>assets/xposed_init</code>.
|
||||||
*/
|
*/
|
||||||
@SuppressLint("PrivateApi")
|
@SuppressLint("PrivateApi")
|
||||||
private static boolean loadModule(String apk, boolean callInitZygote) {
|
private static boolean loadModule(String apk) {
|
||||||
Log.i(TAG, "Loading modules from " + apk);
|
Log.i(TAG, "Loading modules from " + apk);
|
||||||
|
|
||||||
if (!new File(apk).exists()) {
|
if (!new File(apk).exists()) {
|
||||||
|
|
@ -418,7 +387,7 @@ public final class XposedInit {
|
||||||
} catch (ClassNotFoundException ignored) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean res = initModule(mcl, apk, callInitZygote);
|
boolean res = initModule(mcl, apk);
|
||||||
res = res && initNativeModule(mcl, apk);
|
res = res && initNativeModule(mcl, apk);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet;
|
||||||
public abstract class XC_InitPackageResources extends XCallback implements IXposedHookInitPackageResources {
|
public abstract class XC_InitPackageResources extends XCallback implements IXposedHookInitPackageResources {
|
||||||
/**
|
/**
|
||||||
* Creates a new callback with default priority.
|
* Creates a new callback with default priority.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
|
@ -53,12 +54,16 @@ public abstract class XC_InitPackageResources extends XCallback implements IXpos
|
||||||
* Wraps information about the resources being initialized.
|
* Wraps information about the resources being initialized.
|
||||||
*/
|
*/
|
||||||
public static final class InitPackageResourcesParam extends XCallback.Param {
|
public static final class InitPackageResourcesParam extends XCallback.Param {
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public InitPackageResourcesParam(CopyOnWriteSortedSet<XC_InitPackageResources> callbacks) {
|
public InitPackageResourcesParam(CopyOnWriteSortedSet<XC_InitPackageResources> callbacks) {
|
||||||
super(callbacks);
|
super(callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The name of the package for which resources are being loaded. */
|
/**
|
||||||
|
* The name of the package for which resources are being loaded.
|
||||||
|
*/
|
||||||
public String packageName;
|
public String packageName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -68,7 +73,9 @@ public abstract class XC_InitPackageResources extends XCallback implements IXpos
|
||||||
public XResources res;
|
public XResources res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void call(Param param) throws Throwable {
|
protected void call(Param param) throws Throwable {
|
||||||
if (param instanceof InitPackageResourcesParam)
|
if (param instanceof InitPackageResourcesParam)
|
||||||
|
|
|
||||||
|
|
@ -52,25 +52,37 @@ public abstract class XC_LayoutInflated extends XCallback {
|
||||||
* Wraps information about the inflated layout.
|
* Wraps information about the inflated layout.
|
||||||
*/
|
*/
|
||||||
public static final class LayoutInflatedParam extends XCallback.Param {
|
public static final class LayoutInflatedParam extends XCallback.Param {
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public LayoutInflatedParam(CopyOnWriteSortedSet<XC_LayoutInflated> callbacks) {
|
public LayoutInflatedParam(CopyOnWriteSortedSet<XC_LayoutInflated> callbacks) {
|
||||||
super(callbacks);
|
super(callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The view that has been created from the layout. */
|
/**
|
||||||
|
* The view that has been created from the layout.
|
||||||
|
*/
|
||||||
public View view;
|
public View view;
|
||||||
|
|
||||||
/** Container with the ID and name of the underlying resource. */
|
/**
|
||||||
|
* Container with the ID and name of the underlying resource.
|
||||||
|
*/
|
||||||
public ResourceNames resNames;
|
public ResourceNames resNames;
|
||||||
|
|
||||||
/** Directory from which the layout was actually loaded (e.g. "layout-sw600dp"). */
|
/**
|
||||||
|
* Directory from which the layout was actually loaded (e.g. "layout-sw600dp").
|
||||||
|
*/
|
||||||
public String variant;
|
public String variant;
|
||||||
|
|
||||||
/** Resources containing the layout. */
|
/**
|
||||||
|
* Resources containing the layout.
|
||||||
|
*/
|
||||||
public XResources res;
|
public XResources res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void call(Param param) throws Throwable {
|
protected void call(Param param) throws Throwable {
|
||||||
if (param instanceof LayoutInflatedParam)
|
if (param instanceof LayoutInflatedParam)
|
||||||
|
|
@ -92,7 +104,9 @@ public abstract class XC_LayoutInflated extends XCallback {
|
||||||
private final String resDir;
|
private final String resDir;
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public Unhook(String resDir, int id) {
|
public Unhook(String resDir, int id) {
|
||||||
this.resDir = resDir;
|
this.resDir = resDir;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet;
|
||||||
public abstract class XC_LoadPackage extends XCallback implements IXposedHookLoadPackage {
|
public abstract class XC_LoadPackage extends XCallback implements IXposedHookLoadPackage {
|
||||||
/**
|
/**
|
||||||
* Creates a new callback with default priority.
|
* Creates a new callback with default priority.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
|
@ -53,28 +54,42 @@ public abstract class XC_LoadPackage extends XCallback implements IXposedHookLoa
|
||||||
* Wraps information about the app being loaded.
|
* Wraps information about the app being loaded.
|
||||||
*/
|
*/
|
||||||
public static final class LoadPackageParam extends XCallback.Param {
|
public static final class LoadPackageParam extends XCallback.Param {
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public LoadPackageParam(CopyOnWriteSortedSet<XC_LoadPackage> callbacks) {
|
public LoadPackageParam(CopyOnWriteSortedSet<XC_LoadPackage> callbacks) {
|
||||||
super(callbacks);
|
super(callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The name of the package being loaded. */
|
/**
|
||||||
|
* The name of the package being loaded.
|
||||||
|
*/
|
||||||
public String packageName;
|
public String packageName;
|
||||||
|
|
||||||
/** The process in which the package is executed. */
|
/**
|
||||||
|
* The process in which the package is executed.
|
||||||
|
*/
|
||||||
public String processName;
|
public String processName;
|
||||||
|
|
||||||
/** The ClassLoader used for this package. */
|
/**
|
||||||
|
* The ClassLoader used for this package.
|
||||||
|
*/
|
||||||
public ClassLoader classLoader;
|
public ClassLoader classLoader;
|
||||||
|
|
||||||
/** More information about the application being loaded. */
|
/**
|
||||||
|
* More information about the application being loaded.
|
||||||
|
*/
|
||||||
public ApplicationInfo appInfo;
|
public ApplicationInfo appInfo;
|
||||||
|
|
||||||
/** Set to {@code true} if this is the first (and main) application for this process. */
|
/**
|
||||||
|
* Set to {@code true} if this is the first (and main) application for this process.
|
||||||
|
*/
|
||||||
public boolean isFirstApplication;
|
public boolean isFirstApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void call(Param param) throws Throwable {
|
protected void call(Param param) throws Throwable {
|
||||||
if (param instanceof LoadPackageParam)
|
if (param instanceof LoadPackageParam)
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,12 @@ import java.io.Serializable;
|
||||||
import de.robv.android.xposed.IModuleContext;
|
import de.robv.android.xposed.IModuleContext;
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet;
|
import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet;
|
||||||
|
|
||||||
import org.lsposed.lspd.deopt.PrebuiltMethodsDeopter;
|
import org.lsposed.lspd.deopt.PrebuiltMethodsDeopter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for Xposed callbacks.
|
* Base class for Xposed callbacks.
|
||||||
*
|
* <p>
|
||||||
* This class only keeps a priority for ordering multiple callbacks.
|
* This class only keeps a priority for ordering multiple callbacks.
|
||||||
* The actual (abstract) callback methods are added by subclasses.
|
* The actual (abstract) callback methods are added by subclasses.
|
||||||
*/
|
*/
|
||||||
|
|
@ -46,13 +47,17 @@ public abstract class XCallback implements Comparable<XCallback>, IModuleContext
|
||||||
*/
|
*/
|
||||||
public final int priority;
|
public final int priority;
|
||||||
|
|
||||||
/** @deprecated This constructor can't be hidden for technical reasons. Nevertheless, don't use it! */
|
/**
|
||||||
|
* @deprecated This constructor can't be hidden for technical reasons. Nevertheless, don't use it!
|
||||||
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public XCallback() {
|
public XCallback() {
|
||||||
this.priority = PRIORITY_DEFAULT;
|
this.priority = PRIORITY_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public XCallback(int priority) {
|
public XCallback(int priority) {
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
@ -61,17 +66,23 @@ public abstract class XCallback implements Comparable<XCallback>, IModuleContext
|
||||||
* Base class for Xposed callback parameters.
|
* Base class for Xposed callback parameters.
|
||||||
*/
|
*/
|
||||||
public static abstract class Param {
|
public static abstract class Param {
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public final Object[] callbacks;
|
public final Object[] callbacks;
|
||||||
private Bundle extra;
|
private Bundle extra;
|
||||||
|
|
||||||
/** @deprecated This constructor can't be hidden for technical reasons. Nevertheless, don't use it! */
|
/**
|
||||||
|
* @deprecated This constructor can't be hidden for technical reasons. Nevertheless, don't use it!
|
||||||
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
protected Param() {
|
protected Param() {
|
||||||
callbacks = null;
|
callbacks = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
protected Param(CopyOnWriteSortedSet<? extends XCallback> callbacks) {
|
protected Param(CopyOnWriteSortedSet<? extends XCallback> callbacks) {
|
||||||
this.callbacks = callbacks.getSnapshot();
|
this.callbacks = callbacks.getSnapshot();
|
||||||
}
|
}
|
||||||
|
|
@ -112,13 +123,16 @@ public abstract class XCallback implements Comparable<XCallback>, IModuleContext
|
||||||
private static class SerializeWrapper implements Serializable {
|
private static class SerializeWrapper implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final Object object;
|
private final Object object;
|
||||||
|
|
||||||
public SerializeWrapper(Object o) {
|
public SerializeWrapper(Object o) {
|
||||||
object = o;
|
object = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public static void callAll(Param param) {
|
public static void callAll(Param param) {
|
||||||
|
|
||||||
if (param instanceof XC_LoadPackage.LoadPackageParam) {
|
if (param instanceof XC_LoadPackage.LoadPackageParam) {
|
||||||
|
|
@ -134,19 +148,26 @@ public abstract class XCallback implements Comparable<XCallback>, IModuleContext
|
||||||
for (int i = 0; i < param.callbacks.length; i++) {
|
for (int i = 0; i < param.callbacks.length; i++) {
|
||||||
try {
|
try {
|
||||||
((XCallback) param.callbacks[i]).call(param);
|
((XCallback) param.callbacks[i]).call(param);
|
||||||
} catch (Throwable t) { XposedBridge.log(t); }
|
} catch (Throwable t) {
|
||||||
|
XposedBridge.log(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
protected void call(Param param) throws Throwable {}
|
* @hide
|
||||||
|
*/
|
||||||
|
protected void call(Param param) throws Throwable {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getApkPath() {
|
public String getApkPath() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(XCallback other) {
|
public int compareTo(XCallback other) {
|
||||||
if (this == other)
|
if (this == other)
|
||||||
|
|
@ -162,12 +183,18 @@ public abstract class XCallback implements Comparable<XCallback>, IModuleContext
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The default priority, see {@link #priority}. */
|
/**
|
||||||
|
* The default priority, see {@link #priority}.
|
||||||
|
*/
|
||||||
public static final int PRIORITY_DEFAULT = 50;
|
public static final int PRIORITY_DEFAULT = 50;
|
||||||
|
|
||||||
/** Execute this callback late, see {@link #priority}. */
|
/**
|
||||||
|
* Execute this callback late, see {@link #priority}.
|
||||||
|
*/
|
||||||
public static final int PRIORITY_LOWEST = -10000;
|
public static final int PRIORITY_LOWEST = -10000;
|
||||||
|
|
||||||
/** Execute this callback early, see {@link #priority}. */
|
/**
|
||||||
|
* Execute this callback early, see {@link #priority}.
|
||||||
|
*/
|
||||||
public static final int PRIORITY_HIGHEST = 10000;
|
public static final int PRIORITY_HIGHEST = 10000;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,21 @@ import de.robv.android.xposed.SELinuxHelper;
|
||||||
* <p>References to a concrete subclass should generally be retrieved from {@link SELinuxHelper}.
|
* <p>References to a concrete subclass should generally be retrieved from {@link SELinuxHelper}.
|
||||||
*/
|
*/
|
||||||
public abstract class BaseService {
|
public abstract class BaseService {
|
||||||
/** Flag for {@link #checkFileAccess}: Read access. */
|
/**
|
||||||
|
* Flag for {@link #checkFileAccess}: Read access.
|
||||||
|
*/
|
||||||
public static final int R_OK = 4;
|
public static final int R_OK = 4;
|
||||||
/** Flag for {@link #checkFileAccess}: Write access. */
|
/**
|
||||||
|
* Flag for {@link #checkFileAccess}: Write access.
|
||||||
|
*/
|
||||||
public static final int W_OK = 2;
|
public static final int W_OK = 2;
|
||||||
/** Flag for {@link #checkFileAccess}: Executable access. */
|
/**
|
||||||
|
* Flag for {@link #checkFileAccess}: Executable access.
|
||||||
|
*/
|
||||||
public static final int X_OK = 1;
|
public static final int X_OK = 1;
|
||||||
/** Flag for {@link #checkFileAccess}: File/directory exists. */
|
/**
|
||||||
|
* Flag for {@link #checkFileAccess}: File/directory exists.
|
||||||
|
*/
|
||||||
public static final int F_OK = 0;
|
public static final int F_OK = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -173,15 +181,18 @@ public abstract class BaseService {
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/*package*/ BaseService() {}
|
/*package*/ BaseService() {
|
||||||
|
}
|
||||||
|
|
||||||
/*package*/ static void ensureAbsolutePath(String filename) {
|
/*package*/
|
||||||
|
static void ensureAbsolutePath(String filename) {
|
||||||
if (!filename.startsWith("/")) {
|
if (!filename.startsWith("/")) {
|
||||||
throw new IllegalArgumentException("Only absolute filenames are allowed: " + filename);
|
throw new IllegalArgumentException("Only absolute filenames are allowed: " + filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ static void throwCommonIOException(int errno, String errorMsg, String filename, String defaultText) throws IOException {
|
/*package*/
|
||||||
|
static void throwCommonIOException(int errno, String errorMsg, String filename, String defaultText) throws IOException {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case 1: // EPERM
|
case 1: // EPERM
|
||||||
case 13: // EACCES
|
case 13: // EACCES
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public final class DirectAccessService extends BaseService {
|
public final class DirectAccessService extends BaseService {
|
||||||
@Override
|
@Override
|
||||||
public boolean hasDirectFileAccess() {
|
public boolean hasDirectFileAccess() {
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,21 @@ import java.io.InputStream;
|
||||||
* Holder for the result of a {@link BaseService#readFile} or {@link BaseService#statFile} call.
|
* Holder for the result of a {@link BaseService#readFile} or {@link BaseService#statFile} call.
|
||||||
*/
|
*/
|
||||||
public final class FileResult {
|
public final class FileResult {
|
||||||
/** File content, might be {@code null} if the file wasn't read. */
|
/**
|
||||||
|
* File content, might be {@code null} if the file wasn't read.
|
||||||
|
*/
|
||||||
public final byte[] content;
|
public final byte[] content;
|
||||||
/** File input stream, might be {@code null} if the file wasn't read. */
|
/**
|
||||||
|
* File input stream, might be {@code null} if the file wasn't read.
|
||||||
|
*/
|
||||||
public final InputStream stream;
|
public final InputStream stream;
|
||||||
/** File size. */
|
/**
|
||||||
|
* File size.
|
||||||
|
*/
|
||||||
public final long size;
|
public final long size;
|
||||||
/** File last modification time. */
|
/**
|
||||||
|
* File last modification time.
|
||||||
|
*/
|
||||||
public final long mtime;
|
public final long mtime;
|
||||||
|
|
||||||
/*package*/ FileResult(long size, long mtime) {
|
/*package*/ FileResult(long size, long mtime) {
|
||||||
|
|
@ -56,7 +64,9 @@ public final class FileResult {
|
||||||
this.mtime = mtime;
|
this.mtime = mtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder("{");
|
StringBuilder sb = new StringBuilder("{");
|
||||||
|
|
|
||||||
|
|
@ -79,15 +79,15 @@ public class Main {
|
||||||
// Initialize the Xposed framework
|
// Initialize the Xposed framework
|
||||||
try {
|
try {
|
||||||
startBootstrapHook(isSystem, appDataDir);
|
startBootstrapHook(isSystem, appDataDir);
|
||||||
XposedInit.initForZygote();
|
XposedInit.hookResources();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
Utils.logE("error during Xposed initialization", t);
|
Utils.logE("error during Xposed initialization", t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadModulesSafely(boolean callInitZygote) {
|
private static void loadModulesSafely() {
|
||||||
try {
|
try {
|
||||||
XposedInit.loadModules(callInitZygote);
|
XposedInit.loadModules();
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
Utils.logE("error loading module list", exception);
|
Utils.logE("error loading module list", exception);
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +101,7 @@ public class Main {
|
||||||
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
|
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
|
||||||
installBootstrapHooks(isSystem, appDataDir);
|
installBootstrapHooks(isSystem, appDataDir);
|
||||||
Utils.logI("Loading modules for " + niceName);
|
Utils.logI("Loading modules for " + niceName);
|
||||||
loadModulesSafely(true);
|
loadModulesSafely();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forkAndSpecializePost(String appDataDir, String niceName, IBinder binder) {
|
public static void forkAndSpecializePost(String appDataDir, String niceName, IBinder binder) {
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ import static org.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient;
|
||||||
|
|
||||||
// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
|
// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
|
||||||
public class HandleBindAppHooker extends XC_MethodHook {
|
public class HandleBindAppHooker extends XC_MethodHook {
|
||||||
String appDataDir = null;
|
String appDataDir;
|
||||||
|
|
||||||
public HandleBindAppHooker(String appDataDir) {
|
public HandleBindAppHooker(String appDataDir) {
|
||||||
this.appDataDir = appDataDir;
|
this.appDataDir = appDataDir;
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
package org.lsposed.lspd.hooker;
|
package org.lsposed.lspd.hooker;
|
||||||
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
import org.lsposed.lspd.util.Hookers;
|
import org.lsposed.lspd.util.Hookers;
|
||||||
|
|
||||||
import de.robv.android.xposed.XC_MethodHook;
|
import de.robv.android.xposed.XC_MethodHook;
|
||||||
|
|
@ -60,7 +58,7 @@ public class StartBootstrapServicesHooker extends XC_MethodHook {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String className = "com.android.server.pm." + (Build.VERSION.SDK_INT >= 23 ? "PackageDexOptimizer" : "PackageManagerService");
|
String className = "com.android.server.pm.PackageDexOptimizer";
|
||||||
findAndHookMethod(className, SystemMainHooker.systemServerCL,
|
findAndHookMethod(className, SystemMainHooker.systemServerCL,
|
||||||
"dexEntryExists", String.class,
|
"dexEntryExists", String.class,
|
||||||
XC_MethodReplacement.returnConstant(true));
|
XC_MethodReplacement.returnConstant(true));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue