|
| 1 | +/** |
| 2 | + * Modern Xposed Module API. |
| 3 | + * |
| 4 | + * <p>This package provides the public API for developing Xposed modules using the modern |
| 5 | + * Xposed framework. It replaces the legacy XposedBridge API with a redesigned, type-safe |
| 6 | + * interface.</p> |
| 7 | + * |
| 8 | + * <h2>Getting Started</h2> |
| 9 | + * |
| 10 | + * <p>Module entry classes should extend {@link io.github.libxposed.api.XposedModule}. The |
| 11 | + * framework calls {@link io.github.libxposed.api.XposedInterfaceWrapper#attachFramework(XposedInterface) |
| 12 | + * attachFramework()} automatically; modules <b>should not</b> perform initialization work before |
| 13 | + * {@link io.github.libxposed.api.XposedModuleInterface#onModuleLoaded(XposedModuleInterface.ModuleLoadedParam) |
| 14 | + * onModuleLoaded()} is called.</p> |
| 15 | + * |
| 16 | + * <h2>Entry Registration</h2> |
| 17 | + * |
| 18 | + * <p>Java entry classes are listed in {@code META-INF/xposed/java_init.list} (one fully-qualified |
| 19 | + * class name per line); native entries use {@code META-INF/xposed/native_init.list}. Place these |
| 20 | + * files under {@code src/main/resources/META-INF/xposed/} and Gradle will package them into the |
| 21 | + * APK automatically.</p> |
| 22 | + * |
| 23 | + * <h2>Module Configuration</h2> |
| 24 | + * |
| 25 | + * <p>Module metadata is specified via standard Android resources ({@code android:label} for the |
| 26 | + * module name, {@code android:description} for the description) and |
| 27 | + * {@code META-INF/xposed/module.prop} (Java {@link java.util.Properties} format). Required |
| 28 | + * properties:</p> |
| 29 | + * <ul> |
| 30 | + * <li>{@code minApiVersion} – minimum Xposed API version required</li> |
| 31 | + * <li>{@code targetApiVersion} – target Xposed API version</li> |
| 32 | + * </ul> |
| 33 | + * <p>Optional properties:</p> |
| 34 | + * <ul> |
| 35 | + * <li>{@code staticScope} (boolean) – whether the module scope is fixed and users should not |
| 36 | + * apply the module on apps outside the scope list</li> |
| 37 | + * </ul> |
| 38 | + * |
| 39 | + * <h2>Hook Model</h2> |
| 40 | + * |
| 41 | + * <p>The API uses an <b>interceptor-chain</b> model (similar to OkHttp interceptors). Modules |
| 42 | + * implement {@link io.github.libxposed.api.XposedInterface.Hooker Hooker} and its |
| 43 | + * {@link io.github.libxposed.api.XposedInterface.Hooker#intercept(XposedInterface.Chain) |
| 44 | + * intercept(Chain)} method. Hooking is performed through a builder returned by |
| 45 | + * {@link io.github.libxposed.api.XposedInterface#hook(java.lang.reflect.Executable) |
| 46 | + * hook(Executable)}:</p> |
| 47 | + * <pre>{@code |
| 48 | + * HookHandle handle = hook(method) |
| 49 | + * .setPriority(PRIORITY_DEFAULT) |
| 50 | + * .setExceptionMode(ExceptionMode.PROTECTIVE) |
| 51 | + * .intercept(chain -> { |
| 52 | + * // pre-processing |
| 53 | + * Object result = chain.proceed(); |
| 54 | + * // post-processing |
| 55 | + * return result; |
| 56 | + * }); |
| 57 | + * }</pre> |
| 58 | + * |
| 59 | + * <h2>Invoker System</h2> |
| 60 | + * |
| 61 | + * <p>To call the original (or hooked) method bypassing access checks, obtain an |
| 62 | + * {@link io.github.libxposed.api.XposedInterface.Invoker Invoker} via |
| 63 | + * {@link io.github.libxposed.api.XposedInterface#getInvoker(java.lang.reflect.Method) |
| 64 | + * getInvoker(Method)} or |
| 65 | + * {@link io.github.libxposed.api.XposedInterface#getInvoker(java.lang.reflect.Constructor) |
| 66 | + * getInvoker(Constructor)}. The invoker type controls what part of the hook chain is executed |
| 67 | + * (see {@link io.github.libxposed.api.XposedInterface.Invoker.Type Invoker.Type}).</p> |
| 68 | + * |
| 69 | + * <h2>Module Lifecycle Callbacks</h2> |
| 70 | + * |
| 71 | + * <p>Override the following callbacks in {@link io.github.libxposed.api.XposedModule}:</p> |
| 72 | + * <ul> |
| 73 | + * <li>{@link io.github.libxposed.api.XposedModuleInterface#onModuleLoaded(XposedModuleInterface.ModuleLoadedParam) |
| 74 | + * onModuleLoaded()} – called once when the module is loaded into the target process.</li> |
| 75 | + * <li>{@link io.github.libxposed.api.XposedModuleInterface#onPackageLoaded(XposedModuleInterface.PackageLoadedParam) |
| 76 | + * onPackageLoaded()} – called when the default classloader is ready, before |
| 77 | + * {@link android.app.AppComponentFactory} instantiation (API 29+).</li> |
| 78 | + * <li>{@link io.github.libxposed.api.XposedModuleInterface#onPackageReady(XposedModuleInterface.PackageReadyParam) |
| 79 | + * onPackageReady()} – called after the app classloader is created.</li> |
| 80 | + * <li>{@link io.github.libxposed.api.XposedModuleInterface#onSystemServerStarting(XposedModuleInterface.SystemServerStartingParam) |
| 81 | + * onSystemServerStarting()} – called when system server is starting.</li> |
| 82 | + * </ul> |
| 83 | + * |
| 84 | + * <h2>Error Handling</h2> |
| 85 | + * |
| 86 | + * <p>Framework-level errors are reported via subclasses of |
| 87 | + * {@link io.github.libxposed.api.error.XposedFrameworkError}. In particular, |
| 88 | + * {@link io.github.libxposed.api.error.HookFailedError} indicates a fatal hook failure that |
| 89 | + * should be reported to the framework maintainers instead of handled by the module.</p> |
| 90 | + * |
| 91 | + * @see io.github.libxposed.api.XposedInterface |
| 92 | + * @see io.github.libxposed.api.XposedModule |
| 93 | + * @see io.github.libxposed.api.XposedModuleInterface |
| 94 | + */ |
| 95 | +package io.github.libxposed.api; |
0 commit comments