1
mirror of https://github.com/revanced/revanced-patcher synced 2025-09-06 16:38:50 +02:00

Compare commits

..

17 Commits

Author SHA1 Message Date
semantic-release-bot
9ce772a597 chore(release): 20.0.0-dev.1 [skip ci]
# [20.0.0-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v19.3.1...v20.0.0-dev.1) (2024-07-22)

### Features

* Convert APIs to Kotlin DSL ([#298](https://github.com/ReVanced/revanced-patcher/issues/298)) ([3f9cbd2](3f9cbd2408))

### BREAKING CHANGES

* Various old APIs are removed, and DSL APIs are added instead.
2024-07-22 01:11:38 +00:00
oSumAtrIX
3f9cbd2408 feat: Convert APIs to Kotlin DSL (#298)
This commit converts various APIs to Kotlin DSL.

BREAKING CHANGE: Various old APIs are removed, and DSL APIs are added instead.
2024-07-21 22:45:45 +02:00
oSumAtrIX
1ff0830249 ci: Correct usage of repository variable 2024-07-13 00:44:51 +02:00
oSumAtrIX
7be131d348 docs: Improve issue templates 2024-05-26 00:43:39 +02:00
oSumAtrIX
1d78d690bb chore: Fix spelling mistake 2024-04-07 18:22:00 +02:00
Vologhat
042f554d75 refactor: Simplify mapping classes to their names (#290)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-07 17:54:37 +02:00
oSumAtrIX
f63302feab build: Publish sources 2024-03-14 12:21:48 +01:00
oSumAtrIX
1614d7f9f4 build: Set target bytecode level to JVM 11 2024-03-04 19:15:07 +01:00
oSumAtrIX
d64776c933 ci: Update action 2024-03-04 15:36:36 +01:00
oSumAtrIX
03cd9f7f54 chore: Lint code 2024-03-03 00:25:28 +01:00
oSumAtrIX
b69226dd26 build: Bump dependencies 2024-03-02 08:29:38 +01:00
oSumAtrIX
8e1117ed3f refactor: Properly abstract Patch#execute function 2024-02-26 16:45:03 +01:00
oSumAtrIX
29adcd5aad docs: Fix broken links 2024-02-26 04:37:45 +01:00
oSumAtrIX
6b2bc5ef4d docs: Fix docs link [skip ci] 2024-02-25 19:49:40 +01:00
oSumAtrIX
d862d61386 docs: Un-indent markdown to fix rendering 2024-02-25 04:50:44 +01:00
oSumAtrIX
a4e18334bc chore: Revert using a relative image path
For some reason GitHub does not render them correctly
2024-02-25 03:40:20 +01:00
oSumAtrIX
5bef74adb5 build: Bump dependencies 2024-02-25 03:40:20 +01:00
49 changed files with 1585 additions and 2648 deletions

View File

@@ -10,9 +10,6 @@ on:
jobs:
release:
name: Release
permissions:
contents: write
packages: write
runs-on: ubuntu-latest
steps:
- name: Checkout
@@ -49,5 +46,5 @@ jobs:
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
run: npm exec semantic-release

View File

@@ -23,8 +23,7 @@
"assets": [
"CHANGELOG.md",
"gradle.properties"
],
"message": "chore: Release v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
]
}
],
[

View File

@@ -1,69 +1,3 @@
## [20.0.1-dev.3](https://github.com/ReVanced/revanced-patcher/compare/v20.0.1-dev.2...v20.0.1-dev.3) (2024-10-03)
### Performance Improvements
* Free memory earlier and remove negligible lookup maps ([d53aacd](https://github.com/ReVanced/revanced-patcher/commit/d53aacdad4ed3750ddae526fb307577ea36e6171))
## [20.0.1-dev.2](https://github.com/ReVanced/revanced-patcher/compare/v20.0.1-dev.1...v20.0.1-dev.2) (2024-10-01)
## [20.0.1-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0...v20.0.1-dev.1) (2024-09-18)
### Bug Fixes
* Check for class type exactly instead of with contains ([#310](https://github.com/ReVanced/revanced-patcher/issues/310)) ([69f2f20](https://github.com/ReVanced/revanced-patcher/commit/69f2f20fd99162f91cd9c531dfe47d00d3152ead))
# [20.0.0](https://github.com/ReVanced/revanced-patcher/compare/v19.3.1...v20.0.0) (2024-08-06)
### Bug Fixes
* Downgrade smali to fix dex compilation issue ([5227e98](https://github.com/ReVanced/revanced-patcher/commit/5227e98abfaa2ff1204eb20a0f2671f58c489930))
* Improve exception message wording ([5481d0c](https://github.com/ReVanced/revanced-patcher/commit/5481d0c54ccecc91cd8d15af1ba2d3285a33e5ab))
* Make constructor internal as supposed ([7f44174](https://github.com/ReVanced/revanced-patcher/commit/7f44174d91f0af0d50a83d80a7103c779241e094))
* Merge all extensions before initializing lookup maps ([8c4dd5b](https://github.com/ReVanced/revanced-patcher/commit/8c4dd5b3a309077fa9a3827b4931fc28b0517809))
* Use null for compatible package version when adding packages only ([736b3ee](https://github.com/ReVanced/revanced-patcher/commit/736b3eebbfdd7279b8d5fcfc5c46c9e3aadbee12))
### Features
* Add ability to create options outside of a patch ([d310246](https://github.com/ReVanced/revanced-patcher/commit/d310246852504b08a15f6376bbf25ac7c6fae76f))
* Convert APIs to Kotlin DSL ([#298](https://github.com/ReVanced/revanced-patcher/issues/298)) ([11a911d](https://github.com/ReVanced/revanced-patcher/commit/11a911dc674eb0801649949dd3f28dfeb00efe97))
### BREAKING CHANGES
* Various old APIs are removed, and DSL APIs are added instead.
# [20.0.0-dev.4](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.3...v20.0.0-dev.4) (2024-08-06)
### Bug Fixes
* Improve exception message wording ([bd434ce](https://github.com/ReVanced/revanced-patcher/commit/bd434ceb3394d1d5292e8b94e5bfd6da0e4e9c72))
# [20.0.0-dev.3](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.2...v20.0.0-dev.3) (2024-08-01)
### Bug Fixes
* Make constructor internal as supposed ([e95fcd1](https://github.com/ReVanced/revanced-patcher/commit/e95fcd1c0b641164bbf0840ec7e562aeb3bacc3e))
### Features
* Add ability to create options outside of a patch ([b8d763a](https://github.com/ReVanced/revanced-patcher/commit/b8d763a66e0601627dd71c8c24247726aa300146))
# [20.0.0-dev.2](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.1...v20.0.0-dev.2) (2024-07-31)
### Bug Fixes
* Downgrade smali to fix dex compilation issue ([714447d](https://github.com/ReVanced/revanced-patcher/commit/714447de70096bf736e8e1d31c14bb5f24195070))
* Merge all extensions before initializing lookup maps ([328aa87](https://github.com/ReVanced/revanced-patcher/commit/328aa876d8ed7826be3713754b6404195e9fe84b))
* Use null for compatible package version when adding packages only ([a8e8fa4](https://github.com/ReVanced/revanced-patcher/commit/a8e8fa4093deb8cffbd7a582409f41867f6b568b))
# [20.0.0-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v19.3.1...v20.0.0-dev.1) (2024-07-22)

View File

@@ -67,8 +67,7 @@ public final class app/revanced/patcher/PatcherConfig {
public synthetic fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/PatcherContext : java/io/Closeable {
public fun close ()V
public final class app/revanced/patcher/PatcherContext {
public final fun getPackageMetadata ()Lapp/revanced/patcher/PackageMetadata;
}
@@ -149,13 +148,13 @@ public final class app/revanced/patcher/patch/BytecodePatchBuilder : app/revance
}
public final class app/revanced/patcher/patch/BytecodePatchBuilder$InvokedFingerprint {
public fun <init> (Lapp/revanced/patcher/Fingerprint;)V
public final fun getValue (Ljava/lang/Void;Lkotlin/reflect/KProperty;)Lapp/revanced/patcher/Match;
}
public final class app/revanced/patcher/patch/BytecodePatchContext : app/revanced/patcher/patch/PatchContext, java/io/Closeable {
public final class app/revanced/patcher/patch/BytecodePatchContext : app/revanced/patcher/patch/PatchContext {
public final fun classBy (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun classByType (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public fun close ()V
public synthetic fun get ()Ljava/lang/Object;
public fun get ()Ljava/util/Set;
public final fun getClasses ()Lapp/revanced/patcher/util/ProxyClassList;
@@ -204,43 +203,25 @@ public final class app/revanced/patcher/patch/OptionException$ValueValidationExc
public final class app/revanced/patcher/patch/OptionKt {
public static final fun booleanOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun booleanOption (Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun booleanOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun booleanOption$default (Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun booleansOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun booleansOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun booleansOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun booleansOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun floatOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun floatOption (Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun floatOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun floatOption$default (Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun floatsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun floatsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun intOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun intOption (Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun intOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun intOption$default (Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun intsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun intsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun intsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun intsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun longOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun longOption (Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun longOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun longOption$default (Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun longsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun longsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun longsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun longsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun stringOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun stringOption (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun stringOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun stringOption$default (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static final fun stringsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static final fun stringsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun stringsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
public static synthetic fun stringsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
}
public final class app/revanced/patcher/patch/Options : java/util/Map, kotlin/jvm/internal/markers/KMappedMarker {

View File

@@ -36,21 +36,20 @@ repositories {
}
dependencies {
implementation(libs.kotlinx.coroutines.core)
implementation(libs.xpp3)
implementation(libs.smali)
implementation(libs.multidexlib2)
implementation(libs.apktool.lib)
implementation(libs.kotlin.reflect)
// TODO: Convert project to KMP.
compileOnly(libs.android) {
// Exclude, otherwise the org.w3c.dom API breaks.
exclude(group = "xerces", module = "xmlParserAPIs")
}
implementation(libs.apktool.lib)
implementation(libs.kotlin.reflect)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.multidexlib2)
implementation(libs.smali)
implementation(libs.xpp3)
testImplementation(libs.mockk)
testImplementation(libs.kotlin.test)
testImplementation(libs.mockk)
}
kotlin {

View File

@@ -115,9 +115,9 @@ val disableAdsPatch = bytecodePatch(
Patches can have options to get and set before a patch is executed.
Options are useful for making patches configurable.
After loading the patches using `PatchLoader`, options can be set for a patch.
Multiple types are already built into ReVanced Patcher and are supported by any application that uses ReVanced Patcher.
Multiple types are already inbuilt in ReVanced Patcher and are supported by any application that uses ReVanced Patcher.
To define an option, use the available `option` functions:
To define an option, use available `option` functions:
```kt
val patch = bytecodePatch(name = "Patch") {
@@ -149,21 +149,9 @@ The type of an option can be obtained from the `type` property of the option:
option.type // The KType of the option.
```
Options can be declared outside of a patch and added to a patch manually:
```kt
val option = stringOption(key = "option")
bytecodePatch(name = "Patch") {
val value by option()
}
```
This is useful when the same option is referenced in multiple patches.
### 🧩 Extensions
An extension is a precompiled DEX file merged into the patched app before a patch is executed.
An extension is a precompiled DEX file that is merged into the patched app before a patch is executed.
While patches are compile-time constructs, extensions are runtime constructs
that extend the patched app with additional classes.
@@ -244,13 +232,13 @@ The same order is followed for multiple patches depending on the patch.
## 💡 Additional tips
- When using `PatchLoader` to load patches, only patches with a name are loaded.
- When using ´PatchLoader` to load patches, only patches with a name are loaded.
Refer to the inline documentation of `PatchLoader` for detailed information.
- Patches can depend on others. Dependencies are executed first.
The dependent patch will not be executed if a dependency raises an exception while executing.
- A patch can declare compatibility with specific packages and versions,
but patches can still be executed on any package or version.
It is recommended that compatibility is specified to present known compatible packages and versions.
It is recommended to declare compatibility to present known compatible packages and versions.
- If `compatibleWith` is not used, the patch is treated as compatible with any package
- If a package is specified with no versions, the patch is compatible with any version of the package
- If an empty array of versions is specified, the patch is not compatible with any version of the package.

View File

@@ -108,7 +108,7 @@ val rawResourcePatch = rawResourcePatch {
}
@Surpress("unused")
val resourcePatch = resourcePatch {
val resourcePatch = rawResourcePatch {
execute {
// TODO
}

View File

@@ -1,3 +1,3 @@
org.gradle.parallel = true
org.gradle.caching = true
version = 20.0.1-dev.3
version = 20.0.0-dev.1

View File

@@ -1,22 +1,20 @@
[versions]
android = "4.1.1.4"
apktool-lib = "2.9.3"
binary-compatibility-validator = "0.15.1"
kotlin = "2.0.0"
kotlinx-coroutines-core = "1.8.1"
kotlin = "1.9.22"
kotlinx-coroutines-core = "1.7.3"
mockk = "1.13.10"
multidexlib2 = "3.0.3.r3"
# Tracking https://github.com/google/smali/issues/64.
#noinspection GradleDependency
smali = "3.0.5"
binary-compatibility-validator = "0.14.0"
xpp3 = "1.1.4c"
[libraries]
android = { module = "com.google.android:android", version.ref = "android" }
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
smali = { module = "com.android.tools.smali:smali", version.ref = "smali" }

Binary file not shown.

View File

@@ -1,8 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStorePath=wrapper/dist

22
gradlew vendored
View File

@@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -57,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -85,9 +83,7 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -148,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -156,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -205,11 +201,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

22
gradlew.bat vendored
View File

@@ -13,8 +13,6 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -45,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
@@ -59,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail

2976
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
"@saithodev/semantic-release-backmerge": "^4.0.1",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"gradle-semantic-release-plugin": "^1.10.1",
"semantic-release": "^24.1.2"
"gradle-semantic-release-plugin": "^1.9.1",
"semantic-release": "^23.0.2"
}
}

View File

@@ -3,7 +3,8 @@
package app.revanced.patcher
import app.revanced.patcher.extensions.InstructionExtensions.instructionsOrNull
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.BytecodePatchBuilder
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.patch.BytecodePatchContext.LookupMaps.Companion.appendParameters
import app.revanced.patcher.patch.MethodClassPairs
import app.revanced.patcher.util.proxy.ClassProxy
@@ -66,15 +67,36 @@ class Fingerprint internal constructor(
}
// TODO: If only one string is necessary, why not use a single string for every fingerprint?
if (strings?.firstNotNullOfOrNull { lookupMaps.methodsByStrings[it] }?.let(::match) == true) {
fun Fingerprint.lookupByStrings() = strings?.firstNotNullOfOrNull { lookupMaps.methodsByStrings[it] }
if (lookupByStrings()?.let(::match) == true) {
return true
}
context.classes.forEach { classDef ->
if (match(context, classDef)) return true
}
// No strings declared or none matched (partial matches are allowed).
// Use signature matching.
fun Fingerprint.lookupBySignature(): MethodClassPairs {
if (accessFlags == null) return lookupMaps.allMethods
return false
var returnTypeValue = returnType
if (returnTypeValue == null) {
if (AccessFlags.CONSTRUCTOR.isSet(accessFlags)) {
// Constructors always have void return type.
returnTypeValue = "V"
} else {
return lookupMaps.allMethods
}
}
val signature =
buildString {
append(accessFlags)
append(returnTypeValue.first())
appendParameters(parameters ?: return@buildString)
}
return lookupMaps.methodsBySignature[signature] ?: return MethodClassPairs()
}
return match(lookupBySignature())
}
/**
@@ -107,7 +129,7 @@ class Fingerprint internal constructor(
fun match(
context: BytecodePatchContext,
method: Method,
) = match(context, method, context.classBy { method.definingClass == it.type }!!.immutableClass)
) = match(context, method, context.classByType(method.definingClass)!!.immutableClass)
/**
* Match using a [Method].

View File

@@ -39,6 +39,9 @@ class Patcher(private val config: PatcherConfig) : Closeable {
patch.addRecursively()
}
fun Patch<*>.anyRecursively(predicate: (Patch<*>) -> Boolean): Boolean =
predicate(this) || dependencies.any { dependency -> dependency.anyRecursively(predicate) }
context.allPatches.let { allPatches ->
// Check, if what kind of resource mode is required.
config.resourceMode = if (allPatches.any { patch -> patch.anyRecursively { it is ResourcePatch } }) {
@@ -96,15 +99,6 @@ class Patcher(private val config: PatcherConfig) : Closeable {
context.resourceContext.decodeResources(config.resourceMode)
}
logger.info("Merging extensions")
with(context.bytecodeContext) {
context.executablePatches.mergeExtensions()
// Initialize lookup maps.
lookupMaps
}
logger.info("Executing patches")
val executedPatches = LinkedHashMap<Patch<*>, PatchResult>()
@@ -152,7 +146,7 @@ class Patcher(private val config: PatcherConfig) : Closeable {
}
}
override fun close() = context.close()
override fun close() = context.bytecodeContext.lookupMaps.close()
/**
* Compile and save patched APK files.

View File

@@ -20,7 +20,6 @@ class PatcherConfig(
private val temporaryFilesPath: File = File("revanced-temporary-files"),
aaptBinaryPath: String? = null,
frameworkFileDirectory: String? = null,
@Deprecated("This is going to be removed in the future because it is not needed anymore.")
internal val multithreadingDexFileWriter: Boolean = false,
) {
private val logger = Logger.getLogger(PatcherConfig::class.java.name)

View File

@@ -5,7 +5,6 @@ import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.ResourcePatchContext
import brut.androlib.apk.ApkInfo
import brut.directory.ExtFile
import java.io.Closeable
/**
* A context for the patcher containing the current state of the patcher.
@@ -13,7 +12,7 @@ import java.io.Closeable
* @param config The configuration for the patcher.
*/
@Suppress("MemberVisibilityCanBePrivate")
class PatcherContext internal constructor(config: PatcherConfig): Closeable {
class PatcherContext internal constructor(config: PatcherConfig) {
/**
* [PackageMetadata] of the supplied [PatcherConfig.apkFile].
*/
@@ -38,6 +37,4 @@ class PatcherContext internal constructor(config: PatcherConfig): Closeable {
* The context for patches containing the current state of the bytecode.
*/
internal val bytecodeContext = BytecodePatchContext(config)
override fun close() = bytecodeContext.close()
}

View File

@@ -21,6 +21,7 @@ import lanchon.multidexlib2.MultiDexIO
import lanchon.multidexlib2.RawDexIO
import java.io.Closeable
import java.io.FileFilter
import java.io.InputStream
import java.util.*
import java.util.logging.Logger
@@ -30,9 +31,7 @@ import java.util.logging.Logger
* @param config The [PatcherConfig] used to create this context.
*/
@Suppress("MemberVisibilityCanBePrivate")
class BytecodePatchContext internal constructor(private val config: PatcherConfig) :
PatchContext<Set<PatcherResult.PatchedDexFile>>,
Closeable {
class BytecodePatchContext internal constructor(private val config: PatcherConfig) : PatchContext<Set<PatcherResult.PatchedDexFile>> {
private val logger = Logger.getLogger(BytecodePatchContext::class.java.name)
/**
@@ -59,41 +58,33 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
internal val lookupMaps by lazy { LookupMaps(classes) }
/**
* Merge the extensions for this set of patches.
* Merge an extension to [classes].
*
* @param extensionInputStream The input stream of the extension to merge.
*/
internal fun Set<Patch<*>>.mergeExtensions() {
// Lookup map for fast checking if a class exists by its type.
val classesByType = mutableMapOf<String, ClassDef>().apply {
classes.forEach { classDef -> put(classDef.type, classDef) }
}
internal fun merge(extensionInputStream: InputStream) {
val extension = extensionInputStream.readAllBytes()
forEachRecursively { patch ->
if (patch is BytecodePatch && patch.extension != null) {
RawDexIO.readRawDexFile(extension, 0, null).classes.forEach { classDef ->
val existingClass = lookupMaps.classesByType[classDef.type] ?: run {
logger.fine("Adding class \"$classDef\"")
val extension = patch.extension.readAllBytes()
lookupMaps.classesByType[classDef.type] = classDef
classes += classDef
RawDexIO.readRawDexFile(extension, 0, null).classes.forEach { classDef ->
val existingClass = classesByType[classDef.type] ?: run {
logger.fine("Adding class \"$classDef\"")
return@forEach
}
classes += classDef
classesByType[classDef.type] = classDef
logger.fine("Class \"$classDef\" exists already. Adding missing methods and fields.")
return@forEach
}
logger.fine("Class \"$classDef\" exists already. Adding missing methods and fields.")
existingClass.merge(classDef, this@BytecodePatchContext).let { mergedClass ->
// If the class was merged, replace the original class with the merged class.
if (mergedClass === existingClass) {
return@let
}
classes -= existingClass
classes += mergedClass
}
existingClass.merge(classDef, this@BytecodePatchContext).let { mergedClass ->
// If the class was merged, replace the original class with the merged class.
if (mergedClass === existingClass) {
return@let
}
classes -= existingClass
classes += mergedClass
}
}
}
@@ -104,7 +95,6 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
* @param type The type of the class.
* @return A proxy for the first class that matches the type.
*/
@Deprecated("Use classBy { type in it.type } instead.", ReplaceWith("classBy { type in it.type }"))
fun classByType(type: String) = classBy { type in it.type }
/**
@@ -145,9 +135,6 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
override fun get(): Set<PatcherResult.PatchedDexFile> {
logger.info("Compiling patched dex files")
// Free up memory before compiling the dex files.
lookupMaps.close()
val patchedDexFileResults =
config.patchedFiles.resolve("dex").also {
it.deleteRecursively() // Make sure the directory is empty.
@@ -181,6 +168,21 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
* @param classes The list of classes to create the lookup maps from.
*/
internal class LookupMaps internal constructor(classes: List<ClassDef>) : Closeable {
/**
* Classes associated by their type.
*/
internal val classesByType = classes.associateBy { it.type }.toMutableMap()
/**
* All methods and the class they are a member of.
*/
internal val allMethods = MethodClassPairs()
/**
* Methods associated by its access flags, return type and parameter.
*/
internal val methodsBySignature = MethodClassPairsLookupMap()
/**
* Methods associated by strings referenced in it.
*/
@@ -191,6 +193,22 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
classDef.methods.forEach { method ->
val methodClassPair: MethodClassPair = method to classDef
// For fingerprints with no access or return type specified.
allMethods += methodClassPair
val accessFlagsReturnKey = method.accessFlags.toString() + method.returnType.first()
// Add <access><returnType> as the key.
methodsBySignature[accessFlagsReturnKey] = methodClassPair
// Add <access><returnType>[parameters] as the key.
methodsBySignature[
buildString {
append(accessFlagsReturnKey)
appendParameters(method.parameterTypes)
},
] = methodClassPair
// Add strings contained in the method as the key.
method.instructionsOrNull?.forEach instructions@{ instruction ->
if (instruction.opcode != Opcode.CONST_STRING && instruction.opcode != Opcode.CONST_STRING_JUMBO) {
@@ -231,14 +249,11 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
}
override fun close() {
allMethods.clear()
methodsBySignature.clear()
methodsByStrings.clear()
}
}
override fun close() {
lookupMaps.close()
classes.clear()
}
}
/**

File diff suppressed because it is too large Load Diff

View File

@@ -48,9 +48,6 @@ sealed class Patch<C : PatchContext<*>>(
// if a patch has a finalizing block in order to not emit it twice.
internal var finalizeBlock: (Patch<C>.(C) -> Unit)?,
) {
/**
* The options of the patch.
*/
val options = Options(options)
/**
@@ -88,31 +85,6 @@ sealed class Patch<C : PatchContext<*>>(
override fun toString() = name ?: "Patch"
}
internal fun Patch<*>.anyRecursively(
visited: MutableSet<Patch<*>> = mutableSetOf(),
predicate: (Patch<*>) -> Boolean,
): Boolean {
if (this in visited) return false
if (predicate(this)) return true
visited += this
return dependencies.any { it.anyRecursively(visited, predicate) }
}
internal fun Iterable<Patch<*>>.forEachRecursively(
visited: MutableSet<Patch<*>> = mutableSetOf(),
action: (Patch<*>) -> Unit,
): Unit = forEach {
if (it in visited) return@forEach
visited += it
action(it)
it.dependencies.forEachRecursively(visited, action)
}
/**
* A bytecode patch.
*
@@ -155,6 +127,7 @@ class BytecodePatch internal constructor(
finalizeBlock,
) {
override fun execute(context: PatcherContext) = with(context.bytecodeContext) {
extension?.let(::merge)
fingerprints.forEach { it.match(this) }
execute(this)
@@ -295,14 +268,7 @@ sealed class PatchBuilder<C : PatchContext<*>>(
*
* @param versions The versions of the package.
*/
operator fun String.invoke(vararg versions: String) = invoke(versions.toSet())
/**
* Create a package a patch is compatible with.
*
* @param versions The versions of the package.
*/
private operator fun String.invoke(versions: Set<String>? = null) = this to versions
operator fun String.invoke(vararg versions: String) = this to versions.toSet()
/**
* Add packages the patch is compatible with.
@@ -359,16 +325,6 @@ sealed class PatchBuilder<C : PatchContext<*>>(
internal abstract fun build(): Patch<C>
}
/**
* Builds a [Patch].
*
* @param B The [PatchBuilder] to build the patch with.
* @param block The block to build the patch.
*
* @return The built [Patch].
*/
private fun <B : PatchBuilder<*>> B.buildPatch(block: B.() -> Unit = {}) = apply(block).build()
/**
* A [BytecodePatchBuilder] builder.
*
@@ -396,13 +352,13 @@ class BytecodePatchBuilder internal constructor(
*/
operator fun Fingerprint.invoke() = InvokedFingerprint(also { fingerprints.add(it) })
class InvokedFingerprint internal constructor(private val fingerprint: Fingerprint) {
class InvokedFingerprint(private val fingerprint: Fingerprint) {
// The reason getValue isn't extending the Fingerprint class is
// because delegating makes only sense if the fingerprint was previously added to the patch by invoking it.
// It may be likely to forget invoking it. By wrapping the fingerprint into this class,
// the compiler will throw an error if the fingerprint was not invoked if attempting to delegate the match.
operator fun getValue(nothing: Nothing?, property: KProperty<*>) = fingerprint.match
?: throw PatchException("No fingerprint match to delegate to \"${property.name}\".")
?: throw PatchException("No fingerprint match to delegate to ${property.name}.")
}
// Must be internal for the inlined function "extendWith".
@@ -416,10 +372,9 @@ class BytecodePatchBuilder internal constructor(
*
* @param extension The name of the extension resource.
*/
@Suppress("NOTHING_TO_INLINE")
inline fun extendWith(extension: String) = apply {
this.extension = object {}.javaClass.classLoader.getResourceAsStream(extension)
?: throw PatchException("Extension \"$extension\" not found")
?: throw PatchException("Extension resource \"$extension\" not found")
}
override fun build() = BytecodePatch(
@@ -436,24 +391,6 @@ class BytecodePatchBuilder internal constructor(
)
}
/**
* Create a new [BytecodePatch].
*
* @param name The name of the patch.
* If null, the patch is named "Patch" and will not be loaded by [PatchLoader].
* @param description The description of the patch.
* @param use Weather or not the patch should be used.
* @param block The block to build the patch.
*
* @return The created [BytecodePatch].
*/
fun bytecodePatch(
name: String? = null,
description: String? = null,
use: Boolean = true,
block: BytecodePatchBuilder.() -> Unit = {},
) = BytecodePatchBuilder(name, description, use).buildPatch(block) as BytecodePatch
/**
* A [RawResourcePatch] builder.
*
@@ -481,23 +418,6 @@ class RawResourcePatchBuilder internal constructor(
)
}
/**
* Create a new [RawResourcePatch].
*
* @param name The name of the patch.
* If null, the patch is named "Patch" and will not be loaded by [PatchLoader].
* @param description The description of the patch.
* @param use Weather or not the patch should be used.
* @param block The block to build the patch.
* @return The created [RawResourcePatch].
*/
fun rawResourcePatch(
name: String? = null,
description: String? = null,
use: Boolean = true,
block: RawResourcePatchBuilder.() -> Unit = {},
) = RawResourcePatchBuilder(name, description, use).buildPatch(block) as RawResourcePatch
/**
* A [ResourcePatch] builder.
*
@@ -525,6 +445,51 @@ class ResourcePatchBuilder internal constructor(
)
}
/**
* Builds a [Patch].
*
* @param B The [PatchBuilder] to build the patch with.
* @param block The block to build the patch.
*
* @return The built [Patch].
*/
private fun <B : PatchBuilder<*>> B.buildPatch(block: B.() -> Unit = {}) = apply(block).build()
/**
* Create a new [BytecodePatch].
*
* @param name The name of the patch.
* If null, the patch is named "Patch" and will not be loaded by [PatchLoader].
* @param description The description of the patch.
* @param use Weather or not the patch should be used.
* @param block The block to build the patch.
*
* @return The created [BytecodePatch].
*/
fun bytecodePatch(
name: String? = null,
description: String? = null,
use: Boolean = true,
block: BytecodePatchBuilder.() -> Unit = {},
) = BytecodePatchBuilder(name, description, use).buildPatch(block) as BytecodePatch
/**
* Create a new [RawResourcePatch].
*
* @param name The name of the patch.
* If null, the patch is named "Patch" and will not be loaded by [PatchLoader].
* @param description The description of the patch.
* @param use Weather or not the patch should be used.
* @param block The block to build the patch.
* @return The created [RawResourcePatch].
*/
fun rawResourcePatch(
name: String? = null,
description: String? = null,
use: Boolean = true,
block: RawResourcePatchBuilder.() -> Unit = {},
) = RawResourcePatchBuilder(name, description, use).buildPatch(block) as RawResourcePatch
/**
* Create a new [ResourcePatch].
*

View File

@@ -179,9 +179,7 @@ internal object ClassMerger {
callback: MutableClass.() -> Unit,
) {
callback(targetClass)
targetClass.superclass ?: return
this.classBy { targetClass.superclass == it.type }?.mutableClass?.let {
this.classByType(targetClass.superclass ?: return)?.mutableClass?.let {
traverseClassHierarchy(it, callback)
}
}

View File

@@ -9,13 +9,21 @@ class MutableAnnotation(annotation: Annotation) : BaseAnnotation() {
private val type = annotation.type
private val _elements by lazy { annotation.elements.map { element -> element.toMutable() }.toMutableSet() }
override fun getType(): String = type
override fun getType(): String {
return type
}
override fun getElements(): MutableSet<MutableAnnotationElement> = _elements
override fun getElements(): MutableSet<MutableAnnotationElement> {
return _elements
}
override fun getVisibility(): Int = visibility
override fun getVisibility(): Int {
return visibility
}
companion object {
fun Annotation.toMutable(): MutableAnnotation = MutableAnnotation(this)
fun Annotation.toMutable(): MutableAnnotation {
return MutableAnnotation(this)
}
}
}

View File

@@ -18,11 +18,17 @@ class MutableAnnotationElement(annotationElement: AnnotationElement) : BaseAnnot
this.value = value
}
override fun getName(): String = name
override fun getName(): String {
return name
}
override fun getValue(): EncodedValue = value
override fun getValue(): EncodedValue {
return value
}
companion object {
fun AnnotationElement.toMutable(): MutableAnnotationElement = MutableAnnotationElement(this)
fun AnnotationElement.toMutable(): MutableAnnotationElement {
return MutableAnnotationElement(this)
}
}
}

View File

@@ -7,10 +7,9 @@ import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference
import com.android.tools.smali.dexlib2.iface.ClassDef
import com.android.tools.smali.dexlib2.util.FieldUtil
import com.android.tools.smali.dexlib2.util.MethodUtil
import com.google.common.collect.Iterables
class MutableClass(classDef: ClassDef) :
BaseTypeReference(),
ClassDef {
class MutableClass(classDef: ClassDef) : ClassDef, BaseTypeReference() {
// Class
private var type = classDef.type
private var sourceFile = classDef.sourceFile
@@ -24,13 +23,13 @@ class MutableClass(classDef: ClassDef) :
// Methods
private val _methods by lazy { classDef.methods.map { method -> method.toMutable() }.toMutableSet() }
private val _directMethods by lazy { _methods.filter { method -> MethodUtil.isDirect(method) }.toMutableSet() }
private val _virtualMethods by lazy { _methods.filter { method -> !MethodUtil.isDirect(method) }.toMutableSet() }
private val _directMethods by lazy { Iterables.filter(_methods, MethodUtil.METHOD_IS_DIRECT).toMutableSet() }
private val _virtualMethods by lazy { Iterables.filter(_methods, MethodUtil.METHOD_IS_VIRTUAL).toMutableSet() }
// Fields
private val _fields by lazy { classDef.fields.map { field -> field.toMutable() }.toMutableSet() }
private val _staticFields by lazy { _fields.filter { field -> FieldUtil.isStatic(field) }.toMutableSet() }
private val _instanceFields by lazy { _fields.filter { field -> !FieldUtil.isStatic(field) }.toMutableSet() }
private val _staticFields by lazy { Iterables.filter(_fields, FieldUtil.FIELD_IS_STATIC).toMutableSet() }
private val _instanceFields by lazy { Iterables.filter(_fields, FieldUtil.FIELD_IS_INSTANCE).toMutableSet() }
fun setType(type: String) {
this.type = type
@@ -48,31 +47,57 @@ class MutableClass(classDef: ClassDef) :
this.superclass = superclass
}
override fun getType(): String = type
override fun getType(): String {
return type
}
override fun getAccessFlags(): Int = accessFlags
override fun getAccessFlags(): Int {
return accessFlags
}
override fun getSourceFile(): String? = sourceFile
override fun getSourceFile(): String? {
return sourceFile
}
override fun getSuperclass(): String? = superclass
override fun getSuperclass(): String? {
return superclass
}
override fun getInterfaces(): MutableList<String> = _interfaces
override fun getInterfaces(): MutableList<String> {
return _interfaces
}
override fun getAnnotations(): MutableSet<MutableAnnotation> = _annotations
override fun getAnnotations(): MutableSet<MutableAnnotation> {
return _annotations
}
override fun getStaticFields(): MutableSet<MutableField> = _staticFields
override fun getStaticFields(): MutableSet<MutableField> {
return _staticFields
}
override fun getInstanceFields(): MutableSet<MutableField> = _instanceFields
override fun getInstanceFields(): MutableSet<MutableField> {
return _instanceFields
}
override fun getFields(): MutableSet<MutableField> = _fields
override fun getFields(): MutableSet<MutableField> {
return _fields
}
override fun getDirectMethods(): MutableSet<MutableMethod> = _directMethods
override fun getDirectMethods(): MutableSet<MutableMethod> {
return _directMethods
}
override fun getVirtualMethods(): MutableSet<MutableMethod> = _virtualMethods
override fun getVirtualMethods(): MutableSet<MutableMethod> {
return _virtualMethods
}
override fun getMethods(): MutableSet<MutableMethod> = _methods
override fun getMethods(): MutableSet<MutableMethod> {
return _methods
}
companion object {
fun ClassDef.toMutable(): MutableClass = MutableClass(this)
fun ClassDef.toMutable(): MutableClass {
return MutableClass(this)
}
}
}

View File

@@ -7,9 +7,7 @@ import com.android.tools.smali.dexlib2.HiddenApiRestriction
import com.android.tools.smali.dexlib2.base.reference.BaseFieldReference
import com.android.tools.smali.dexlib2.iface.Field
class MutableField(field: Field) :
BaseFieldReference(),
Field {
class MutableField(field: Field) : Field, BaseFieldReference() {
private var definingClass = field.definingClass
private var name = field.name
private var type = field.type
@@ -39,21 +37,37 @@ class MutableField(field: Field) :
this.initialValue = initialValue
}
override fun getDefiningClass(): String = this.definingClass
override fun getDefiningClass(): String {
return this.definingClass
}
override fun getName(): String = this.name
override fun getName(): String {
return this.name
}
override fun getType(): String = this.type
override fun getType(): String {
return this.type
}
override fun getAnnotations(): MutableSet<MutableAnnotation> = this._annotations
override fun getAnnotations(): MutableSet<MutableAnnotation> {
return this._annotations
}
override fun getAccessFlags(): Int = this.accessFlags
override fun getAccessFlags(): Int {
return this.accessFlags
}
override fun getHiddenApiRestrictions(): MutableSet<HiddenApiRestriction> = this._hiddenApiRestrictions
override fun getHiddenApiRestrictions(): MutableSet<HiddenApiRestriction> {
return this._hiddenApiRestrictions
}
override fun getInitialValue(): MutableEncodedValue? = this.initialValue
override fun getInitialValue(): MutableEncodedValue? {
return this.initialValue
}
companion object {
fun Field.toMutable(): MutableField = MutableField(this)
fun Field.toMutable(): MutableField {
return MutableField(this)
}
}
}

View File

@@ -7,9 +7,7 @@ import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.Method
class MutableMethod(method: Method) :
BaseMethodReference(),
Method {
class MutableMethod(method: Method) : Method, BaseMethodReference() {
private var definingClass = method.definingClass
private var name = method.name
private var accessFlags = method.accessFlags
@@ -38,25 +36,45 @@ class MutableMethod(method: Method) :
this.returnType = returnType
}
override fun getDefiningClass(): String = definingClass
override fun getDefiningClass(): String {
return definingClass
}
override fun getName(): String = name
override fun getName(): String {
return name
}
override fun getParameterTypes(): MutableList<CharSequence> = _parameterTypes
override fun getParameterTypes(): MutableList<CharSequence> {
return _parameterTypes
}
override fun getReturnType(): String = returnType
override fun getReturnType(): String {
return returnType
}
override fun getAnnotations(): MutableSet<MutableAnnotation> = _annotations
override fun getAnnotations(): MutableSet<MutableAnnotation> {
return _annotations
}
override fun getAccessFlags(): Int = accessFlags
override fun getAccessFlags(): Int {
return accessFlags
}
override fun getHiddenApiRestrictions(): MutableSet<HiddenApiRestriction> = _hiddenApiRestrictions
override fun getHiddenApiRestrictions(): MutableSet<HiddenApiRestriction> {
return _hiddenApiRestrictions
}
override fun getParameters(): MutableList<MutableMethodParameter> = _parameters
override fun getParameters(): MutableList<MutableMethodParameter> {
return _parameters
}
override fun getImplementation(): MutableMethodImplementation? = _implementation
override fun getImplementation(): MutableMethodImplementation? {
return _implementation
}
companion object {
fun Method.toMutable(): MutableMethod = MutableMethod(this)
fun Method.toMutable(): MutableMethod {
return MutableMethod(this)
}
}
}

View File

@@ -5,9 +5,7 @@ import com.android.tools.smali.dexlib2.base.BaseMethodParameter
import com.android.tools.smali.dexlib2.iface.MethodParameter
// TODO: finish overriding all members if necessary
class MutableMethodParameter(parameter: MethodParameter) :
BaseMethodParameter(),
MethodParameter {
class MutableMethodParameter(parameter: MethodParameter) : MethodParameter, BaseMethodParameter() {
private var type = parameter.type
private var name = parameter.name
private var signature = parameter.signature
@@ -15,15 +13,25 @@ class MutableMethodParameter(parameter: MethodParameter) :
parameter.annotations.map { annotation -> annotation.toMutable() }.toMutableSet()
}
override fun getType(): String = type
override fun getType(): String {
return type
}
override fun getName(): String? = name
override fun getName(): String? {
return name
}
override fun getSignature(): String? = signature
override fun getSignature(): String? {
return signature
}
override fun getAnnotations(): MutableSet<MutableAnnotation> = _annotations
override fun getAnnotations(): MutableSet<MutableAnnotation> {
return _annotations
}
companion object {
fun MethodParameter.toMutable(): MutableMethodParameter = MutableMethodParameter(this)
fun MethodParameter.toMutable(): MutableMethodParameter {
return MutableMethodParameter(this)
}
}
}

View File

@@ -14,15 +14,21 @@ class MutableAnnotationEncodedValue(annotationEncodedValue: AnnotationEncodedVal
annotationEncodedValue.elements.map { annotationElement -> annotationElement.toMutable() }.toMutableSet()
}
override fun getType(): String = this.type
override fun getType(): String {
return this.type
}
fun setType(type: String) {
this.type = type
}
override fun getElements(): MutableSet<out AnnotationElement> = _elements
override fun getElements(): MutableSet<out AnnotationElement> {
return _elements
}
companion object {
fun AnnotationEncodedValue.toMutable(): MutableAnnotationEncodedValue = MutableAnnotationEncodedValue(this)
fun AnnotationEncodedValue.toMutable(): MutableAnnotationEncodedValue {
return MutableAnnotationEncodedValue(this)
}
}
}

View File

@@ -5,16 +5,18 @@ import com.android.tools.smali.dexlib2.base.value.BaseArrayEncodedValue
import com.android.tools.smali.dexlib2.iface.value.ArrayEncodedValue
import com.android.tools.smali.dexlib2.iface.value.EncodedValue
class MutableArrayEncodedValue(arrayEncodedValue: ArrayEncodedValue) :
BaseArrayEncodedValue(),
MutableEncodedValue {
class MutableArrayEncodedValue(arrayEncodedValue: ArrayEncodedValue) : BaseArrayEncodedValue(), MutableEncodedValue {
private val _value by lazy {
arrayEncodedValue.value.map { encodedValue -> encodedValue.toMutable() }.toMutableList()
}
override fun getValue(): MutableList<out EncodedValue> = _value
override fun getValue(): MutableList<out EncodedValue> {
return _value
}
companion object {
fun ArrayEncodedValue.toMutable(): MutableArrayEncodedValue = MutableArrayEncodedValue(this)
fun ArrayEncodedValue.toMutable(): MutableArrayEncodedValue {
return MutableArrayEncodedValue(this)
}
}
}

View File

@@ -8,13 +8,17 @@ class MutableBooleanEncodedValue(booleanEncodedValue: BooleanEncodedValue) :
MutableEncodedValue {
private var value = booleanEncodedValue.value
override fun getValue(): Boolean = this.value
override fun getValue(): Boolean {
return this.value
}
fun setValue(value: Boolean) {
this.value = value
}
companion object {
fun BooleanEncodedValue.toMutable(): MutableBooleanEncodedValue = MutableBooleanEncodedValue(this)
fun BooleanEncodedValue.toMutable(): MutableBooleanEncodedValue {
return MutableBooleanEncodedValue(this)
}
}
}

Some files were not shown because too many files have changed in this diff Show More