No XposedContext
This commit is contained in:
parent
b581d269a3
commit
844d2984a0
|
|
@ -1,12 +0,0 @@
|
||||||
package io.github.libxposed.api;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Independent {@link Context} for each Xposed module loaded into the target process.<br/>
|
|
||||||
* This class should be extended by the Xposed framework as the implementation of Xposed interfaces.<br/>
|
|
||||||
* Modules should not use this class directly.
|
|
||||||
*/
|
|
||||||
public abstract class XposedContext extends Context implements XposedInterface {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,209 +0,0 @@
|
||||||
package io.github.libxposed.api;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.ContextWrapper;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import io.github.libxposed.api.utils.DexParser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap of {@link XposedContext} used by the modules for the purpose of shielding framework implementation details.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"unused"})
|
|
||||||
@SuppressLint("DiscouragedApi")
|
|
||||||
public class XposedContextWrapper extends ContextWrapper implements XposedInterface {
|
|
||||||
|
|
||||||
XposedContextWrapper(@NonNull XposedContext base) {
|
|
||||||
super(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
XposedContextWrapper(@NonNull XposedContextWrapper base) {
|
|
||||||
super(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Xposed API version of current implementation.
|
|
||||||
*
|
|
||||||
* @return API version
|
|
||||||
*/
|
|
||||||
public final int getAPIVersion() {
|
|
||||||
return API;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the implementation {@link XposedContext}. Should not be used by modules.
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final XposedContext getBaseContext() {
|
|
||||||
return (XposedContext) super.getBaseContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final String getFrameworkName() {
|
|
||||||
return getBaseContext().getFrameworkName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final String getFrameworkVersion() {
|
|
||||||
return getBaseContext().getFrameworkVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final long getFrameworkVersionCode() {
|
|
||||||
return getBaseContext().getFrameworkVersionCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final int getFrameworkPrivilege() {
|
|
||||||
return getBaseContext().getFrameworkPrivilege();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final MethodUnhooker<Method> hook(@NonNull Method origin, @NonNull Class<? extends Hooker> hooker) {
|
|
||||||
return getBaseContext().hook(origin, hooker);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final MethodUnhooker<Method> hook(@NonNull Method origin, int priority, @NonNull Class<? extends Hooker> hooker) {
|
|
||||||
return getBaseContext().hook(origin, priority, hooker);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final <T> MethodUnhooker<Constructor<T>> hook(@NonNull Constructor<T> origin, @NonNull Class<? extends Hooker> hooker) {
|
|
||||||
return getBaseContext().hook(origin, hooker);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final <T> MethodUnhooker<Constructor<T>> hook(@NonNull Constructor<T> origin, int priority, @NonNull Class<? extends Hooker> hooker) {
|
|
||||||
return getBaseContext().hook(origin, priority, hooker);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean deoptimize(@NonNull Method method) {
|
|
||||||
return getBaseContext().deoptimize(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final <T> boolean deoptimize(@NonNull Constructor<T> constructor) {
|
|
||||||
return getBaseContext().deoptimize(constructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public final Object invokeOrigin(@NonNull Method method, @Nullable Object thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
|
|
||||||
return getBaseContext().invokeOrigin(method, thisObject, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public final Object invokeSpecial(@NonNull Method method, @NonNull Object thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
|
|
||||||
return getBaseContext().invokeSpecial(method, thisObject, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final <T> T newInstanceOrigin(@NonNull Constructor<T> constructor, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException {
|
|
||||||
return getBaseContext().newInstanceOrigin(constructor, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public final <T, U> U newInstanceSpecial(@NonNull Constructor<T> constructor, @NonNull Class<U> subClass, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException {
|
|
||||||
return getBaseContext().newInstanceSpecial(constructor, subClass, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void log(@NonNull String message) {
|
|
||||||
getBaseContext().log(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final void log(@NonNull String message, @NonNull Throwable throwable) {
|
|
||||||
getBaseContext().log(message, throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public final DexParser parseDex(@NonNull ByteBuffer dexData, boolean includeAnnotations) throws IOException {
|
|
||||||
return getBaseContext().parseDex(dexData, includeAnnotations);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected final void attachBaseContext(Context base) {
|
|
||||||
if (base instanceof XposedContext || base instanceof XposedContextWrapper) {
|
|
||||||
super.attachBaseContext(base);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -47,7 +47,7 @@ public interface XposedInterface {
|
||||||
int FRAMEWORK_PRIVILEGE_APP = 2;
|
int FRAMEWORK_PRIVILEGE_APP = 2;
|
||||||
/**
|
/**
|
||||||
* Indicates that the framework is embedded in the hooked app,
|
* Indicates that the framework is embedded in the hooked app,
|
||||||
* which means {@link #getSharedPreferences} will be null and remote file is unsupported.
|
* which means {@link #getRemotePreferences} will be null and remote file is unsupported.
|
||||||
*/
|
*/
|
||||||
int FRAMEWORK_PRIVILEGE_EMBEDDED = 3;
|
int FRAMEWORK_PRIVILEGE_EMBEDDED = 3;
|
||||||
|
|
||||||
|
|
@ -443,42 +443,49 @@ public interface XposedInterface {
|
||||||
@Nullable
|
@Nullable
|
||||||
DexParser parseDex(@NonNull ByteBuffer dexData, boolean includeAnnotations) throws IOException;
|
DexParser parseDex(@NonNull ByteBuffer dexData, boolean includeAnnotations) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
// Methods the same with Context
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets remote preferences stored in Xposed framework. Note that those are read-only in hooked apps.
|
* Gets the application info of the module.
|
||||||
*
|
*
|
||||||
* @see Context#getSharedPreferences(String, int)
|
* @see Context#getApplicationInfo()
|
||||||
*/
|
*/
|
||||||
SharedPreferences getSharedPreferences(String name, int mode);
|
@NonNull
|
||||||
|
ApplicationInfo getApplicationInfo();
|
||||||
/**
|
|
||||||
* Open a remote file stored in Xposed framework.
|
|
||||||
*
|
|
||||||
* @see Context#openFileInput(String)
|
|
||||||
*/
|
|
||||||
FileInputStream openFileInput(String name) throws FileNotFoundException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List all remote files stored in Xposed framework. Note that you can only access files created by
|
|
||||||
* your own module app with XposedService.
|
|
||||||
*
|
|
||||||
* @see Context#fileList()
|
|
||||||
*/
|
|
||||||
String[] fileList();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets resources of the module.
|
* Gets resources of the module.
|
||||||
*
|
*
|
||||||
* @see Context#getResources()
|
* @see Context#getResources()
|
||||||
*/
|
*/
|
||||||
|
@NonNull
|
||||||
Resources getResources();
|
Resources getResources();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the application info of the module.
|
* Gets remote preferences stored in Xposed framework. Note that those are read-only in hooked apps.
|
||||||
*
|
*
|
||||||
* @see Context#getApplicationInfo()
|
* @param group Group name
|
||||||
|
* @return The preferences, null if the group does not exists
|
||||||
|
* @throws UnsupportedOperationException If the framework is embedded
|
||||||
*/
|
*/
|
||||||
ApplicationInfo getApplicationInfo();
|
@Nullable
|
||||||
|
SharedPreferences getRemotePreferences(@NonNull String group);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open an InputStream to read a file from the module's shared data directory.
|
||||||
|
*
|
||||||
|
* @param name File name, must not contain path separators and . or ..
|
||||||
|
* @return The InputStream
|
||||||
|
* @throws FileNotFoundException If the file does not exist or the path is forbidden
|
||||||
|
* @throws UnsupportedOperationException If the framework is embedded
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
FileInputStream openRemoteFileInput(@NonNull String name) throws FileNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all files in the module's shared data directory.
|
||||||
|
*
|
||||||
|
* @return The file list
|
||||||
|
* @throws UnsupportedOperationException If the framework is embedded
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
String[] listRemoteFiles();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
package io.github.libxposed.api;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import io.github.libxposed.api.utils.DexParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap of {@link XposedInterface} used by the modules for the purpose of shielding framework implementation details.
|
||||||
|
*/
|
||||||
|
public class XposedInterfaceWrapper implements XposedInterface {
|
||||||
|
|
||||||
|
private final XposedInterface mBase;
|
||||||
|
|
||||||
|
XposedInterfaceWrapper(@NonNull XposedInterface base) {
|
||||||
|
mBase = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public final String getFrameworkName() {
|
||||||
|
return mBase.getFrameworkName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public final String getFrameworkVersion() {
|
||||||
|
return mBase.getFrameworkVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final long getFrameworkVersionCode() {
|
||||||
|
return mBase.getFrameworkVersionCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int getFrameworkPrivilege() {
|
||||||
|
return mBase.getFrameworkPrivilege();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public final MethodUnhooker<Method> hook(@NonNull Method origin, @NonNull Class<? extends Hooker> hooker) {
|
||||||
|
return mBase.hook(origin, hooker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public final MethodUnhooker<Method> hook(@NonNull Method origin, int priority, @NonNull Class<? extends Hooker> hooker) {
|
||||||
|
return mBase.hook(origin, priority, hooker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public final <T> MethodUnhooker<Constructor<T>> hook(@NonNull Constructor<T> origin, @NonNull Class<? extends Hooker> hooker) {
|
||||||
|
return mBase.hook(origin, hooker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public final <T> MethodUnhooker<Constructor<T>> hook(@NonNull Constructor<T> origin, int priority, @NonNull Class<? extends Hooker> hooker) {
|
||||||
|
return mBase.hook(origin, priority, hooker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean deoptimize(@NonNull Method method) {
|
||||||
|
return mBase.deoptimize(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final <T> boolean deoptimize(@NonNull Constructor<T> constructor) {
|
||||||
|
return mBase.deoptimize(constructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public final Object invokeOrigin(@NonNull Method method, @Nullable Object thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
|
||||||
|
return mBase.invokeOrigin(method, thisObject, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public final Object invokeSpecial(@NonNull Method method, @NonNull Object thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
|
||||||
|
return mBase.invokeSpecial(method, thisObject, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public final <T> T newInstanceOrigin(@NonNull Constructor<T> constructor, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException {
|
||||||
|
return mBase.newInstanceOrigin(constructor, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public final <T, U> U newInstanceSpecial(@NonNull Constructor<T> constructor, @NonNull Class<U> subClass, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException {
|
||||||
|
return mBase.newInstanceSpecial(constructor, subClass, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void log(@NonNull String message) {
|
||||||
|
mBase.log(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void log(@NonNull String message, @NonNull Throwable throwable) {
|
||||||
|
mBase.log(message, throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public final DexParser parseDex(@NonNull ByteBuffer dexData, boolean includeAnnotations) throws IOException {
|
||||||
|
return mBase.parseDex(dexData, includeAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SharedPreferences getRemotePreferences(@NonNull String name) {
|
||||||
|
return mBase.getRemotePreferences(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ApplicationInfo getApplicationInfo() {
|
||||||
|
return mBase.getApplicationInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Resources getResources() {
|
||||||
|
return mBase.getResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public FileInputStream openRemoteFileInput(@NonNull String name) throws FileNotFoundException {
|
||||||
|
return mBase.openRemoteFileInput(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String[] listRemoteFiles() {
|
||||||
|
return mBase.listRemoteFiles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,15 +7,15 @@ import androidx.annotation.NonNull;
|
||||||
* Entry classes will be instantiated exactly once for each process.
|
* Entry classes will be instantiated exactly once for each process.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public abstract class XposedModule extends XposedContextWrapper implements XposedModuleInterface {
|
public abstract class XposedModule extends XposedInterfaceWrapper implements XposedModuleInterface {
|
||||||
/**
|
/**
|
||||||
* Instantiates a new Xposed module.<br/>
|
* Instantiates a new Xposed module.<br/>
|
||||||
* When the module is loaded into the target process, the constructor will be called.
|
* When the module is loaded into the target process, the constructor will be called.
|
||||||
*
|
*
|
||||||
* @param base The base context provided by the framework, should not be used by the module
|
* @param base The implementation interface provided by the framework, should not be used by the module
|
||||||
* @param param Information about the process in which the module is loaded
|
* @param param Information about the process in which the module is loaded
|
||||||
*/
|
*/
|
||||||
public XposedModule(@NonNull XposedContext base, @NonNull ModuleLoadedParam param) {
|
public XposedModule(@NonNull XposedInterface base, @NonNull ModuleLoadedParam param) {
|
||||||
super(base);
|
super(base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue