ConnectionServiceFixture.java revision 2c93c50e5be7d85b78c4af15aaa10e44f0bcdf3e
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 17package com.android.server.telecom.tests; 18 19import com.android.internal.telecom.IConnectionService; 20import com.android.internal.telecom.IConnectionServiceAdapter; 21import com.android.internal.telecom.IVideoProvider; 22import com.android.internal.telecom.RemoteServiceCallback; 23import com.android.server.telecom.Log; 24 25import junit.framework.TestCase; 26 27import org.mockito.Mockito; 28 29import android.content.ComponentName; 30import android.os.Bundle; 31import android.os.IBinder; 32import android.os.IInterface; 33import android.os.RemoteException; 34import android.telecom.CallAudioState; 35import android.telecom.Connection; 36import android.telecom.ConnectionRequest; 37import android.telecom.DisconnectCause; 38import android.telecom.ParcelableConference; 39import android.telecom.ParcelableConnection; 40import android.telecom.PhoneAccountHandle; 41import android.telecom.StatusHints; 42 43import java.util.ArrayList; 44import java.util.HashMap; 45import java.util.HashSet; 46import java.util.List; 47import java.util.Map; 48import java.util.Set; 49 50import static org.mockito.Matchers.any; 51 52/** 53 * Controls a test {@link IConnectionService} as would be provided by a source of connectivity 54 * to the Telecom framework. 55 */ 56public class ConnectionServiceFixture implements TestFixture<IConnectionService> { 57 58 public class FakeConnectionService extends IConnectionService.Stub { 59 60 @Override 61 public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) 62 throws RemoteException { 63 if (!mConnectionServiceAdapters.add(adapter)) { 64 throw new RuntimeException("Adapter already added: " + adapter); 65 } 66 } 67 68 @Override 69 public void removeConnectionServiceAdapter(IConnectionServiceAdapter adapter) 70 throws RemoteException { 71 if (!mConnectionServiceAdapters.remove(adapter)) { 72 throw new RuntimeException("Adapter never added: " + adapter); 73 } 74 } 75 76 @Override 77 public void createConnection(PhoneAccountHandle connectionManagerPhoneAccount, 78 String id, 79 ConnectionRequest request, boolean isIncoming, boolean isUnknown) 80 throws RemoteException { 81 Log.i(ConnectionServiceFixture.this, "xoxox createConnection --> " + id); 82 83 if (mConnectionById.containsKey(id)) { 84 throw new RuntimeException("Connection already exists: " + id); 85 } 86 mLatestConnectionId = id; 87 ConnectionInfo c = new ConnectionInfo(); 88 c.connectionManagerPhoneAccount = connectionManagerPhoneAccount; 89 c.id = id; 90 c.request = request; 91 c.isIncoming = isIncoming; 92 c.isUnknown = isUnknown; 93 c.capabilities |= Connection.CAPABILITY_HOLD | Connection.CAPABILITY_SUPPORT_HOLD; 94 mConnectionById.put(id, c); 95 } 96 97 @Override 98 public void abort(String callId) throws RemoteException { } 99 100 @Override 101 public void answerVideo(String callId, int videoState) throws RemoteException { } 102 103 @Override 104 public void answer(String callId) throws RemoteException { } 105 106 @Override 107 public void reject(String callId) throws RemoteException { } 108 109 @Override 110 public void rejectWithMessage(String callId, String message) throws RemoteException { } 111 112 @Override 113 public void disconnect(String callId) throws RemoteException { } 114 115 @Override 116 public void hold(String callId) throws RemoteException { } 117 118 @Override 119 public void unhold(String callId) throws RemoteException { } 120 121 @Override 122 public void onCallAudioStateChanged(String activeCallId, CallAudioState audioState) 123 throws RemoteException { } 124 125 @Override 126 public void playDtmfTone(String callId, char digit) throws RemoteException { } 127 128 @Override 129 public void stopDtmfTone(String callId) throws RemoteException { } 130 131 @Override 132 public void conference(String conferenceCallId, String callId) throws RemoteException { } 133 134 @Override 135 public void splitFromConference(String callId) throws RemoteException { } 136 137 @Override 138 public void mergeConference(String conferenceCallId) throws RemoteException { } 139 140 @Override 141 public void swapConference(String conferenceCallId) throws RemoteException { } 142 143 @Override 144 public void onPostDialContinue(String callId, boolean proceed) throws RemoteException { } 145 146 @Override 147 public IBinder asBinder() { 148 return this; 149 } 150 151 @Override 152 public IInterface queryLocalInterface(String descriptor) { 153 return this; 154 } 155 }; 156 157 private IConnectionService.Stub mConnectionService = new FakeConnectionService(); 158 private IConnectionService.Stub mConnectionServiceSpy = Mockito.spy(mConnectionService); 159 160 public class ConnectionInfo { 161 PhoneAccountHandle connectionManagerPhoneAccount; 162 String id; 163 boolean ringing; 164 ConnectionRequest request; 165 boolean isIncoming; 166 boolean isUnknown; 167 int state; 168 int addressPresentation; 169 int capabilities; 170 StatusHints statusHints; 171 DisconnectCause disconnectCause; 172 String conferenceId; 173 String callerDisplayName; 174 int callerDisplayNamePresentation; 175 final List<String> conferenceableConnectionIds = new ArrayList<>(); 176 IVideoProvider videoProvider; 177 int videoState; 178 boolean isVoipAudioMode; 179 Bundle extras; 180 } 181 182 public class ConferenceInfo { 183 PhoneAccountHandle phoneAccount; 184 int state; 185 int capabilities; 186 final List<String> connectionIds = new ArrayList<>(); 187 IVideoProvider videoProvider; 188 int videoState; 189 long connectTimeMillis; 190 StatusHints statusHints; 191 Bundle extras; 192 } 193 194 public String mLatestConnectionId; 195 public final Set<IConnectionServiceAdapter> mConnectionServiceAdapters = new HashSet<>(); 196 public final Map<String, ConnectionInfo> mConnectionById = new HashMap<>(); 197 public final Map<String, ConferenceInfo> mConferenceById = new HashMap<>(); 198 public final List<ComponentName> mRemoteConnectionServiceNames = new ArrayList<>(); 199 public final List<IBinder> mRemoteConnectionServices = new ArrayList<>(); 200 201 public ConnectionServiceFixture() throws Exception { } 202 203 @Override 204 public IConnectionService getTestDouble() { 205 return mConnectionServiceSpy; 206 } 207 208 public void sendHandleCreateConnectionComplete(String id) throws Exception { 209 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 210 a.handleCreateConnectionComplete( 211 id, 212 mConnectionById.get(id).request, 213 parcelable(mConnectionById.get(id))); 214 } 215 } 216 217 public void sendSetActive(String id) throws Exception { 218 mConnectionById.get(id).state = Connection.STATE_ACTIVE; 219 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 220 a.setActive(id); 221 } 222 } 223 224 public void sendSetRinging(String id) throws Exception { 225 mConnectionById.get(id).state = Connection.STATE_RINGING; 226 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 227 a.setRinging(id); 228 } 229 } 230 231 public void sendSetDialing(String id) throws Exception { 232 mConnectionById.get(id).state = Connection.STATE_DIALING; 233 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 234 a.setDialing(id); 235 } 236 } 237 238 public void sendSetDisconnected(String id, int disconnectCause) throws Exception { 239 mConnectionById.get(id).state = Connection.STATE_DISCONNECTED; 240 mConnectionById.get(id).disconnectCause = new DisconnectCause(disconnectCause); 241 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 242 a.setDisconnected(id, mConnectionById.get(id).disconnectCause); 243 } 244 } 245 246 public void sendSetOnHold(String id) throws Exception { 247 mConnectionById.get(id).state = Connection.STATE_HOLDING; 248 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 249 a.setOnHold(id); 250 } 251 } 252 253 public void sendSetRingbackRequested(String id) throws Exception { 254 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 255 a.setRingbackRequested(id, mConnectionById.get(id).ringing); 256 } 257 } 258 259 public void sendSetConnectionCapabilities(String id) throws Exception { 260 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 261 a.setConnectionCapabilities(id, mConnectionById.get(id).capabilities); 262 } 263 } 264 265 public void sendSetIsConferenced(String id) throws Exception { 266 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 267 a.setIsConferenced(id, mConnectionById.get(id).conferenceId); 268 } 269 } 270 271 public void sendAddConferenceCall(String id) throws Exception { 272 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 273 a.addConferenceCall(id, parcelable(mConferenceById.get(id))); 274 } 275 } 276 277 public void sendRemoveCall(String id) throws Exception { 278 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 279 a.removeCall(id); 280 } 281 } 282 283 public void sendOnPostDialWait(String id, String remaining) throws Exception { 284 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 285 a.onPostDialWait(id, remaining); 286 } 287 } 288 289 public void sendOnPostDialChar(String id, char nextChar) throws Exception { 290 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 291 a.onPostDialChar(id, nextChar); 292 } 293 } 294 295 public void sendQueryRemoteConnectionServices() throws Exception { 296 mRemoteConnectionServices.clear(); 297 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 298 a.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() { 299 @Override 300 public void onError() throws RemoteException { 301 throw new RuntimeException(); 302 } 303 304 @Override 305 public void onResult( 306 List<ComponentName> names, 307 List<IBinder> services) 308 throws RemoteException { 309 TestCase.assertEquals(names.size(), services.size()); 310 mRemoteConnectionServiceNames.addAll(names); 311 mRemoteConnectionServices.addAll(services); 312 } 313 314 @Override 315 public IBinder asBinder() { 316 return this; 317 } 318 }); 319 } 320 } 321 322 public void sendSetVideoProvider(String id) throws Exception { 323 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 324 a.setVideoProvider(id, mConnectionById.get(id).videoProvider); 325 } 326 } 327 328 public void sendSetVideoState(String id) throws Exception { 329 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 330 a.setVideoState(id, mConnectionById.get(id).videoState); 331 } 332 } 333 334 public void sendSetIsVoipAudioMode(String id) throws Exception { 335 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 336 a.setIsVoipAudioMode(id, mConnectionById.get(id).isVoipAudioMode); 337 } 338 } 339 340 public void sendSetStatusHints(String id) throws Exception { 341 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 342 a.setStatusHints(id, mConnectionById.get(id).statusHints); 343 } 344 } 345 346 public void sendSetAddress(String id) throws Exception { 347 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 348 a.setAddress( 349 id, 350 mConnectionById.get(id).request.getAddress(), 351 mConnectionById.get(id).addressPresentation); 352 } 353 } 354 355 public void sendSetCallerDisplayName(String id) throws Exception { 356 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 357 a.setCallerDisplayName( 358 id, 359 mConnectionById.get(id).callerDisplayName, 360 mConnectionById.get(id).callerDisplayNamePresentation); 361 } 362 } 363 364 public void sendSetConferenceableConnections(String id) throws Exception { 365 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 366 a.setConferenceableConnections(id, mConnectionById.get(id).conferenceableConnectionIds); 367 } 368 } 369 370 public void sendAddExistingConnection(String id) throws Exception { 371 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 372 a.addExistingConnection(id, parcelable(mConnectionById.get(id))); 373 } 374 } 375 376 private ParcelableConference parcelable(ConferenceInfo c) { 377 return new ParcelableConference( 378 c.phoneAccount, 379 c.state, 380 c.capabilities, 381 c.connectionIds, 382 c.videoProvider, 383 c.videoState, 384 c.connectTimeMillis, 385 c.statusHints, 386 c.extras); 387 } 388 389 private ParcelableConnection parcelable(ConnectionInfo c) { 390 return new ParcelableConnection( 391 c.request.getAccountHandle(), 392 c.state, 393 c.capabilities, 394 c.request.getAddress(), 395 c.addressPresentation, 396 c.callerDisplayName, 397 c.callerDisplayNamePresentation, 398 c.videoProvider, 399 c.videoState, 400 false, /* ringback requested */ 401 false, /* voip audio mode */ 402 0, /* Connect Time for conf call on this connection */ 403 c.statusHints, 404 c.disconnectCause, 405 c.conferenceableConnectionIds, 406 c.extras); 407 } 408} 409