1 /* 2 * Copyright (C) 2014 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; 18 19 import android.os.Binder; 20 import android.telecom.PhoneAccountHandle; 21 22 import com.android.internal.telecom.IInCallAdapter; 23 24 /** 25 * Receives call commands and updates from in-call app and passes them through to CallsManager. 26 * {@link InCallController} creates an instance of this class and passes it to the in-call app after 27 * binding to it. This adapter can receive commands and updates until the in-call app is unbound. 28 */ 29 class InCallAdapter extends IInCallAdapter.Stub { 30 private final CallsManager mCallsManager; 31 private final CallIdMapper mCallIdMapper; 32 private final TelecomSystem.SyncRoot mLock; 33 34 /** Persists the specified parameters. */ InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper, TelecomSystem.SyncRoot lock)35 public InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper, 36 TelecomSystem.SyncRoot lock) { 37 mCallsManager = callsManager; 38 mCallIdMapper = callIdMapper; 39 mLock = lock; 40 } 41 42 @Override answerCall(String callId, int videoState)43 public void answerCall(String callId, int videoState) { 44 long token = Binder.clearCallingIdentity(); 45 try { 46 synchronized (mLock) { 47 Log.d(this, "answerCall(%s,%d)", callId, videoState); 48 if (mCallIdMapper.isValidCallId(callId)) { 49 Call call = mCallIdMapper.getCall(callId); 50 if (call != null) { 51 mCallsManager.answerCall(call, videoState); 52 } else { 53 Log.w(this, "answerCall, unknown call id: %s", callId); 54 } 55 } 56 } 57 } finally { 58 Binder.restoreCallingIdentity(token); 59 } 60 } 61 62 @Override rejectCall(String callId, boolean rejectWithMessage, String textMessage)63 public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) { 64 long token = Binder.clearCallingIdentity(); 65 try { 66 synchronized (mLock) { 67 Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage); 68 if (mCallIdMapper.isValidCallId(callId)) { 69 Call call = mCallIdMapper.getCall(callId); 70 if (call != null) { 71 mCallsManager.rejectCall(call, rejectWithMessage, textMessage); 72 } else { 73 Log.w(this, "setRingback, unknown call id: %s", callId); 74 } 75 } 76 } 77 } finally { 78 Binder.restoreCallingIdentity(token); 79 } 80 } 81 82 @Override playDtmfTone(String callId, char digit)83 public void playDtmfTone(String callId, char digit) { 84 long token = Binder.clearCallingIdentity(); 85 try { 86 synchronized (mLock) { 87 Log.d(this, "playDtmfTone(%s,%c)", callId, digit); 88 if (mCallIdMapper.isValidCallId(callId)) { 89 Call call = mCallIdMapper.getCall(callId); 90 if (call != null) { 91 mCallsManager.playDtmfTone(call, digit); 92 } else { 93 Log.w(this, "playDtmfTone, unknown call id: %s", callId); 94 } 95 } 96 } 97 } finally { 98 Binder.restoreCallingIdentity(token); 99 } 100 } 101 102 @Override stopDtmfTone(String callId)103 public void stopDtmfTone(String callId) { 104 long token = Binder.clearCallingIdentity(); 105 try { 106 synchronized (mLock) { 107 Log.d(this, "stopDtmfTone(%s)", callId); 108 if (mCallIdMapper.isValidCallId(callId)) { 109 Call call = mCallIdMapper.getCall(callId); 110 if (call != null) { 111 mCallsManager.stopDtmfTone(call); 112 } else { 113 Log.w(this, "stopDtmfTone, unknown call id: %s", callId); 114 } 115 } 116 } 117 } finally { 118 Binder.restoreCallingIdentity(token); 119 } 120 } 121 122 @Override postDialContinue(String callId, boolean proceed)123 public void postDialContinue(String callId, boolean proceed) { 124 long token = Binder.clearCallingIdentity(); 125 try { 126 synchronized (mLock) { 127 Log.d(this, "postDialContinue(%s)", callId); 128 if (mCallIdMapper.isValidCallId(callId)) { 129 Call call = mCallIdMapper.getCall(callId); 130 if (call != null) { 131 mCallsManager.postDialContinue(call, proceed); 132 } else { 133 Log.w(this, "postDialContinue, unknown call id: %s", callId); 134 } 135 } 136 } 137 } finally { 138 Binder.restoreCallingIdentity(token); 139 } 140 } 141 142 @Override disconnectCall(String callId)143 public void disconnectCall(String callId) { 144 long token = Binder.clearCallingIdentity(); 145 try { 146 synchronized (mLock) { 147 Log.v(this, "disconnectCall: %s", callId); 148 if (mCallIdMapper.isValidCallId(callId)) { 149 Call call = mCallIdMapper.getCall(callId); 150 if (call != null) { 151 mCallsManager.disconnectCall(call); 152 } else { 153 Log.w(this, "disconnectCall, unknown call id: %s", callId); 154 } 155 } 156 } 157 } finally { 158 Binder.restoreCallingIdentity(token); 159 } 160 } 161 162 @Override holdCall(String callId)163 public void holdCall(String callId) { 164 long token = Binder.clearCallingIdentity(); 165 try { 166 synchronized (mLock) { 167 if (mCallIdMapper.isValidCallId(callId)) { 168 Call call = mCallIdMapper.getCall(callId); 169 if (call != null) { 170 mCallsManager.holdCall(call); 171 } else { 172 Log.w(this, "holdCall, unknown call id: %s", callId); 173 } 174 } 175 } 176 } finally { 177 Binder.restoreCallingIdentity(token); 178 } 179 } 180 181 @Override unholdCall(String callId)182 public void unholdCall(String callId) { 183 long token = Binder.clearCallingIdentity(); 184 try { 185 synchronized (mLock) { 186 if (mCallIdMapper.isValidCallId(callId)) { 187 Call call = mCallIdMapper.getCall(callId); 188 if (call != null) { 189 mCallsManager.unholdCall(call); 190 } else { 191 Log.w(this, "unholdCall, unknown call id: %s", callId); 192 } 193 } 194 } 195 } finally { 196 Binder.restoreCallingIdentity(token); 197 } 198 } 199 200 @Override phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault)201 public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, 202 boolean setDefault) { 203 long token = Binder.clearCallingIdentity(); 204 try { 205 synchronized (mLock) { 206 if (mCallIdMapper.isValidCallId(callId)) { 207 Call call = mCallIdMapper.getCall(callId); 208 if (call != null) { 209 mCallsManager.phoneAccountSelected(call, accountHandle, setDefault); 210 } else { 211 Log.w(this, "phoneAccountSelected, unknown call id: %s", callId); 212 } 213 } 214 } 215 } finally { 216 Binder.restoreCallingIdentity(token); 217 } 218 } 219 220 @Override mute(boolean shouldMute)221 public void mute(boolean shouldMute) { 222 long token = Binder.clearCallingIdentity(); 223 try { 224 synchronized (mLock) { 225 mCallsManager.mute(shouldMute); 226 } 227 } finally { 228 Binder.restoreCallingIdentity(token); 229 } 230 } 231 232 @Override setAudioRoute(int route)233 public void setAudioRoute(int route) { 234 long token = Binder.clearCallingIdentity(); 235 try { 236 synchronized (mLock) { 237 mCallsManager.setAudioRoute(route); 238 } 239 } finally { 240 Binder.restoreCallingIdentity(token); 241 } 242 } 243 244 @Override conference(String callId, String otherCallId)245 public void conference(String callId, String otherCallId) { 246 long token = Binder.clearCallingIdentity(); 247 try { 248 synchronized (mLock) { 249 if (mCallIdMapper.isValidCallId(callId) && 250 mCallIdMapper.isValidCallId(otherCallId)) { 251 Call call = mCallIdMapper.getCall(callId); 252 Call otherCall = mCallIdMapper.getCall(otherCallId); 253 if (call != null && otherCall != null) { 254 mCallsManager.conference(call, otherCall); 255 } else { 256 Log.w(this, "conference, unknown call id: %s or %s", callId, otherCallId); 257 } 258 259 } 260 } 261 } finally { 262 Binder.restoreCallingIdentity(token); 263 } 264 } 265 266 @Override splitFromConference(String callId)267 public void splitFromConference(String callId) { 268 long token = Binder.clearCallingIdentity(); 269 try { 270 synchronized (mLock) { 271 if (mCallIdMapper.isValidCallId(callId)) { 272 Call call = mCallIdMapper.getCall(callId); 273 if (call != null) { 274 call.splitFromConference(); 275 } else { 276 Log.w(this, "splitFromConference, unknown call id: %s", callId); 277 } 278 } 279 } 280 } finally { 281 Binder.restoreCallingIdentity(token); 282 } 283 } 284 285 @Override mergeConference(String callId)286 public void mergeConference(String callId) { 287 long token = Binder.clearCallingIdentity(); 288 try { 289 synchronized (mLock) { 290 if (mCallIdMapper.isValidCallId(callId)) { 291 Call call = mCallIdMapper.getCall(callId); 292 if (call != null) { 293 call.mergeConference(); 294 } else { 295 Log.w(this, "mergeConference, unknown call id: %s", callId); 296 } 297 } 298 } 299 } finally { 300 Binder.restoreCallingIdentity(token); 301 } 302 } 303 304 @Override swapConference(String callId)305 public void swapConference(String callId) { 306 long token = Binder.clearCallingIdentity(); 307 try { 308 synchronized (mLock) { 309 if (mCallIdMapper.isValidCallId(callId)) { 310 Call call = mCallIdMapper.getCall(callId); 311 if (call != null) { 312 call.swapConference(); 313 } else { 314 Log.w(this, "swapConference, unknown call id: %s", callId); 315 } 316 } 317 } 318 } finally { 319 Binder.restoreCallingIdentity(token); 320 } 321 } 322 323 @Override turnOnProximitySensor()324 public void turnOnProximitySensor() { 325 long token = Binder.clearCallingIdentity(); 326 try { 327 synchronized (mLock) { 328 mCallsManager.turnOnProximitySensor(); 329 } 330 } finally { 331 Binder.restoreCallingIdentity(token); 332 } 333 } 334 335 @Override turnOffProximitySensor(boolean screenOnImmediately)336 public void turnOffProximitySensor(boolean screenOnImmediately) { 337 long token = Binder.clearCallingIdentity(); 338 try { 339 synchronized (mLock) { 340 mCallsManager.turnOffProximitySensor(screenOnImmediately); 341 } 342 } finally { 343 Binder.restoreCallingIdentity(token); 344 } 345 } 346 } 347