summaryrefslogtreecommitdiff
path: root/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java
diff options
context:
space:
mode:
Diffstat (limited to 'InCallUI/tests/src/com/android/incallui/TestTelecomCall.java')
-rw-r--r--InCallUI/tests/src/com/android/incallui/TestTelecomCall.java161
1 files changed, 161 insertions, 0 deletions
diff --git a/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java b/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java
new file mode 100644
index 000000000..48ac6e18f
--- /dev/null
+++ b/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.incallui;
+
+import com.google.common.base.Preconditions;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.telecom.DisconnectCause;
+import android.telecom.GatewayInfo;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.StatusHints;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Wrapper class which uses reflection to create instances of {@link android.telecom.Call} for use
+ * with unit testing. Since {@link android.telecom.Call} is final, it cannot be mocked using
+ * mockito, and since all setter methods are hidden, it is necessary to use reflection. In the
+ * future, it would be desirable to replace this if a different mocking solution is used.
+ */
+public class TestTelecomCall {
+
+ private android.telecom.Call mCall;
+
+ public static @Nullable TestTelecomCall createInstance(String callId,
+ Uri handle,
+ int handlePresentation,
+ String callerDisplayName,
+ int callerDisplayNamePresentation,
+ PhoneAccountHandle accountHandle,
+ int capabilities,
+ int properties,
+ DisconnectCause disconnectCause,
+ long connectTimeMillis,
+ GatewayInfo gatewayInfo,
+ int videoState,
+ StatusHints statusHints,
+ Bundle extras,
+ Bundle intentExtras) {
+
+ try {
+ // Phone and InCall adapter are @hide, so we cannot refer to them directly.
+ Class<?> phoneClass = Class.forName("android.telecom.Phone");
+ Class<?> incallAdapterClass = Class.forName("android.telecom.InCallAdapter");
+ Class<?> callClass = android.telecom.Call.class;
+ Constructor<?> cons = callClass
+ .getDeclaredConstructor(phoneClass, String.class, incallAdapterClass);
+ cons.setAccessible(true);
+
+ android.telecom.Call call = (android.telecom.Call) cons.newInstance(null, callId, null);
+
+ // Create an instance of the call details.
+ Class<?> callDetailsClass = android.telecom.Call.Details.class;
+ Constructor<?> detailsCons = callDetailsClass.getDeclaredConstructor(
+ String.class, /* telecomCallId */
+ Uri.class, /* handle */
+ int.class, /* handlePresentation */
+ String.class, /* callerDisplayName */
+ int.class, /* callerDisplayNamePresentation */
+ PhoneAccountHandle.class, /* accountHandle */
+ int.class, /* capabilities */
+ int.class, /* properties */
+ DisconnectCause.class, /* disconnectCause */
+ long.class, /* connectTimeMillis */
+ GatewayInfo.class, /* gatewayInfo */
+ int.class, /* videoState */
+ StatusHints.class, /* statusHints */
+ Bundle.class, /* extras */
+ Bundle.class /* intentExtras */);
+ detailsCons.setAccessible(true);
+
+ android.telecom.Call.Details details = (android.telecom.Call.Details)
+ detailsCons.newInstance(callId, handle, handlePresentation, callerDisplayName,
+ callerDisplayNamePresentation, accountHandle, capabilities, properties,
+ disconnectCause, connectTimeMillis, gatewayInfo, videoState,
+ statusHints,
+ extras, intentExtras);
+
+ // Finally, set this as the details of the call.
+ Field detailsField = call.getClass().getDeclaredField("mDetails");
+ detailsField.setAccessible(true);
+ detailsField.set(call, details);
+
+ return new TestTelecomCall(call);
+ } catch (NoSuchMethodException nsm) {
+ return null;
+ } catch (ClassNotFoundException cnf) {
+ return null;
+ } catch (IllegalAccessException e) {
+ return null;
+ } catch (InstantiationException e) {
+ return null;
+ } catch (InvocationTargetException e) {
+ return null;
+ } catch (NoSuchFieldException e) {
+ return null;
+ }
+ }
+
+ private TestTelecomCall(android.telecom.Call call) {
+ mCall = call;
+ }
+
+ public android.telecom.Call getCall() {
+ return mCall;
+ }
+
+ public void forceDetailsUpdate() {
+ Preconditions.checkNotNull(mCall);
+
+ try {
+ Method method = mCall.getClass().getDeclaredMethod("fireDetailsChanged",
+ android.telecom.Call.Details.class);
+ method.setAccessible(true);
+ method.invoke(mCall, mCall.getDetails());
+ } catch (NoSuchMethodException e) {
+ Log.e(this, "forceDetailsUpdate", e);
+ } catch (InvocationTargetException e) {
+ Log.e(this, "forceDetailsUpdate", e);
+ } catch (IllegalAccessException e) {
+ Log.e(this, "forceDetailsUpdate", e);
+ }
+ }
+
+ public void setCapabilities(int capabilities) {
+ Preconditions.checkNotNull(mCall);
+ try {
+ Field field = mCall.getDetails().getClass().getDeclaredField("mCallCapabilities");
+ field.setAccessible(true);
+ field.set(mCall.getDetails(), capabilities);
+ } catch (IllegalAccessException e) {
+ Log.e(this, "setProperties", e);
+ } catch (NoSuchFieldException e) {
+ Log.e(this, "setProperties", e);
+ }
+ }
+
+ public void setCall(android.telecom.Call call) {
+ mCall = call;
+ }
+}