1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.M; 4 import static org.robolectric.util.reflector.Reflector.reflector; 5 6 import android.telecom.Call; 7 import android.telecom.CallAudioState; 8 import android.telecom.InCallAdapter; 9 import android.telecom.Phone; 10 import java.util.ArrayList; 11 import java.util.Collections; 12 import java.util.List; 13 import org.robolectric.annotation.Implementation; 14 import org.robolectric.annotation.Implements; 15 import org.robolectric.annotation.RealObject; 16 import org.robolectric.shadow.api.Shadow; 17 import org.robolectric.util.ReflectionHelpers; 18 import org.robolectric.util.reflector.Accessor; 19 import org.robolectric.util.reflector.ForType; 20 21 /** Shadow for {@link android.telecom.Phone}. */ 22 @Implements(value = Phone.class, isInAndroidSdk = false) 23 public class ShadowPhone { 24 @RealObject private Phone phone; 25 26 private final List<Call> calls = new ArrayList<>(); 27 28 @Implementation(minSdk = M) getCalls()29 protected final List<Call> getCalls() { 30 List<Call> unmodifiableCalls = reflector(ReflectorPhone.class, phone).getUnmodifiableCalls(); 31 if (unmodifiableCalls != null) { 32 return unmodifiableCalls; 33 } 34 return Collections.unmodifiableList(calls); 35 } 36 37 @Implementation(minSdk = M) getCallAudioState()38 protected final CallAudioState getCallAudioState() { 39 CallAudioState callAudioState = reflector(ReflectorPhone.class, phone).getCallAudioState(); 40 if (callAudioState != null) { 41 return callAudioState; 42 } 43 InCallAdapter inCallAdapter = ReflectionHelpers.getField(phone, "mInCallAdapter"); 44 int audioRoute = ((ShadowInCallAdapter) Shadow.extract(inCallAdapter)).getAudioRoute(); 45 46 return new CallAudioState( 47 /* muted= */ false, 48 audioRoute, 49 CallAudioState.ROUTE_SPEAKER | CallAudioState.ROUTE_EARPIECE); 50 } 51 52 /** Add Call to a collection that returns when getCalls is called. */ addCall(Call call)53 public void addCall(Call call) { 54 calls.add(call); 55 List<Call> realCalls = reflector(ReflectorPhone.class, phone).getCalls(); 56 if (realCalls != null) { 57 realCalls.add(call); 58 } 59 } 60 61 /** Remove call that has previously been added via addCall(). */ removeCall(Call call)62 public void removeCall(Call call) { 63 calls.remove(call); 64 List<Call> realCalls = reflector(ReflectorPhone.class, phone).getCalls(); 65 if (realCalls != null) { 66 realCalls.remove(call); 67 } 68 } 69 70 @ForType(Phone.class) 71 interface ReflectorPhone { 72 @Accessor("mUnmodifiableCalls") getUnmodifiableCalls()73 List<Call> getUnmodifiableCalls(); 74 75 @Accessor("mCalls") getCalls()76 List<Call> getCalls(); 77 78 @Accessor("mCallAudioState") getCallAudioState()79 CallAudioState getCallAudioState(); 80 } 81 } 82