1 package com.android.incallui; 2 3 import com.google.common.base.Preconditions; 4 5 import com.android.contacts.common.compat.CallSdkCompat; 6 7 import android.os.Handler; 8 import android.os.Looper; 9 import android.telecom.Call; 10 import android.util.ArraySet; 11 12 import java.util.Collections; 13 import java.util.Set; 14 import java.util.concurrent.ConcurrentHashMap; 15 16 /** 17 * Tracks the external calls known to the InCall UI. 18 * 19 * External calls are those with {@link android.telecom.Call.Details#PROPERTY_IS_EXTERNAL_CALL}. 20 */ 21 public class ExternalCallList { 22 23 public interface ExternalCallListener { 24 void onExternalCallAdded(Call call); 25 void onExternalCallRemoved(Call call); 26 void onExternalCallUpdated(Call call); 27 } 28 29 /** 30 * Handles {@link android.telecom.Call.Callback} callbacks. 31 */ 32 private final Call.Callback mTelecomCallCallback = new Call.Callback() { 33 @Override 34 public void onDetailsChanged(Call call, Call.Details details) { 35 notifyExternalCallUpdated(call); 36 } 37 }; 38 39 private final Set<Call> mExternalCalls = new ArraySet<>(); 40 private final Set<ExternalCallListener> mExternalCallListeners = Collections.newSetFromMap( 41 new ConcurrentHashMap<ExternalCallListener, Boolean>(8, 0.9f, 1)); 42 43 /** 44 * Begins tracking an external call and notifies listeners of the new call. 45 */ 46 public void onCallAdded(Call telecomCall) { 47 Preconditions.checkArgument(telecomCall.getDetails() 48 .hasProperty(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL)); 49 mExternalCalls.add(telecomCall); 50 telecomCall.registerCallback(mTelecomCallCallback, new Handler(Looper.getMainLooper())); 51 notifyExternalCallAdded(telecomCall); 52 } 53 54 /** 55 * Stops tracking an external call and notifies listeners of the removal of the call. 56 */ 57 public void onCallRemoved(Call telecomCall) { 58 Preconditions.checkArgument(mExternalCalls.contains(telecomCall)); 59 mExternalCalls.remove(telecomCall); 60 telecomCall.unregisterCallback(mTelecomCallCallback); 61 notifyExternalCallRemoved(telecomCall); 62 } 63 64 /** 65 * Adds a new listener to external call events. 66 */ 67 public void addExternalCallListener(ExternalCallListener listener) { 68 mExternalCallListeners.add(Preconditions.checkNotNull(listener)); 69 } 70 71 /** 72 * Removes a listener to external call events. 73 */ 74 public void removeExternalCallListener(ExternalCallListener listener) { 75 Preconditions.checkArgument(mExternalCallListeners.contains(listener)); 76 mExternalCallListeners.remove(Preconditions.checkNotNull(listener)); 77 } 78 79 /** 80 * Notifies listeners of the addition of a new external call. 81 */ 82 private void notifyExternalCallAdded(Call call) { 83 for (ExternalCallListener listener : mExternalCallListeners) { 84 listener.onExternalCallAdded(call); 85 } 86 } 87 88 /** 89 * Notifies listeners of the removal of an external call. 90 */ 91 private void notifyExternalCallRemoved(Call call) { 92 for (ExternalCallListener listener : mExternalCallListeners) { 93 listener.onExternalCallRemoved(call); 94 } 95 } 96 97 /** 98 * Notifies listeners of changes to an external call. 99 */ 100 private void notifyExternalCallUpdated(Call call) { 101 for (ExternalCallListener listener : mExternalCallListeners) { 102 listener.onExternalCallUpdated(call); 103 } 104 } 105 } 106