1/*
2 * Copyright (C) 2017 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
17package art;
18
19import java.util.ArrayList;
20// Common Redefinition functions. Placed here for use by CTS
21public class Redefinition {
22  public static final class CommonClassDefinition {
23    public final Class<?> target;
24    public final byte[] class_file_bytes;
25    public final byte[] dex_file_bytes;
26
27    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
28      this.target = target;
29      this.class_file_bytes = class_file_bytes;
30      this.dex_file_bytes = dex_file_bytes;
31    }
32  }
33
34  // A set of possible test configurations. Test should set this if they need to.
35  // This must be kept in sync with the defines in ti-agent/common_helper.cc
36  public static enum Config {
37    COMMON_REDEFINE(0),
38    COMMON_RETRANSFORM(1),
39    COMMON_TRANSFORM(2);
40
41    private final int val;
42    private Config(int val) {
43      this.val = val;
44    }
45  }
46
47  public static void setTestConfiguration(Config type) {
48    nativeSetTestConfiguration(type.val);
49  }
50
51  private static native void nativeSetTestConfiguration(int type);
52
53  // Transforms the class
54  public static native void doCommonClassRedefinition(Class<?> target,
55                                                      byte[] classfile,
56                                                      byte[] dexfile);
57
58  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
59    ArrayList<Class<?>> classes = new ArrayList<>();
60    ArrayList<byte[]> class_files = new ArrayList<>();
61    ArrayList<byte[]> dex_files = new ArrayList<>();
62
63    for (CommonClassDefinition d : defs) {
64      classes.add(d.target);
65      class_files.add(d.class_file_bytes);
66      dex_files.add(d.dex_file_bytes);
67    }
68    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
69                                   class_files.toArray(new byte[0][]),
70                                   dex_files.toArray(new byte[0][]));
71  }
72
73  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
74    for (CommonClassDefinition d : defs) {
75      addCommonTransformationResult(d.target.getCanonicalName(),
76                                    d.class_file_bytes,
77                                    d.dex_file_bytes);
78    }
79  }
80
81  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
82                                                           byte[][] classfiles,
83                                                           byte[][] dexfiles);
84  public static native void doCommonClassRetransformation(Class<?>... target);
85  public static native void setPopRetransformations(boolean pop);
86  public static native void popTransformationFor(String name);
87  public static native void enableCommonRetransformation(boolean enable);
88  public static native void addCommonTransformationResult(String target_name,
89                                                          byte[] class_bytes,
90                                                          byte[] dex_bytes);
91}
92