1 /* 2 * Copyright (C) 2013 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.testapps; 18 19 import android.net.Uri; 20 import android.telecom.CallAudioState; 21 import android.telecom.Conference; 22 import android.telecom.Connection; 23 import android.telecom.ConnectionRequest; 24 import android.telecom.ConnectionService; 25 import android.telecom.DisconnectCause; 26 import android.telecom.PhoneAccountHandle; 27 import android.telecom.RemoteConference; 28 import android.telecom.RemoteConnection; 29 import android.telecom.StatusHints; 30 import android.telecom.VideoProfile; 31 import android.util.Log; 32 33 import java.util.ArrayList; 34 import java.util.HashMap; 35 import java.util.List; 36 import java.util.Map; 37 38 /** 39 * Service which acts as a fake ConnectionManager if so configured. 40 */ 41 public class TestConnectionManager extends ConnectionService { 42 public final class TestManagedConnection extends Connection { 43 private final RemoteConnection.Callback mRemoteCallback = new RemoteConnection.Callback() { 44 @Override 45 public void onStateChanged(RemoteConnection connection, int state) { 46 setState(state); 47 } 48 49 @Override 50 public void onDisconnected( 51 RemoteConnection connection, DisconnectCause disconnectCause) { 52 setDisconnected(disconnectCause); 53 destroy(); 54 } 55 56 @Override 57 public void onRingbackRequested(RemoteConnection connection, boolean ringback) { 58 setRingbackRequested(ringback); 59 } 60 61 @Override 62 public void onConnectionCapabilitiesChanged(RemoteConnection connection, 63 int connectionCapabilities) { 64 setConnectionCapabilities(connectionCapabilities); 65 } 66 67 @Override 68 public void onConnectionPropertiesChanged(RemoteConnection connection, 69 int connectionProperties) { 70 setConnectionProperties(connectionProperties); 71 } 72 73 @Override 74 public void onPostDialWait(RemoteConnection connection, String remainingDigits) { 75 setPostDialWait(remainingDigits); 76 } 77 78 @Override 79 public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) { 80 setAudioModeIsVoip(isVoip); 81 } 82 83 @Override 84 public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) { 85 setStatusHints(statusHints); 86 } 87 88 @Override 89 public void onVideoStateChanged(RemoteConnection connection, int videoState) { 90 if (videoState == VideoProfile.STATE_BIDIRECTIONAL) { 91 setVideoProvider(new TestManagedVideoProvider(connection.getVideoProvider())); 92 } 93 setVideoState(videoState); 94 } 95 96 @Override 97 public void onAddressChanged( 98 RemoteConnection connection, Uri address, int presentation) { 99 setAddress(address, presentation); 100 } 101 102 @Override 103 public void onCallerDisplayNameChanged( 104 RemoteConnection connection, String callerDisplayName, int presentation) { 105 setCallerDisplayName(callerDisplayName, presentation); 106 } 107 108 @Override 109 public void onDestroyed(RemoteConnection connection) { 110 destroy(); 111 mManagedConnectionByRemote.remove(mRemote); 112 } 113 114 @Override 115 public void onConferenceableConnectionsChanged( 116 RemoteConnection connect, 117 List<RemoteConnection> conferenceable) { 118 List<Connection> c = new ArrayList<>(); 119 for (RemoteConnection remote : conferenceable) { 120 if (mManagedConnectionByRemote.containsKey(remote)) { 121 c.add(mManagedConnectionByRemote.get(remote)); 122 } 123 } 124 setConferenceableConnections(c); 125 } 126 127 @Override 128 public void onRttInitiationSuccess(RemoteConnection connection) { 129 sendRttInitiationSuccess(); 130 } 131 132 @Override 133 public void onRttInitiationFailure(RemoteConnection connection, int reason) { 134 sendRttInitiationFailure(reason); 135 } 136 137 @Override 138 public void onRttSessionRemotelyTerminated(RemoteConnection connection) { 139 sendRttSessionRemotelyTerminated(); 140 } 141 142 @Override 143 public void onRemoteRttRequest(RemoteConnection connection) { 144 sendRemoteRttRequest(); 145 } 146 }; 147 148 private final RemoteConnection mRemote; 149 private final boolean mIsIncoming; 150 TestManagedConnection(RemoteConnection remote, boolean isIncoming)151 TestManagedConnection(RemoteConnection remote, boolean isIncoming) { 152 mRemote = remote; 153 mIsIncoming = isIncoming; 154 mRemote.registerCallback(mRemoteCallback); 155 setState(mRemote.getState()); 156 setVideoState(mRemote.getVideoState()); 157 setConnectionProperties(remote.getConnectionProperties()); 158 } 159 160 @Override onAbort()161 public void onAbort() { 162 mRemote.abort(); 163 } 164 165 /** 166 * ${inheritDoc} 167 */ 168 @Override onAnswer(int videoState)169 public void onAnswer(int videoState) { 170 mRemote.answer(videoState); 171 } 172 173 /** 174 * ${inheritDoc} 175 */ 176 @Override onDisconnect()177 public void onDisconnect() { 178 mRemote.disconnect(); 179 } 180 181 @Override onPlayDtmfTone(char c)182 public void onPlayDtmfTone(char c) { 183 mRemote.playDtmfTone(c); 184 } 185 186 /** 187 * ${inheritDoc} 188 */ 189 @Override onHold()190 public void onHold() { 191 mRemote.hold(); 192 } 193 194 /** 195 * ${inheritDoc} 196 */ 197 @Override onReject()198 public void onReject() { 199 mRemote.reject(); 200 } 201 202 /** 203 * ${inheritDoc} 204 */ 205 @Override onUnhold()206 public void onUnhold() { 207 mRemote.unhold(); 208 } 209 210 @Override onCallAudioStateChanged(CallAudioState state)211 public void onCallAudioStateChanged(CallAudioState state) { 212 mRemote.setCallAudioState(state); 213 } 214 215 @Override onStartRtt(RttTextStream rttTextStream)216 public void onStartRtt(RttTextStream rttTextStream) { 217 mRemote.startRtt(rttTextStream); 218 } 219 220 @Override onStopRtt()221 public void onStopRtt() { 222 mRemote.stopRtt(); 223 } 224 225 @Override handleRttUpgradeResponse(RttTextStream rttTextStream)226 public void handleRttUpgradeResponse(RttTextStream rttTextStream) { 227 mRemote.sendRttUpgradeResponse(rttTextStream); 228 } 229 setState(int state)230 private void setState(int state) { 231 log("setState: " + state); 232 switch (state) { 233 case STATE_ACTIVE: 234 setActive(); 235 break; 236 case STATE_HOLDING: 237 setOnHold(); 238 break; 239 case STATE_DIALING: 240 setDialing(); 241 break; 242 case STATE_RINGING: 243 setRinging(); 244 break; 245 } 246 } 247 } 248 public final class TestManagedConference extends Conference { 249 private final RemoteConference.Callback mRemoteCallback = new RemoteConference.Callback() { 250 @Override 251 public void onStateChanged(RemoteConference conference, int oldState, int newState) { 252 switch (newState) { 253 case Connection.STATE_DISCONNECTED: 254 // See onDisconnected below 255 break; 256 case Connection.STATE_HOLDING: 257 setOnHold(); 258 break; 259 case Connection.STATE_ACTIVE: 260 setActive(); 261 break; 262 default: 263 log("unrecognized state for Conference: " + newState); 264 break; 265 } 266 } 267 268 @Override 269 public void onDisconnected(RemoteConference conference, 270 DisconnectCause disconnectCause) { 271 setDisconnected(disconnectCause); 272 } 273 274 @Override 275 public void onConnectionAdded( 276 RemoteConference conference, 277 RemoteConnection connection) { 278 TestManagedConnection c = mManagedConnectionByRemote.get(connection); 279 if (c == null) { 280 log("onConnectionAdded cannot find remote connection: " + connection); 281 } else { 282 addConnection(c); 283 } 284 } 285 286 @Override 287 public void onConnectionRemoved( 288 RemoteConference conference, 289 RemoteConnection connection) { 290 TestManagedConnection c = mManagedConnectionByRemote.get(connection); 291 if (c == null) { 292 log("onConnectionRemoved cannot find remote connection: " + connection); 293 } else { 294 removeConnection(c); 295 } 296 } 297 298 @Override 299 public void onConnectionCapabilitiesChanged(RemoteConference conference, 300 int connectionCapabilities) { 301 setConnectionCapabilities(connectionCapabilities); 302 } 303 304 @Override 305 public void onConnectionPropertiesChanged(RemoteConference conference, 306 int connectionProperties) { 307 setConnectionProperties(connectionProperties); 308 } 309 310 @Override 311 public void onDestroyed(RemoteConference conference) { 312 destroy(); 313 mRemote.unregisterCallback(mRemoteCallback); 314 mManagedConferenceByRemote.remove(mRemote); 315 } 316 317 }; 318 319 @Override onPlayDtmfTone(char c)320 public void onPlayDtmfTone(char c) { 321 mRemote.playDtmfTone(c); 322 }; 323 324 @Override onStopDtmfTone()325 public void onStopDtmfTone() { 326 mRemote.stopDtmfTone(); 327 }; 328 329 private final RemoteConference mRemote; 330 TestManagedConference(RemoteConference remote)331 public TestManagedConference(RemoteConference remote) { 332 super(null); 333 mRemote = remote; 334 remote.registerCallback(mRemoteCallback); 335 setActive(); 336 for (RemoteConnection r : remote.getConnections()) { 337 TestManagedConnection c = mManagedConnectionByRemote.get(r); 338 if (c != null) { 339 addConnection(c); 340 } 341 } 342 } 343 } 344 log(String msg)345 static void log(String msg) { 346 Log.w("telecomtestcs", "[TestConnectionManager] " + msg); 347 } 348 349 private final Map<RemoteConference, TestManagedConference> mManagedConferenceByRemote 350 = new HashMap<>(); 351 private final Map<RemoteConnection, TestManagedConnection> mManagedConnectionByRemote 352 = new HashMap<>(); 353 354 @Override onCreateOutgoingConnection( PhoneAccountHandle connectionManagerAccount, final ConnectionRequest request)355 public Connection onCreateOutgoingConnection( 356 PhoneAccountHandle connectionManagerAccount, 357 final ConnectionRequest request) { 358 return makeConnection(request, false); 359 } 360 361 @Override onCreateIncomingConnection( PhoneAccountHandle connectionManagerAccount, final ConnectionRequest request)362 public Connection onCreateIncomingConnection( 363 PhoneAccountHandle connectionManagerAccount, 364 final ConnectionRequest request) { 365 return makeConnection(request, true); 366 } 367 368 @Override onConference(Connection a, Connection b)369 public void onConference(Connection a, Connection b) { 370 conferenceRemoteConnections( 371 ((TestManagedConnection) a).mRemote, 372 ((TestManagedConnection) b).mRemote); 373 } 374 375 @Override onRemoteConferenceAdded(RemoteConference remoteConference)376 public void onRemoteConferenceAdded(RemoteConference remoteConference) { 377 addConference(new TestManagedConference(remoteConference)); 378 } 379 getManagedConnectionByRemote()380 Map<RemoteConnection, TestManagedConnection> getManagedConnectionByRemote() { 381 return mManagedConnectionByRemote; 382 } 383 makeConnection(ConnectionRequest request, boolean incoming)384 private Connection makeConnection(ConnectionRequest request, boolean incoming) { 385 RemoteConnection remote = incoming 386 ? createRemoteIncomingConnection(request.getAccountHandle(), request) 387 : createRemoteOutgoingConnection(request.getAccountHandle(), request); 388 TestManagedConnection local = new TestManagedConnection(remote, false); 389 mManagedConnectionByRemote.put(remote, local); 390 return local; 391 } 392 } 393