[core] Remove useless codes (#505)

* [core] Replace tabs with spaces

* [core] Remove useless codes
This commit is contained in:
tehcneko 2021-04-24 14:59:35 +08:00 committed by GitHub
parent 86304f11ce
commit d7897b67d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 3080 additions and 2874 deletions

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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);

View File

@ -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;
/** /**

View File

@ -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 {
}

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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) {
}
} }
} }
} }

View File

@ -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;

View File

@ -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.
* *

View File

@ -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;
} }

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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;
} }

View File

@ -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

View File

@ -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() {

View File

@ -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("{");

View File

@ -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) {

View File

@ -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;

View File

@ -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));