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.incallui; 18 19 import com.google.common.base.Preconditions; 20 21 import android.content.ActivityNotFoundException; 22 import android.content.Intent; 23 import android.os.Looper; 24 import android.telecom.InCallService; 25 import android.telecom.PhoneAccountHandle; 26 27 import java.util.List; 28 29 final class TelecomAdapter implements InCallServiceListener { 30 private static final String ADD_CALL_MODE_KEY = "add_call_mode"; 31 32 private static TelecomAdapter sInstance; 33 private InCallService mInCallService; 34 getInstance()35 static TelecomAdapter getInstance() { 36 Preconditions.checkState(Looper.getMainLooper().getThread() == Thread.currentThread()); 37 if (sInstance == null) { 38 sInstance = new TelecomAdapter(); 39 } 40 return sInstance; 41 } 42 TelecomAdapter()43 private TelecomAdapter() { 44 } 45 46 @Override setInCallService(InCallService inCallService)47 public void setInCallService(InCallService inCallService) { 48 mInCallService = inCallService; 49 } 50 51 @Override clearInCallService()52 public void clearInCallService() { 53 mInCallService = null; 54 } 55 getTelecomCallById(String callId)56 private android.telecom.Call getTelecomCallById(String callId) { 57 Call call = CallList.getInstance().getCallById(callId); 58 return call == null ? null : call.getTelecomCall(); 59 } 60 answerCall(String callId, int videoState)61 void answerCall(String callId, int videoState) { 62 android.telecom.Call call = getTelecomCallById(callId); 63 if (call != null) { 64 call.answer(videoState); 65 } else { 66 Log.e(this, "error answerCall, call not in call list: " + callId); 67 } 68 } 69 rejectCall(String callId, boolean rejectWithMessage, String message)70 void rejectCall(String callId, boolean rejectWithMessage, String message) { 71 android.telecom.Call call = getTelecomCallById(callId); 72 if (call != null) { 73 call.reject(rejectWithMessage, message); 74 } else { 75 Log.e(this, "error rejectCall, call not in call list: " + callId); 76 } 77 } 78 disconnectCall(String callId)79 void disconnectCall(String callId) { 80 android.telecom.Call call = getTelecomCallById(callId); 81 if (call != null) { 82 call.disconnect(); 83 } else { 84 Log.e(this, "error disconnectCall, call not in call list " + callId); 85 } 86 } 87 holdCall(String callId)88 void holdCall(String callId) { 89 android.telecom.Call call = getTelecomCallById(callId); 90 if (call != null) { 91 call.hold(); 92 } else { 93 Log.e(this, "error holdCall, call not in call list " + callId); 94 } 95 } 96 unholdCall(String callId)97 void unholdCall(String callId) { 98 android.telecom.Call call = getTelecomCallById(callId); 99 if (call != null) { 100 call.unhold(); 101 } else { 102 Log.e(this, "error unholdCall, call not in call list " + callId); 103 } 104 } 105 mute(boolean shouldMute)106 void mute(boolean shouldMute) { 107 if (mInCallService != null) { 108 mInCallService.setMuted(shouldMute); 109 } else { 110 Log.e(this, "error mute, mInCallService is null"); 111 } 112 } 113 setAudioRoute(int route)114 void setAudioRoute(int route) { 115 if (mInCallService != null) { 116 mInCallService.setAudioRoute(route); 117 } else { 118 Log.e(this, "error setAudioRoute, mInCallService is null"); 119 } 120 } 121 separateCall(String callId)122 void separateCall(String callId) { 123 android.telecom.Call call = getTelecomCallById(callId); 124 if (call != null) { 125 call.splitFromConference(); 126 } else { 127 Log.e(this, "error separateCall, call not in call list " + callId); 128 } 129 } 130 merge(String callId)131 void merge(String callId) { 132 android.telecom.Call call = getTelecomCallById(callId); 133 if (call != null) { 134 List<android.telecom.Call> conferenceable = call.getConferenceableCalls(); 135 if (!conferenceable.isEmpty()) { 136 call.conference(conferenceable.get(0)); 137 } else { 138 if (call.getDetails().can(android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE)) { 139 call.mergeConference(); 140 } 141 } 142 } else { 143 Log.e(this, "error merge, call not in call list " + callId); 144 } 145 } 146 swap(String callId)147 void swap(String callId) { 148 android.telecom.Call call = getTelecomCallById(callId); 149 if (call != null) { 150 if (call.getDetails().can(android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE)) { 151 call.swapConference(); 152 } 153 } else { 154 Log.e(this, "error swap, call not in call list " + callId); 155 } 156 } 157 addCall()158 void addCall() { 159 if (mInCallService != null) { 160 Intent intent = new Intent(Intent.ACTION_DIAL); 161 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 162 163 // when we request the dialer come up, we also want to inform 164 // it that we're going through the "add call" option from the 165 // InCallScreen / PhoneUtils. 166 intent.putExtra(ADD_CALL_MODE_KEY, true); 167 try { 168 Log.d(this, "Sending the add Call intent"); 169 mInCallService.startActivity(intent); 170 } catch (ActivityNotFoundException e) { 171 // This is rather rare but possible. 172 // Note: this method is used even when the phone is encrypted. At that moment 173 // the system may not find any Activity which can accept this Intent. 174 Log.e(this, "Activity for adding calls isn't found.", e); 175 } 176 } 177 } 178 playDtmfTone(String callId, char digit)179 void playDtmfTone(String callId, char digit) { 180 android.telecom.Call call = getTelecomCallById(callId); 181 if (call != null) { 182 call.playDtmfTone(digit); 183 } else { 184 Log.e(this, "error playDtmfTone, call not in call list " + callId); 185 } 186 } 187 stopDtmfTone(String callId)188 void stopDtmfTone(String callId) { 189 android.telecom.Call call = getTelecomCallById(callId); 190 if (call != null) { 191 call.stopDtmfTone(); 192 } else { 193 Log.e(this, "error stopDtmfTone, call not in call list " + callId); 194 } 195 } 196 postDialContinue(String callId, boolean proceed)197 void postDialContinue(String callId, boolean proceed) { 198 android.telecom.Call call = getTelecomCallById(callId); 199 if (call != null) { 200 call.postDialContinue(proceed); 201 } else { 202 Log.e(this, "error postDialContinue, call not in call list " + callId); 203 } 204 } 205 phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault)206 void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault) { 207 if (accountHandle == null) { 208 Log.e(this, "error phoneAccountSelected, accountHandle is null"); 209 // TODO: Do we really want to send null accountHandle? 210 } 211 212 android.telecom.Call call = getTelecomCallById(callId); 213 if (call != null) { 214 call.phoneAccountSelected(accountHandle, setDefault); 215 } else { 216 Log.e(this, "error phoneAccountSelected, call not in call list " + callId); 217 } 218 } 219 canAddCall()220 boolean canAddCall() { 221 if (mInCallService != null) { 222 return mInCallService.canAddCall(); 223 } 224 return false; 225 } 226 } 227