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