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