• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 
17 package android.os.instrumentation;
18 
19 import android.annotation.NonNull;
20 
21 import java.lang.reflect.Executable;
22 
23 /**
24  * A utility class for dynamic instrumentation / uprobestats.
25  *
26  * @hide
27  */
28 public final class MethodDescriptorParser {
29 
30     /**
31      * Parses a {@link MethodDescriptor} (in string representation) into a {@link Executable}.
32      */
parseMethodDescriptor(ClassLoader classLoader, @NonNull MethodDescriptor descriptor)33     public static Executable parseMethodDescriptor(ClassLoader classLoader,
34             @NonNull MethodDescriptor descriptor) {
35         try {
36             Class<?> javaClass = classLoader.loadClass(descriptor.fullyQualifiedClassName);
37             Class<?>[] parameters = new Class[descriptor.fullyQualifiedParameters.length];
38             for (int i = 0; i < descriptor.fullyQualifiedParameters.length; i++) {
39                 String typeName = descriptor.fullyQualifiedParameters[i];
40                 boolean isArrayType = typeName.endsWith("[]");
41                 if (isArrayType) {
42                     typeName = typeName.substring(0, typeName.length() - 2);
43                 }
44                 switch (typeName) {
45                     case "boolean":
46                         parameters[i] = isArrayType ? boolean.class.arrayType() : boolean.class;
47                         break;
48                     case "byte":
49                         parameters[i] = isArrayType ? byte.class.arrayType() : byte.class;
50                         break;
51                     case "char":
52                         parameters[i] = isArrayType ? char.class.arrayType() : char.class;
53                         break;
54                     case "short":
55                         parameters[i] = isArrayType ? short.class.arrayType() : short.class;
56                         break;
57                     case "int":
58                         parameters[i] = isArrayType ? int.class.arrayType() : int.class;
59                         break;
60                     case "long":
61                         parameters[i] = isArrayType ? long.class.arrayType() : long.class;
62                         break;
63                     case "float":
64                         parameters[i] = isArrayType ? float.class.arrayType() : float.class;
65                         break;
66                     case "double":
67                         parameters[i] = isArrayType ? double.class.arrayType() : double.class;
68                         break;
69                     default:
70                         parameters[i] = isArrayType ? classLoader.loadClass(typeName).arrayType()
71                                 : classLoader.loadClass(typeName);
72                 }
73             }
74 
75             if (com.android.art.flags.Flags.executableMethodFileOffsetsV2()
76                     && descriptor.methodName.equals("<init>")) {
77                 return javaClass.getDeclaredConstructor(parameters);
78             }
79             return javaClass.getDeclaredMethod(descriptor.methodName, parameters);
80         } catch (ClassNotFoundException | NoSuchMethodException e) {
81             throw new IllegalArgumentException(
82                     "The specified method cannot be found. Is this descriptor valid? "
83                             + descriptor, e);
84         }
85     }
86 }
87