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