1 /*
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 
17 package com.android.internal.telephony;
18 
19 import android.telephony.SmsCbMessage;
20 import android.util.Log;
21 
22 import com.android.internal.telephony.cdma.SmsMessage;
23 
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import junit.framework.Assert;
28 
29 /**
30  * This class provides reflection for classes/methods that are not accessible from tests.
31  * Convention for helper function naming is: classNameFunctionName()
32  */
33 public class TelephonyTestUtils {
34     private static final String TAG = "TelephonyTestUtils";
35 
36     /**
37      * This function calls constructor that takes in params.
38      * This function does not work if any of the parameter passed in is null because
39      * params[i].getClass() fails. In that case it needs to be handled by the caller (it knows the
40      * param types so getClass() is not needed)
41      */
createNewInstance(String className, Object... params)42     public static Object createNewInstance(String className, Object... params) {
43         try {
44             Class clazz = Class.forName(className);
45             int numParam = params.length;
46             Class<?>[] paramType = new Class[numParam];
47             for (int i = 0; i < numParam; i++) {
48                 paramType[i] = params[i].getClass();
49             }
50             Constructor constructor = clazz.getDeclaredConstructor(paramType);
51             constructor.setAccessible(true);
52 
53             return constructor.newInstance(params);
54         } catch (Exception e) {
55             Assert.fail(e.toString());
56             return null;
57         }
58     }
59 
60     /**
61      * This function does not work if any of the parameter passed in is null because
62      * params[i].getClass() fails. In that case it needs to be handled by the caller (it knows the
63      * param types so getClass() is not needed)
64      */
invokeStaticMethod(Class<?> clazz, String method, Object... params)65     public static Object invokeStaticMethod(Class<?> clazz, String method, Object... params) {
66         try {
67             int numParam = params.length;
68             Class<?>[] paramType = new Class[numParam];
69             for (int i = 0; i < numParam; i++) {
70                 paramType[i] = params[i].getClass();
71             }
72             Method methodReflection = clazz.getDeclaredMethod(method, paramType);
73             methodReflection.setAccessible(true);
74             return methodReflection.invoke(null, params);
75         } catch (Exception e) {
76             Assert.fail(e.toString());
77             return null;
78         }
79     }
80 
81     /**
82      * This is needed when the test expects the method in source being called to throw an exception.
83      * Throwable will be an instanceof the expected exception.
84      * This function does not work if any of the parameter passed in is null because
85      * params[i].getClass() fails. In that case it needs to be handled by the caller (it knows the
86      * param types so getClass() is not needed)
87      */
invokeStaticMethodThrowsException(Class<?> clazz, String method, Object... params)88     public static Object invokeStaticMethodThrowsException(Class<?> clazz, String method,
89                                                            Object... params) throws Throwable {
90         try {
91             int numParam = params.length;
92             Class<?>[] paramType = new Class[numParam];
93             for (int i = 0; i < numParam; i++) {
94                 paramType[i] = params[i].getClass();
95             }
96             Method methodReflection = clazz.getDeclaredMethod(method, paramType);
97             methodReflection.setAccessible(true);
98             return methodReflection.invoke(null, params);
99         } catch (InvocationTargetException e) {
100             throw e.getTargetException();
101         } catch (Exception e) {
102             Assert.fail(e.toString());
103             return null;
104         }
105     }
106 
107     /**
108      * This function does not work if any of the parameter passed in is null because
109      * params[i].getClass() fails. In that case it needs to be handled by the caller (it knows the
110      * param types so getClass() is not needed)
111      */
invokeNonStaticMethod(Class<?> clazz, Object caller, String method, Object... params)112     public static Object invokeNonStaticMethod(Class<?> clazz, Object caller, String method,
113                                                Object... params) {
114         try {
115             int numParam = params.length;
116             Class<?>[] paramType = new Class[numParam];
117             for (int i = 0; i < numParam; i++) {
118                 paramType[i] = params[i].getClass();
119             }
120             Method methodReflection = clazz.getDeclaredMethod(method, paramType);
121             methodReflection.setAccessible(true);
122             return methodReflection.invoke(caller, params);
123         } catch (Exception e) {
124             Assert.fail(e.toString());
125             return null;
126         }
127     }
128 
129     /**
130      * This is needed when the test expects the method in source being called to throw an exception.
131      * Throwable will be an instanceof the expected exception.
132      * This function does not work if any of the parameter passed in is null because
133      * params[i].getClass() fails. In that case it needs to be handled by the caller (it knows the
134      * param types so getClass() is not needed)
135      */
invokeNonStaticMethodThrowsException(Class<?> clazz, Object caller, String method, Object... params)136     public static Object invokeNonStaticMethodThrowsException(Class<?> clazz, Object caller,
137                                                               String method, Object... params)
138             throws Throwable {
139         try {
140             int numParam = params.length;
141             Class<?>[] paramType = new Class[numParam];
142             for (int i = 0; i < numParam; i++) {
143                 paramType[i] = params[i].getClass();
144             }
145             Method methodReflection = clazz.getDeclaredMethod(method, paramType);
146             methodReflection.setAccessible(true);
147             return methodReflection.invoke(caller, params);
148         } catch (InvocationTargetException e) {
149             throw e.getTargetException();
150         } catch (Exception e) {
151             Assert.fail(e.toString());
152             return null;
153         }
154     }
155 
waitForMs(long ms)156     public static void waitForMs(long ms) {
157         try {
158             Thread.sleep(ms);
159         } catch (InterruptedException e) {
160             logd("InterruptedException while waiting: " + e);
161         }
162     }
163 
logd(String s)164     private static void logd(String s) {
165         Log.d(TAG, s);
166     }
167 }
168