aboutsummaryrefslogtreecommitdiff
path: root/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInCallService.java
diff options
context:
space:
mode:
Diffstat (limited to 'shadows/framework/src/main/java/org/robolectric/shadows/ShadowInCallService.java')
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowInCallService.java58
1 files changed, 52 insertions, 6 deletions
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInCallService.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInCallService.java
index 4ab7b896d..c3b4a3e41 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInCallService.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInCallService.java
@@ -3,6 +3,7 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N_MR1;
import static android.os.Build.VERSION_CODES.P;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
import static org.robolectric.shadow.api.Shadow.invokeConstructor;
import static org.robolectric.util.reflector.Reflector.reflector;
@@ -18,7 +19,6 @@ import android.telecom.InCallService;
import android.telecom.ParcelableCall;
import android.telecom.Phone;
import com.android.internal.os.SomeArgs;
-import com.android.internal.telecom.IInCallAdapter;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
@@ -26,6 +26,7 @@ import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
import org.robolectric.util.reflector.Accessor;
+import org.robolectric.util.reflector.Constructor;
import org.robolectric.util.reflector.Direct;
import org.robolectric.util.reflector.ForType;
@@ -37,14 +38,23 @@ public class ShadowInCallService extends ShadowService {
private static final int MSG_SET_POST_DIAL_WAIT = 4;
private static final int MSG_ON_CONNECTION_EVENT = 9;
- private ShadowPhone shadowPhone;
private boolean canAddCall;
private boolean muted;
private int audioRoute = CallAudioState.ROUTE_EARPIECE;
private BluetoothDevice bluetoothDevice;
private int supportedRouteMask;
- @Implementation
+ /* Starting in Android V, the InCallService does not allow setting an InCallAdapter if Phone
+ * was already set. This is how the InCallService should be instantiated in tests:
+ * ```
+ * InCallServiceController serviceController =
+ * Robolectric.buildService(InCallServiceImpl.class, intent).create();
+ * IInCallService.Stub inCallServiceBinder =
+ * (IInCallService.Stub) serviceController.get().onBind(intent);
+ * inCallServiceBinder.setInCallAdapter(new InCallAdapterImpl());
+ * ```
+ * Do not rely on reflection for this and use the public APIs instead. */
+ @Implementation(maxSdk = UPSIDE_DOWN_CAKE)
protected void __constructor__() {
InCallAdapter adapter = Shadow.newInstanceOf(InCallAdapter.class);
Phone phone;
@@ -60,13 +70,17 @@ public class ShadowInCallService extends ShadowService {
ReflectionHelpers.callConstructor(
Phone.class, ClassParameter.from(InCallAdapter.class, adapter));
}
- shadowPhone = Shadow.extract(phone);
ReflectionHelpers.setField(inCallService, "mPhone", phone);
invokeConstructor(InCallService.class, inCallService);
}
+ /**
+ * @deprecated Please add calls by adding a Call using {@link
+ * android.telecom.InCallService.InCallServiceBinder}.
+ */
+ @Deprecated
public void addCall(Call call) {
- shadowPhone.addCall(call);
+ getShadowPhone().addCall(call);
}
public void addCall(ParcelableCall parcelableCall) {
@@ -96,8 +110,12 @@ public class ShadowInCallService extends ShadowService {
getHandler().obtainMessage(MSG_ON_CONNECTION_EVENT, args).sendToTarget();
}
+ /**
+ * @deprecated Please remove calls by invoking {@link Call#disconnect()}.
+ */
+ @Deprecated
public void removeCall(Call call) {
- shadowPhone.removeCall(call);
+ getShadowPhone().removeCall(call);
}
@Implementation
@@ -168,12 +186,34 @@ public class ShadowInCallService extends ShadowService {
*/
private boolean isInCallAdapterSet() {
Phone phone = reflector(ReflectorInCallService.class, inCallService).getPhone();
+ if (phone == null) {
+ return false;
+ }
InCallAdapter inCallAdapter = reflector(ReflectorPhone.class, phone).getInCallAdapter();
Object internalAdapter =
reflector(ReflectorInCallAdapter.class, inCallAdapter).getInternalInCallAdapter();
return internalAdapter != null;
}
+ private ShadowPhone getShadowPhone() {
+ if (reflector(ReflectorInCallService.class, inCallService).getPhone() == null) {
+ setPhone();
+ }
+ Phone phone = reflector(ReflectorInCallService.class, inCallService).getPhone();
+ return Shadow.extract(phone);
+ }
+
+ private void setPhone() {
+ InCallAdapter adapter = Shadow.newInstanceOf(InCallAdapter.class);
+ Phone phone;
+ if (VERSION.SDK_INT > N_MR1) {
+ phone = reflector(ReflectorPhone.class, inCallService).newInstance(adapter, "", 0);
+ } else {
+ phone = reflector(ReflectorPhone.class, inCallService).newInstance(adapter);
+ }
+ ReflectionHelpers.setField(inCallService, "mPhone", phone);
+ }
+
@ForType(InCallService.class)
interface ReflectorInCallService {
@Accessor("mHandler")
@@ -199,6 +239,12 @@ public class ShadowInCallService extends ShadowService {
interface ReflectorPhone {
@Accessor("mInCallAdapter")
InCallAdapter getInCallAdapter();
+
+ @Constructor
+ Phone newInstance(InCallAdapter inCallAdapter, String name, int type);
+
+ @Constructor
+ Phone newInstance(InCallAdapter inCallAdapter);
}
@ForType(InCallAdapter.class)