From 53d75bd10e1ae86c634cf6de46df9a9212951200 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Mon, 2 Jan 2023 17:27:37 +0800 Subject: [PATCH] Move libxposed to a standalone gradle module --- api/.gitignore | 1 + api/build.gradle.kts | 12 ++ .../main/java/android/content/Context.java | 4 + .../java/android/content/ContextWrapper.java | 16 +++ .../android/content/pm/ApplicationInfo.java | 4 + .../android/content/res/AssetManager.java | 4 + .../android/content/res/Configuration.java | 4 + .../java/android/content/res/Resources.java | 13 ++ .../java/android/content/res/TypedArray.java | 7 ++ api/src/main/java/android/os/Bundle.java | 4 + .../java/android/util/DisplayMetrics.java | 4 + .../io/github/libxposed/XposedContext.java | 0 .../libxposed/XposedContextWrapper.java | 0 .../io/github/libxposed/XposedInterface.java | 3 +- .../io/github/libxposed/XposedModule.java | 0 .../libxposed/XposedModuleInterface.java | 1 - .../io/github/libxposed}/XposedResources.java | 8 +- .../io/github/libxposed/XposedTypedArray.java | 10 ++ .../java/io/github/libxposed/XposedUtils.java | 0 core/build.gradle.kts | 118 +----------------- .../java/android/content/res/XResources.java | 3 +- .../android/content/res/XposedTypedArray.java | 7 -- .../callbacks/XC_InitPackageResources.java | 2 +- magisk-loader/build.gradle.kts | 98 +++++++++++++++ settings.gradle.kts | 1 + 25 files changed, 193 insertions(+), 131 deletions(-) create mode 100644 api/.gitignore create mode 100644 api/build.gradle.kts create mode 100644 api/src/main/java/android/content/Context.java create mode 100644 api/src/main/java/android/content/ContextWrapper.java create mode 100644 api/src/main/java/android/content/pm/ApplicationInfo.java create mode 100644 api/src/main/java/android/content/res/AssetManager.java create mode 100644 api/src/main/java/android/content/res/Configuration.java create mode 100644 api/src/main/java/android/content/res/Resources.java create mode 100644 api/src/main/java/android/content/res/TypedArray.java create mode 100644 api/src/main/java/android/os/Bundle.java create mode 100644 api/src/main/java/android/util/DisplayMetrics.java rename {core => api}/src/main/java/io/github/libxposed/XposedContext.java (100%) rename {core => api}/src/main/java/io/github/libxposed/XposedContextWrapper.java (100%) rename {core => api}/src/main/java/io/github/libxposed/XposedInterface.java (98%) rename {core => api}/src/main/java/io/github/libxposed/XposedModule.java (100%) rename {core => api}/src/main/java/io/github/libxposed/XposedModuleInterface.java (96%) rename {core/src/main/java/android/content/res => api/src/main/java/io/github/libxposed}/XposedResources.java (62%) create mode 100644 api/src/main/java/io/github/libxposed/XposedTypedArray.java rename {core => api}/src/main/java/io/github/libxposed/XposedUtils.java (100%) delete mode 100644 core/src/main/java/android/content/res/XposedTypedArray.java diff --git a/api/.gitignore b/api/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/api/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/api/build.gradle.kts b/api/build.gradle.kts new file mode 100644 index 00000000..a42021f8 --- /dev/null +++ b/api/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("java-library") +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { + compileOnly("androidx.annotation:annotation:1.5.0") +} diff --git a/api/src/main/java/android/content/Context.java b/api/src/main/java/android/content/Context.java new file mode 100644 index 00000000..95cd2c6a --- /dev/null +++ b/api/src/main/java/android/content/Context.java @@ -0,0 +1,4 @@ +package android.content; + +public abstract class Context { +} diff --git a/api/src/main/java/android/content/ContextWrapper.java b/api/src/main/java/android/content/ContextWrapper.java new file mode 100644 index 00000000..78e4d6eb --- /dev/null +++ b/api/src/main/java/android/content/ContextWrapper.java @@ -0,0 +1,16 @@ +package android.content; + +public class ContextWrapper extends Context { + public ContextWrapper(Context base) { + throw new UnsupportedOperationException("STUB"); + } + + protected void attachBaseContext(Context base) { + throw new UnsupportedOperationException("STUB"); + } + + public Context getBaseContext() { + throw new UnsupportedOperationException("SUTB"); + } + +} diff --git a/api/src/main/java/android/content/pm/ApplicationInfo.java b/api/src/main/java/android/content/pm/ApplicationInfo.java new file mode 100644 index 00000000..e0d81c50 --- /dev/null +++ b/api/src/main/java/android/content/pm/ApplicationInfo.java @@ -0,0 +1,4 @@ +package android.content.pm; + +public class ApplicationInfo { +} diff --git a/api/src/main/java/android/content/res/AssetManager.java b/api/src/main/java/android/content/res/AssetManager.java new file mode 100644 index 00000000..c69204dc --- /dev/null +++ b/api/src/main/java/android/content/res/AssetManager.java @@ -0,0 +1,4 @@ +package android.content.res; + +public class AssetManager { +} diff --git a/api/src/main/java/android/content/res/Configuration.java b/api/src/main/java/android/content/res/Configuration.java new file mode 100644 index 00000000..80e4df10 --- /dev/null +++ b/api/src/main/java/android/content/res/Configuration.java @@ -0,0 +1,4 @@ +package android.content.res; + +public class Configuration { +} diff --git a/api/src/main/java/android/content/res/Resources.java b/api/src/main/java/android/content/res/Resources.java new file mode 100644 index 00000000..c9f1ae9f --- /dev/null +++ b/api/src/main/java/android/content/res/Resources.java @@ -0,0 +1,13 @@ +package android.content.res; + +import android.util.DisplayMetrics; + +public class Resources { + protected Resources(ClassLoader classLoader) { + throw new UnsupportedOperationException("STUB"); + } + + protected Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) { + throw new UnsupportedOperationException("STUB"); + } +} diff --git a/api/src/main/java/android/content/res/TypedArray.java b/api/src/main/java/android/content/res/TypedArray.java new file mode 100644 index 00000000..d7428efa --- /dev/null +++ b/api/src/main/java/android/content/res/TypedArray.java @@ -0,0 +1,7 @@ +package android.content.res; + +public class TypedArray { + protected TypedArray(Resources resources) { + throw new UnsupportedOperationException("STUB"); + } +} diff --git a/api/src/main/java/android/os/Bundle.java b/api/src/main/java/android/os/Bundle.java new file mode 100644 index 00000000..49ff9ee2 --- /dev/null +++ b/api/src/main/java/android/os/Bundle.java @@ -0,0 +1,4 @@ +package android.os; + +public class Bundle { +} diff --git a/api/src/main/java/android/util/DisplayMetrics.java b/api/src/main/java/android/util/DisplayMetrics.java new file mode 100644 index 00000000..35c44ff0 --- /dev/null +++ b/api/src/main/java/android/util/DisplayMetrics.java @@ -0,0 +1,4 @@ +package android.util; + +public class DisplayMetrics { +} diff --git a/core/src/main/java/io/github/libxposed/XposedContext.java b/api/src/main/java/io/github/libxposed/XposedContext.java similarity index 100% rename from core/src/main/java/io/github/libxposed/XposedContext.java rename to api/src/main/java/io/github/libxposed/XposedContext.java diff --git a/core/src/main/java/io/github/libxposed/XposedContextWrapper.java b/api/src/main/java/io/github/libxposed/XposedContextWrapper.java similarity index 100% rename from core/src/main/java/io/github/libxposed/XposedContextWrapper.java rename to api/src/main/java/io/github/libxposed/XposedContextWrapper.java diff --git a/core/src/main/java/io/github/libxposed/XposedInterface.java b/api/src/main/java/io/github/libxposed/XposedInterface.java similarity index 98% rename from core/src/main/java/io/github/libxposed/XposedInterface.java rename to api/src/main/java/io/github/libxposed/XposedInterface.java index 65f1bdc3..06df16f3 100644 --- a/core/src/main/java/io/github/libxposed/XposedInterface.java +++ b/api/src/main/java/io/github/libxposed/XposedInterface.java @@ -110,7 +110,8 @@ public interface XposedInterface { boolean deoptimize(@Nullable Constructor constructor); - @Nullable XposedUtils getUtils(); + @Nullable + XposedUtils getUtils(); void log(@NonNull String message); diff --git a/core/src/main/java/io/github/libxposed/XposedModule.java b/api/src/main/java/io/github/libxposed/XposedModule.java similarity index 100% rename from core/src/main/java/io/github/libxposed/XposedModule.java rename to api/src/main/java/io/github/libxposed/XposedModule.java diff --git a/core/src/main/java/io/github/libxposed/XposedModuleInterface.java b/api/src/main/java/io/github/libxposed/XposedModuleInterface.java similarity index 96% rename from core/src/main/java/io/github/libxposed/XposedModuleInterface.java rename to api/src/main/java/io/github/libxposed/XposedModuleInterface.java index 509fceee..664a6f64 100644 --- a/core/src/main/java/io/github/libxposed/XposedModuleInterface.java +++ b/api/src/main/java/io/github/libxposed/XposedModuleInterface.java @@ -1,7 +1,6 @@ package io.github.libxposed; import android.content.pm.ApplicationInfo; -import android.content.res.XposedResources; import android.os.Bundle; import androidx.annotation.NonNull; diff --git a/core/src/main/java/android/content/res/XposedResources.java b/api/src/main/java/io/github/libxposed/XposedResources.java similarity index 62% rename from core/src/main/java/android/content/res/XposedResources.java rename to api/src/main/java/io/github/libxposed/XposedResources.java index 60a29118..01bb1311 100644 --- a/core/src/main/java/android/content/res/XposedResources.java +++ b/api/src/main/java/io/github/libxposed/XposedResources.java @@ -1,14 +1,16 @@ -package android.content.res; +package io.github.libxposed; +import android.content.res.AssetManager; +import android.content.res.Configuration; +import android.content.res.Resources; import android.util.DisplayMetrics; public abstract class XposedResources extends Resources { - @SuppressWarnings("deprecation") public XposedResources(AssetManager assets, DisplayMetrics metrics, Configuration config) { super(assets, metrics, config); } public XposedResources(ClassLoader classLoader) { - super(null, null, null); + super(classLoader); } } diff --git a/api/src/main/java/io/github/libxposed/XposedTypedArray.java b/api/src/main/java/io/github/libxposed/XposedTypedArray.java new file mode 100644 index 00000000..d5cb616c --- /dev/null +++ b/api/src/main/java/io/github/libxposed/XposedTypedArray.java @@ -0,0 +1,10 @@ +package io.github.libxposed; + +import android.content.res.Resources; +import android.content.res.TypedArray; + +public class XposedTypedArray extends TypedArray { + public XposedTypedArray(Resources resources) { + super(resources); + } +} diff --git a/core/src/main/java/io/github/libxposed/XposedUtils.java b/api/src/main/java/io/github/libxposed/XposedUtils.java similarity index 100% rename from core/src/main/java/io/github/libxposed/XposedUtils.java rename to api/src/main/java/io/github/libxposed/XposedUtils.java diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 613e8cc5..42bd5a29 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -17,17 +17,6 @@ * Copyright (C) 2021 - 2022 LSPosed Contributors */ -import com.android.build.api.instrumentation.AsmClassVisitorFactory -import com.android.build.api.instrumentation.ClassContext -import com.android.build.api.instrumentation.ClassData -import com.android.build.api.instrumentation.InstrumentationParameters -import com.android.build.api.instrumentation.InstrumentationScope -import com.android.build.api.instrumentation.FramesComputationMode -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Opcodes -import org.objectweb.asm.Type - val apiCode: Int by rootProject.extra val verName: String by rootProject.extra val verCode: Int by rootProject.extra @@ -64,112 +53,6 @@ copy { into("src/main/jni/src/") } -abstract class ExampleClassVisitorFactory : AsmClassVisitorFactory { - override fun createClassVisitor( - classContext: ClassContext, nextClassVisitor: ClassVisitor - ): ClassVisitor { - return object : ClassVisitor(Opcodes.ASM9, nextClassVisitor) { - override fun visit( - version: Int, - access: Int, - name: String?, - signature: String?, - superName: String?, - interfaces: Array? - ) { - val newSuperName = "xposed/dummy/X${superName?.substringAfterLast('/')}SuperClass" - println("replace super class of $name to $newSuperName") - super.visit( - version, - access, - name, - signature, - newSuperName, - interfaces - ) - } - - override fun visitMethod( - access: Int, - name: String?, - descriptor: String?, - signature: String?, - exceptions: Array? - ): MethodVisitor { - return object : MethodVisitor( - Opcodes.ASM9, super.visitMethod( - access, - name, - descriptor, - signature, - exceptions - ) - ) { - override fun visitVarInsn(opcode: Int, `var`: Int) { - } - - override fun visitInsn(opcode: Int) { - if (opcode != Opcodes.ACONST_NULL) { - super.visitInsn(opcode) - } - } - - override fun visitMaxs(maxStack: Int, maxLocals: Int) { - super.visitMaxs( - if (maxLocals > maxStack) maxLocals else maxStack, - maxLocals - ) - } - - override fun visitMethodInsn( - opcode: Int, - owner: String?, - name: String?, - instDescriptor: String?, - isInterface: Boolean - ) { - if (opcode == Opcodes.INVOKESPECIAL) { - for (i in 0 .. Type.getMethodType(descriptor).argumentTypes.size) { - super.visitVarInsn(Opcodes.ALOAD, i) - } - val newOwner = - "xposed/dummy/X${owner?.substringAfterLast('/')}SuperClass" - println("replace method call of $owner.$name$instDescriptor to $newOwner.$name$descriptor") - super.visitMethodInsn( - opcode, - newOwner, - name, - descriptor, - isInterface - ) - } else { - super.visitMethodInsn( - opcode, - owner, - name, - instDescriptor, - isInterface - ) - } - } - } - } - } - } - - override fun isInstrumentable(classData: ClassData): Boolean { - return classData.className.startsWith("android.content.res.Xposed") - } -} - - -androidComponents.onVariants { variant -> - variant.instrumentation.transformClassesWith( - ExampleClassVisitorFactory::class.java, InstrumentationScope.PROJECT - ) {} - variant.instrumentation.setAsmFramesComputationMode(FramesComputationMode.COPY_FRAMES) -} - dependencies { implementation("org.apache.commons:commons-lang3:3.12.0") implementation("de.upb.cs.swt:axml:2.1.3") @@ -178,4 +61,5 @@ dependencies { implementation(projects.hiddenapi.bridge) implementation(projects.services.daemonService) implementation(projects.services.managerService) + implementation(projects.api) } diff --git a/core/src/main/java/android/content/res/XResources.java b/core/src/main/java/android/content/res/XResources.java index b14fdef4..fd89bfec 100644 --- a/core/src/main/java/android/content/res/XResources.java +++ b/core/src/main/java/android/content/res/XResources.java @@ -66,7 +66,8 @@ import de.robv.android.xposed.XposedInit; import de.robv.android.xposed.callbacks.XC_LayoutInflated; import de.robv.android.xposed.callbacks.XC_LayoutInflated.LayoutInflatedParam; import de.robv.android.xposed.callbacks.XCallback; -import xposed.dummy.XTypedArraySuperClass; +import io.github.libxposed.XposedResources; +import io.github.libxposed.XposedTypedArray; /** * {@link android.content.res.Resources} subclass that allows replacing individual resources. diff --git a/core/src/main/java/android/content/res/XposedTypedArray.java b/core/src/main/java/android/content/res/XposedTypedArray.java deleted file mode 100644 index 1309a845..00000000 --- a/core/src/main/java/android/content/res/XposedTypedArray.java +++ /dev/null @@ -1,7 +0,0 @@ -package android.content.res; - -public class XposedTypedArray extends TypedArray { - public XposedTypedArray(Resources resources) { - super(); - } -} diff --git a/core/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java b/core/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java index edbcb2f8..24a75b9a 100644 --- a/core/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java +++ b/core/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java @@ -21,7 +21,6 @@ package de.robv.android.xposed.callbacks; import android.content.res.XResources; -import android.content.res.XposedResources; import android.os.Bundle; import androidx.annotation.NonNull; @@ -31,6 +30,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import de.robv.android.xposed.IXposedHookInitPackageResources; import io.github.libxposed.XposedModuleInterface; +import io.github.libxposed.XposedResources; /** * This class is only used for internal purposes, except for the {@link InitPackageResourcesParam} diff --git a/magisk-loader/build.gradle.kts b/magisk-loader/build.gradle.kts index f05a7a78..8990f70a 100644 --- a/magisk-loader/build.gradle.kts +++ b/magisk-loader/build.gradle.kts @@ -23,6 +23,15 @@ import org.apache.tools.ant.filters.ReplaceTokens import java.io.ByteArrayOutputStream import java.security.MessageDigest import java.util.Locale +import com.android.build.api.instrumentation.AsmClassVisitorFactory +import com.android.build.api.instrumentation.ClassContext +import com.android.build.api.instrumentation.ClassData +import com.android.build.api.instrumentation.InstrumentationParameters +import com.android.build.api.instrumentation.InstrumentationScope +import com.android.build.api.instrumentation.FramesComputationMode +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes plugins { id("com.android.application") @@ -321,5 +330,94 @@ task("reRunApp") { finalizedBy(reRunDaemon) } +abstract class ExampleClassVisitorFactory : + AsmClassVisitorFactory { + override fun createClassVisitor( + classContext: ClassContext, + nextClassVisitor: ClassVisitor + ): ClassVisitor { + return object : + ClassVisitor(Opcodes.ASM9, nextClassVisitor) { + override fun visit( + version: Int, + access: Int, + name: String?, + signature: String?, + superName: String?, + interfaces: Array? + ) { + val newSuperName = "xposed/dummy/X${superName?.substringAfterLast('/')}SuperClass" + println("replace super class of $name to $newSuperName") + super.visit( + version, + access, + name, + signature, + newSuperName, + interfaces + ) + } + + override fun visitMethod( + access: Int, + name: String?, + descriptor: String?, + signature: String?, + exceptions: Array? + ): MethodVisitor { + return object : MethodVisitor( + Opcodes.ASM9, super.visitMethod( + access, + name, + descriptor, + signature, + exceptions + ) + ) { + override fun visitMethodInsn( + opcode: Int, + owner: String?, + name: String?, + instDescriptor: String?, + isInterface: Boolean + ) { + if (opcode == Opcodes.INVOKESPECIAL) { + val newOwner = + "xposed/dummy/X${owner?.substringAfterLast('/')}SuperClass" + println("replace method call of $owner.$name$instDescriptor to $newOwner.$name$descriptor") + super.visitMethodInsn( + opcode, + newOwner, + name, + descriptor, + isInterface + ) + } else { + super.visitMethodInsn( + opcode, + owner, + name, + instDescriptor, + isInterface + ) + } + } + } + } + } + } + + override fun isInstrumentable(classData: ClassData): Boolean { + return classData.className == "io.github.libxposed.XposedResources" || classData.className == "io.github.libxposed.XposedTypedArray" + } +} + +androidComponents.onVariants { variant -> + variant.instrumentation.transformClassesWith( + ExampleClassVisitorFactory::class.java, InstrumentationScope.ALL + ) {} + variant.instrumentation.setAsmFramesComputationMode(FramesComputationMode.COPY_FRAMES) +} + evaluationDependsOn(":app") evaluationDependsOn(":daemon") diff --git a/settings.gradle.kts b/settings.gradle.kts index d894ea57..6fae2fae 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -30,6 +30,7 @@ dependencyResolutionManagement { rootProject.name = "LSPosed" include( ":app", + ":api", ":core", ":daemon", ":dex2oat",