diff --git a/api/src/main/java/io/github/libxposed/api/XposedInterface.java b/api/src/main/java/io/github/libxposed/api/XposedInterface.java index bdc4dfd..a8fbf55 100644 --- a/api/src/main/java/io/github/libxposed/api/XposedInterface.java +++ b/api/src/main/java/io/github/libxposed/api/XposedInterface.java @@ -64,10 +64,128 @@ public interface XposedInterface { */ int PRIORITY_HIGHEST = 10000; + /** + * Contextual interface for before invocation callbacks. + */ + interface BeforeHookCallback { + /** + * Gets the method / constructor to be hooked. + */ + @NonNull + Member getMember(); + + /** + * Gets the {@code this} object, or {@code null} if the method is static. + */ + @Nullable + Object getThisObject(); + + /** + * Gets the arguments passed to the method / constructor. You can modify the arguments. + */ + @NonNull + Object[] getArgs(); + + /** + * Sets the return value of the method and skip the invocation. If the procedure is a constructor, + * the {@code result} param will be ignored. + * Note that the after invocation callback will still be called. + * + * @param result The return value + */ + void returnAndSkip(@Nullable Object result); + + /** + * Throw an exception from the method / constructor and skip the invocation. + * Note that the after invocation callback will still be called. + * + * @param throwable The exception to be thrown + */ + void throwAndSkip(@Nullable Throwable throwable); + + /** + * Sets an extra object to the hook context in order to share additional contextual information + * between the before and after invocation callbacks of the same procedure call. + * + * @param The type of the extra object + * @param key The name of the extra object + * @param value The extra object + */ + void setExtra(@NonNull String key, @Nullable T value); + } + + /** + * Contextual interface for after invocation callbacks. + */ + interface AfterHookCallback { + /** + * Gets the method / constructor to be hooked. + */ + @NonNull + Member getMember(); + + /** + * Gets the {@code this} object, or {@code null} if the method is static. + */ + @Nullable + Object getThisObject(); + + /** + * Gets all arguments passed to the method / constructor. + */ + @NonNull + Object[] getArgs(); + + /** + * Gets the return value of the method or the before invocation callback. If the procedure is a + * constructor, a void method or an exception was thrown, the return value will be {@code null}. + */ + @Nullable + Object getResult(); + + /** + * Gets the exception thrown by the method / constructor or the before invocation callback. If the + * procedure call was successful, the return value will be {@code null}. + */ + @Nullable + Throwable getThrowable(); + + /** + * Gets whether the invocation was skipped by the before invocation callback. + */ + boolean isSkipped(); + + /** + * Sets the return value of the method and skip the invocation. If the procedure is a constructor, + * the {@code result} param will be ignored. + * + * @param result The return value + */ + void setResult(@Nullable Object result); + + /** + * Sets the exception thrown by the method / constructor. + * + * @param throwable The exception to be thrown. + */ + void setThrowable(@Nullable Throwable throwable); + + /** + * Gets an extra object saved by the before invocation callback of the same procedure call. + * + * @param The type of the extra object + * @param key The name of the extra object + * @return The extra object, or {@code null} if not found + */ + @Nullable + T getExtra(@NonNull String key); + } + /** * Interface for method / constructor hooking. Xposed modules should define their own hooker class - * and implement this interface. Normally, there could be one global hooker class for all method - * hooking. + * and implement this interface. Normally, a hooker class corresponds to a method / constructor, but + * there could also be a single hooker class for all of them. By this way you can implement an interface + * like the old API. * *

* Classes implementing this interface should be annotated with {@link XposedHooker} and should provide @@ -77,19 +195,12 @@ public interface XposedInterface { * *

* The before invocation method should have the following signature:
- * params: {@code member} - The {@link Member} object representing the method or constructor being hooked
- *              - * {@code thisObject} - The {@code this} pointer, or null if the method is static
- *              - * {@code args} - The arguments used for the method call
- * returns: An {@link Hooker} object, used to save contextual information for current invocation routine + * params: {@code callback} - The {@link BeforeHookCallback} of the procedure call
*

* *

* The after invocation method should have the following signature:
- * params: {@code extras} - The {@link Hooker} object returned by the before invocation method
- *              - * {@code result} - The result of the invocation + * params: {@code callback} - The {@link AfterHookCallback} of the procedure call
*

* *

Example usage:

@@ -99,14 +210,12 @@ public interface XposedInterface { * public class ExampleHooker implements XposedInterface.Hooker { * * @BeforeInvocation - * public static @Nullable XposedInterface.Hooker - * before(@NonNull Member member, @Nullable Object thisObject, @NonNull Object[] args) { + * public static void before(@NonNull BeforeHookCallback callback) { * // Pre-hooking logic goes here * } * * @AfterInvocation - * public static void - * after(@Nullable XposedInterface.Hooker extras, @Nullable Object result) { + * public static void after(@NonNull AfterHookCallback callback) { * // Post-hooking logic goes here * } * }