Home | History | Annotate | Download | only in incallui
      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