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
17package com.android.internal.telephony;
18
19import android.telephony.SmsCbMessage;
20import android.util.Log;
21
22import com.android.internal.telephony.cdma.SmsMessage;
23
24import java.lang.reflect.Constructor;
25import java.lang.reflect.InvocationTargetException;
26import java.lang.reflect.Method;
27import 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 */
33public 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     */
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     */
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     */
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     */
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     */
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
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
164    private static void logd(String s) {
165        Log.d(TAG, s);
166    }
167}
168