1 /* 2 * Copyright (C) 2015 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.server.telecom.tests; 18 19 import com.android.internal.telecom.IInCallAdapter; 20 import com.android.internal.telecom.IInCallService; 21 22 import org.mockito.Mockito; 23 24 import android.os.Bundle; 25 import android.os.IBinder; 26 import android.os.IInterface; 27 import android.os.RemoteException; 28 import android.telecom.CallAudioState; 29 import android.telecom.CallEndpoint; 30 import android.telecom.ParcelableCall; 31 32 import java.util.HashMap; 33 import java.util.List; 34 import java.util.Map; 35 import java.util.concurrent.CountDownLatch; 36 import java.util.concurrent.TimeUnit; 37 38 /** 39 * Controls a test {@link IInCallService} as would be provided by an InCall UI on a system. 40 */ 41 public class InCallServiceFixture implements TestFixture<IInCallService> { 42 43 public String mLatestCallId; 44 public IInCallAdapter mInCallAdapter; 45 public CallAudioState mCallAudioState; 46 public final Map<String, ParcelableCall> mCallById = new HashMap<>(); 47 public final Map<String, String> mPostDialById = new HashMap<>(); 48 public final Map<String, String> mPostDialWaitById = new HashMap<>(); 49 public boolean mBringToForeground; 50 public boolean mShowDialpad; 51 public boolean mCanAddCall; 52 public boolean mSilenceRinger; 53 public CountDownLatch mUpdateCallLock = new CountDownLatch(1); 54 public CountDownLatch mAddCallLock = new CountDownLatch(1); 55 56 public class FakeInCallService extends IInCallService.Stub { 57 @Override setInCallAdapter(IInCallAdapter inCallAdapter)58 public void setInCallAdapter(IInCallAdapter inCallAdapter) throws RemoteException { 59 if (mInCallAdapter != null && inCallAdapter != null) { 60 throw new RuntimeException("Adapter is already set"); 61 } 62 if (mInCallAdapter == null && inCallAdapter == null) { 63 throw new RuntimeException("Adapter was never set"); 64 } 65 mInCallAdapter = inCallAdapter; 66 } 67 68 @Override addCall(ParcelableCall call)69 public void addCall(ParcelableCall call) throws RemoteException { 70 if (mCallById.containsKey(call.getId())) { 71 throw new RuntimeException("Call " + call.getId() + " already added"); 72 } 73 mLatestCallId = call.getId(); 74 mCallById.put(call.getId(), call); 75 mAddCallLock.countDown(); 76 } 77 78 @Override updateCall(ParcelableCall call)79 public void updateCall(ParcelableCall call) throws RemoteException { 80 if (!mCallById.containsKey(call.getId())) { 81 // This used to throw an exception, however the actual InCallService implementation 82 // ignores updates for calls which don't yet exist. This is not a problem as when 83 // a call is added to an InCallService its entire state is parceled and sent to the 84 // InCallService. 85 return; 86 } 87 mLatestCallId = call.getId(); 88 mCallById.put(call.getId(), call); 89 mUpdateCallLock.countDown(); 90 } 91 92 @Override setPostDial(String callId, String remaining)93 public void setPostDial(String callId, String remaining) throws RemoteException { 94 mPostDialWaitById.remove(callId); 95 mPostDialById.put(callId, remaining); 96 } 97 98 @Override setPostDialWait(String callId, String remaining)99 public void setPostDialWait(String callId, String remaining) throws RemoteException { 100 mPostDialById.remove(callId); 101 mPostDialWaitById.put(callId, remaining); 102 } 103 104 @Override onCallAudioStateChanged(CallAudioState audioState)105 public void onCallAudioStateChanged(CallAudioState audioState) throws RemoteException { 106 mCallAudioState = audioState; 107 } 108 109 @Override onCallEndpointChanged(CallEndpoint callEndpoint)110 public void onCallEndpointChanged(CallEndpoint callEndpoint) {} 111 112 @Override onAvailableCallEndpointsChanged(List<CallEndpoint> availableCallEndpoints)113 public void onAvailableCallEndpointsChanged(List<CallEndpoint> availableCallEndpoints) {} 114 115 @Override onMuteStateChanged(boolean isMuted)116 public void onMuteStateChanged(boolean isMuted) {} 117 118 @Override bringToForeground(boolean showDialpad)119 public void bringToForeground(boolean showDialpad) throws RemoteException { 120 mBringToForeground = true; 121 mShowDialpad = showDialpad; 122 } 123 124 @Override onCanAddCallChanged(boolean canAddCall)125 public void onCanAddCallChanged(boolean canAddCall) throws RemoteException { 126 mCanAddCall = canAddCall; 127 } 128 129 @Override silenceRinger()130 public void silenceRinger() throws RemoteException { 131 mSilenceRinger = true; 132 } 133 134 @Override onConnectionEvent(String callId, String event, Bundle extras)135 public void onConnectionEvent(String callId, String event, Bundle extras) 136 throws RemoteException { 137 } 138 139 @Override onRttUpgradeRequest(String callId, int id)140 public void onRttUpgradeRequest(String callId, int id) throws RemoteException { 141 } 142 143 @Override onRttInitiationFailure(String callId, int reason)144 public void onRttInitiationFailure(String callId, int reason) throws RemoteException { 145 } 146 147 @Override asBinder()148 public IBinder asBinder() { 149 return this; 150 } 151 152 @Override queryLocalInterface(String descriptor)153 public IInterface queryLocalInterface(String descriptor) { 154 return this; 155 } 156 157 @Override onHandoverFailed(String callId, int error)158 public void onHandoverFailed(String callId, int error) {} 159 160 @Override onHandoverComplete(String callId)161 public void onHandoverComplete(String callId) {} 162 } 163 164 private IInCallService.Stub mInCallServiceFake = new FakeInCallService(); 165 private IInCallService.Stub mInCallServiceSpy = Mockito.spy(mInCallServiceFake); 166 InCallServiceFixture()167 public InCallServiceFixture() throws Exception { } 168 169 @Override getTestDouble()170 public IInCallService getTestDouble() { 171 return mInCallServiceSpy; 172 } 173 getCall(String id)174 public ParcelableCall getCall(String id) { 175 return mCallById.get(id); 176 } 177 getInCallAdapter()178 public IInCallAdapter getInCallAdapter() { 179 return mInCallAdapter; 180 } 181 waitForUpdate()182 public void waitForUpdate() { 183 try { 184 mUpdateCallLock.await(5000, TimeUnit.MILLISECONDS); 185 } catch (InterruptedException ie) { 186 return; 187 } 188 mUpdateCallLock = new CountDownLatch(1); 189 } 190 waitUntilNumCalls(int numCalls)191 public void waitUntilNumCalls(int numCalls) { 192 if (mCallById.size() == numCalls) { 193 return; 194 } 195 mAddCallLock = new CountDownLatch(1); 196 197 try { 198 mAddCallLock.await(5000, TimeUnit.MILLISECONDS); 199 } catch (InterruptedException ie) { 200 return; 201 } 202 } 203 } 204