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