ConnectionServiceFixture.java revision 1b5490ac8643a5969adaba6f68d872acd251d666
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.IBinder; 31import android.os.IInterface; 32import android.os.RemoteException; 33import android.telecom.AudioState; 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 mConnectionById.put(id, c); 94 } 95 96 @Override 97 public void abort(String callId) throws RemoteException { } 98 99 @Override 100 public void answerVideo(String callId, int videoState) throws RemoteException { } 101 102 @Override 103 public void answer(String callId) throws RemoteException { } 104 105 @Override 106 public void reject(String callId) throws RemoteException { } 107 108 @Override 109 public void disconnect(String callId) throws RemoteException { } 110 111 @Override 112 public void hold(String callId) throws RemoteException { } 113 114 @Override 115 public void unhold(String callId) throws RemoteException { } 116 117 @Override 118 public void onCallAudioStateChanged(String activeCallId, CallAudioState audioState) 119 throws RemoteException { } 120 121 @Override 122 public void playDtmfTone(String callId, char digit) throws RemoteException { } 123 124 @Override 125 public void stopDtmfTone(String callId) throws RemoteException { } 126 127 @Override 128 public void conference(String conferenceCallId, String callId) throws RemoteException { } 129 130 @Override 131 public void splitFromConference(String callId) throws RemoteException { } 132 133 @Override 134 public void mergeConference(String conferenceCallId) throws RemoteException { } 135 136 @Override 137 public void swapConference(String conferenceCallId) throws RemoteException { } 138 139 @Override 140 public void onPostDialContinue(String callId, boolean proceed) throws RemoteException { } 141 142 @Override 143 public IBinder asBinder() { 144 return this; 145 } 146 147 @Override 148 public IInterface queryLocalInterface(String descriptor) { 149 return this; 150 } 151 }; 152 153 private IConnectionService.Stub mConnectionService = new FakeConnectionService(); 154 private IConnectionService.Stub mConnectionServiceSpy = Mockito.spy(mConnectionService); 155 156 public class ConnectionInfo { 157 PhoneAccountHandle connectionManagerPhoneAccount; 158 String id; 159 boolean ringing; 160 ConnectionRequest request; 161 boolean isIncoming; 162 boolean isUnknown; 163 int state; 164 int addressPresentation; 165 int capabilities; 166 StatusHints statusHints; 167 DisconnectCause disconnectCause; 168 String conferenceId; 169 String callerDisplayName; 170 int callerDisplayNamePresentation; 171 final List<String> conferenceableConnectionIds = new ArrayList<>(); 172 IVideoProvider videoProvider; 173 int videoState; 174 boolean isVoipAudioMode; 175 } 176 177 public class ConferenceInfo { 178 PhoneAccountHandle phoneAccount; 179 int state; 180 int capabilities; 181 final List<String> connectionIds = new ArrayList<>(); 182 IVideoProvider videoProvider; 183 int videoState; 184 long connectTimeMillis; 185 StatusHints statusHints; 186 } 187 188 public String mLatestConnectionId; 189 public final Set<IConnectionServiceAdapter> mConnectionServiceAdapters = new HashSet<>(); 190 public final Map<String, ConnectionInfo> mConnectionById = new HashMap<>(); 191 public final Map<String, ConferenceInfo> mConferenceById = new HashMap<>(); 192 public final List<ComponentName> mRemoteConnectionServiceNames = new ArrayList<>(); 193 public final List<IBinder> mRemoteConnectionServices = new ArrayList<>(); 194 195 public ConnectionServiceFixture() throws Exception { } 196 197 @Override 198 public IConnectionService getTestDouble() { 199 return mConnectionServiceSpy; 200 } 201 202 public void sendHandleCreateConnectionComplete(String id) throws Exception { 203 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 204 a.handleCreateConnectionComplete( 205 id, 206 mConnectionById.get(id).request, 207 parcelable(mConnectionById.get(id))); 208 } 209 } 210 211 public void sendSetActive(String id) throws Exception { 212 mConnectionById.get(id).state = Connection.STATE_ACTIVE; 213 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 214 a.setActive(id); 215 } 216 } 217 218 public void sendSetRinging(String id) throws Exception { 219 mConnectionById.get(id).state = Connection.STATE_RINGING; 220 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 221 a.setRinging(id); 222 } 223 } 224 225 public void sendSetDialing(String id) throws Exception { 226 mConnectionById.get(id).state = Connection.STATE_DIALING; 227 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 228 a.setDialing(id); 229 } 230 } 231 232 public void sendSetDisconnected(String id, int disconnectCause) throws Exception { 233 mConnectionById.get(id).state = Connection.STATE_DISCONNECTED; 234 mConnectionById.get(id).disconnectCause = new DisconnectCause(disconnectCause); 235 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 236 a.setDisconnected(id, mConnectionById.get(id).disconnectCause); 237 } 238 } 239 240 public void sendSetOnHold(String id) throws Exception { 241 mConnectionById.get(id).state = Connection.STATE_HOLDING; 242 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 243 a.setOnHold(id); 244 } 245 } 246 247 public void sendSetRingbackRequested(String id) throws Exception { 248 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 249 a.setRingbackRequested(id, mConnectionById.get(id).ringing); 250 } 251 } 252 253 public void sendSetConnectionCapabilities(String id) throws Exception { 254 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 255 a.setConnectionCapabilities(id, mConnectionById.get(id).capabilities); 256 } 257 } 258 259 public void sendSetIsConferenced(String id) throws Exception { 260 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 261 a.setIsConferenced(id, mConnectionById.get(id).conferenceId); 262 } 263 } 264 265 public void sendAddConferenceCall(String id) throws Exception { 266 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 267 a.addConferenceCall(id, parcelable(mConferenceById.get(id))); 268 } 269 } 270 271 public void sendRemoveCall(String id) throws Exception { 272 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 273 a.removeCall(id); 274 } 275 } 276 277 public void sendOnPostDialWait(String id, String remaining) throws Exception { 278 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 279 a.onPostDialWait(id, remaining); 280 } 281 } 282 283 public void sendOnPostDialChar(String id, char nextChar) throws Exception { 284 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 285 a.onPostDialChar(id, nextChar); 286 } 287 } 288 289 public void sendQueryRemoteConnectionServices() throws Exception { 290 mRemoteConnectionServices.clear(); 291 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 292 a.queryRemoteConnectionServices(new RemoteServiceCallback.Stub() { 293 @Override 294 public void onError() throws RemoteException { 295 throw new RuntimeException(); 296 } 297 298 @Override 299 public void onResult( 300 List<ComponentName> names, 301 List<IBinder> services) 302 throws RemoteException { 303 TestCase.assertEquals(names.size(), services.size()); 304 mRemoteConnectionServiceNames.addAll(names); 305 mRemoteConnectionServices.addAll(services); 306 } 307 308 @Override 309 public IBinder asBinder() { 310 return this; 311 } 312 }); 313 } 314 } 315 316 public void sendSetVideoProvider(String id) throws Exception { 317 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 318 a.setVideoProvider(id, mConnectionById.get(id).videoProvider); 319 } 320 } 321 322 public void sendSetVideoState(String id) throws Exception { 323 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 324 a.setVideoState(id, mConnectionById.get(id).videoState); 325 } 326 } 327 328 public void sendSetIsVoipAudioMode(String id) throws Exception { 329 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 330 a.setIsVoipAudioMode(id, mConnectionById.get(id).isVoipAudioMode); 331 } 332 } 333 334 public void sendSetStatusHints(String id) throws Exception { 335 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 336 a.setStatusHints(id, mConnectionById.get(id).statusHints); 337 } 338 } 339 340 public void sendSetAddress(String id) throws Exception { 341 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 342 a.setAddress( 343 id, 344 mConnectionById.get(id).request.getAddress(), 345 mConnectionById.get(id).addressPresentation); 346 } 347 } 348 349 public void sendSetCallerDisplayName(String id) throws Exception { 350 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 351 a.setCallerDisplayName( 352 id, 353 mConnectionById.get(id).callerDisplayName, 354 mConnectionById.get(id).callerDisplayNamePresentation); 355 } 356 } 357 358 public void sendSetConferenceableConnections(String id) throws Exception { 359 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 360 a.setConferenceableConnections(id, mConnectionById.get(id).conferenceableConnectionIds); 361 } 362 } 363 364 public void sendAddExistingConnection(String id) throws Exception { 365 for (IConnectionServiceAdapter a : mConnectionServiceAdapters) { 366 a.addExistingConnection(id, parcelable(mConnectionById.get(id))); 367 } 368 } 369 370 private ParcelableConference parcelable(ConferenceInfo c) { 371 return new ParcelableConference( 372 c.phoneAccount, 373 c.state, 374 c.capabilities, 375 c.connectionIds, 376 c.videoProvider, 377 c.videoState, 378 c.connectTimeMillis, 379 c.statusHints); 380 } 381 382 private ParcelableConnection parcelable(ConnectionInfo c) { 383 return new ParcelableConnection( 384 c.request.getAccountHandle(), 385 c.state, 386 c.capabilities, 387 c.request.getAddress(), 388 c.addressPresentation, 389 c.callerDisplayName, 390 c.callerDisplayNamePresentation, 391 c.videoProvider, 392 c.videoState, 393 false, /* ringback requested */ 394 false, /* voip audio mode */ 395 c.statusHints, 396 c.disconnectCause, 397 c.conferenceableConnectionIds); 398 } 399} 400