/ Android-Bytecode.md
Android-Bytecode.md
1 We use ASM to rewrite Java bytecode in `jar` files during the build process, which usually happens after java compilation of the specific `jar` file and before the final assembly of `apk` file. Through bytecode rewrite, we can rewrite/redirect classes, methods, etc. without patching or manually overriding every occurance of them. 2 3 # How to use 4 5 In order to use bytecode rewrite, you need to take the following steps: 6 7 1. Start by making a file and a class named `{***}ClassAdapter` under `build/android/bytecode/java/org/brave/bytecode`. The folder has a lot of examples of how the class shall be like. The most important part is it shall `extends BraveClassVisitor` and all redirections/rewrites happen in its constructor. 8 2. Go to `build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java` and add your newly created class to the chain of invocation of the adapters. 9 3. Go to `build/android/bytecode/BUILD.gn` and add your newly created `java` file to `sources`. 10 4. If you are redirecting/rewriting any exisitng classes, methods or fields from upstream, you shall add tests for their existence in `android/javatests/org/chromium/chrome/browser/BytecodeTest.java`. In addition, if you are redirecting a class, also add tests for consturctors and supers. 11 5. If you are redirecting an existing method, add that method to `android/java/proguard.flags` following the examples of exising entries. The `***` and `...` part means the rule will match any method signature regardless of what types and how many parameters there are. 12 6. Check any references to the classes/methods/fields you want to rewrite is compiled to one of the `jar` files listed in `build/android/bytecode/bytecode_rewriter.gni`. If not, then add the output `jar` file to the list. The easiest way to find out which jar file is search for the name of the source `java` file you are trying to rewrite in `gn/gni` files and find the `android_library` target which compiles the file. The `jar` file shall be the one with the same target name under `obj/{path to the gn file you are looking at}`. 13 14 # Supported redirection/rewrite 15 16 - `changeSuperName(String className, String superName)`: change super of `className` to `superName`. 17 18 - `deleteMethod(String className, String methodName)`: delete `methodName` from `className`. 19 20 - `makePublicMethod(String className, String methodName)`: change the visibility of `methodName` in `className` to `public`. 21 22 - `makePrivateMethod(String className, String methodName)`: change the visibility of `methodName` in `className` to `private`. 23 24 - `changeMethodOwner(String currentOwner, String methodName, String newOwner)`: change any **invocation** of `methodName` from being from class `currentOwner` to class `newOwner`. This _does not_ change method definition. 25 26 - `deleteField(String className, String fieldName)`: delete `fieldName` from `className`. 27 28 - `deleteInnerClass(String outerName, String innerName)`: delete and inner class `innerName` from class `outerName`. 29 30 - `makeNonFinalClass(String className)`: remove keywork `final` from the definition of `className`. 31 32 - `makePublicInnerClass(String outerName, String innerName)`: make the visibility of inner class `innerName` inside `outerName` to be `public`. 33 34 - `makeProtectedField(String className, String fieldName)`: change the visibility of `fieldName` in `className` to `protected`. 35 36 - `addMethodAnnotation(String className, String methodName, String annotationType)`: add annotation `annotationType` (e.g. `Override`) to the definition of `methodName`. 37 38 - `redirectConstructor(String originalClassName, String newClassName)`: redirect any invocation of constructor `originalClassName` (i.e. `new originalClassName()`) to a new constructor `newClassName`. 39 40 - `redirectTypeInMethod(String className, String methodName, String originalTypeName, String newTypeName)`: change any mention of type in definition of `methodName` in `className` from `originalTypeName` to `newTypeName`. This includes method signature, body and return type.