blob: 98e723670d8c7da4b464319b9ed0f07056e6f18b [file] [log] [blame]
Alex Light5c11a792017-03-10 14:29:22 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import java.util.Base64;
18import java.util.concurrent.Semaphore;
19
20public class Main {
21 // class Transform {
22 // public void sayHi(Runnable r) {
23 // System.out.println("Hello - Transformed");
24 // r.run();
25 // System.out.println("Goodbye - Transformed");
26 // }
27 // }
28 private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
29 "yv66vgAAADQAJAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW" +
30 "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
31 "KVYBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkACgcAHAwAHQAeAQATSGVsbG8gLSBU" +
32 "cmFuc2Zvcm1lZAcAHwwAIAAhBwAiDAAjAAoBABVHb29kYnllIC0gVHJhbnNmb3JtZWQBAAlUcmFu" +
33 "c2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZh" +
34 "L2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZh" +
35 "L2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuACAABwAIAAAAAAACAAAA" +
36 "CQAKAAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAAAQABAA0ADgABAAsAAAA7AAIA" +
37 "AgAAABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAMACAAEAA4ABQAWAAYA" +
38 "AQAPAAAAAgAQ");
39 private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
40 "ZGV4CjAzNQAYeAMMXgYWxoeSHAS9EWKCCtVRSAGpqZVQAwAAcAAAAHhWNBIAAAAAAAAAALACAAAR" +
41 "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAMAgAARAEAAKIB" +
42 "AACqAQAAwQEAANYBAADjAQAA+gEAAA4CAAAkAgAAOAIAAEwCAABcAgAAXwIAAGMCAAB3AgAAfAIA" +
43 "AIUCAACKAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" +
44 "lAEAAAsAAAAGAAAAnAEAAAUAAQANAAAAAAAAAAAAAAAAAAEAEAAAAAEAAgAOAAAAAgAAAAAAAAAD" +
45 "AAAADwAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAJ8CAAAAAAAAAQABAAEAAACRAgAABAAAAHAQ" +
46 "AwAAAA4ABAACAAIAAACWAgAAFAAAAGIAAAAbAQIAAABuIAIAEAByEAQAAwBiAAAAGwEBAAAAbiAC" +
47 "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AFUdvb2RieWUgLSBUcmFuc2Zvcm1lZAATSGVsbG8g" +
48 "LSBUcmFuc2Zvcm1lZAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEv" +
49 "bGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJM" +
50 "amF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00" +
51 "LjEzAANvdXQAB3ByaW50bG4AA3J1bgAFc2F5SGkAAQAHDgADAQAHDoc8hwAAAAEBAICABMQCAQHc" +
52 "AgAAAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAACAAAABwAAALQAAAADAAAAAwAAANAAAAAE" +
53 "AAAAAQAAAPQAAAAFAAAABQAAAPwAAAAGAAAAAQAAACQBAAABIAAAAgAAAEQBAAABEAAAAgAAAJQB" +
54 "AAACIAAAEQAAAKIBAAADIAAAAgAAAJECAAAAIAAAAQAAAJ8CAAAAEAAAAQAAALACAAA=");
55
56 public static void main(String[] args) {
57 // Semaphores to let each thread know where the other is. We could use barriers but semaphores
58 // mean we don't need to have the worker thread be waiting around.
59 final Semaphore sem_redefine_start = new Semaphore(0);
60 final Semaphore sem_redefine_end = new Semaphore(0);
61 // Create a thread to do the actual redefinition. We will just communicate through an
62 // atomic-integer.
63 new Thread(() -> {
64 try {
65 // Wait for the other thread to ask for redefinition.
66 sem_redefine_start.acquire();
67 // Do the redefinition.
68 doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
69 // Allow the other thread to wake up if it is waiting.
70 sem_redefine_end.release();
71 } catch (InterruptedException e) {
72 throw new Error("unable to do redefinition", e);
73 }
74 }).start();
75
76 Transform t = new Transform();
77 t.sayHi(() -> { System.out.println("Not doing anything here"); });
78 t.sayHi(() -> {
79 try {
80 System.out.println("transforming calling function");
81 // Wake up the waiting thread.
82 sem_redefine_start.release();
83 // Wait for the other thread to finish with redefinition.
84 sem_redefine_end.acquire();
85 } catch (InterruptedException e) {
86 throw new Error("unable to do redefinition", e);
87 }
88 });
89 t.sayHi(() -> { System.out.println("Not doing anything here"); });
90 }
91
92 // Transforms the class
93 private static native void doCommonClassRedefinition(Class<?> target,
94 byte[] classfile,
95 byte[] dexfile);
96}