196b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon/* 296b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * Copyright (C) 2013 The Android Open Source Project 396b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * 496b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 596b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * you may not use this file except in compliance with the License. 696b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * You may obtain a copy of the License at 796b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * 896b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * http://www.apache.org/licenses/LICENSE-2.0 996b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * 1096b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * Unless required by applicable law or agreed to in writing, software 1196b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 1296b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1396b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * See the License for the specific language governing permissions and 1496b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon * limitations under the License 1596b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon */ 1696b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 1796b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordonpackage com.android.incallui; 1896b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 198b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Chengimport com.google.android.collect.Lists; 2096b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordonimport com.google.android.collect.Maps; 21a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordonimport com.google.android.collect.Sets; 2296b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordonimport com.google.common.base.Preconditions; 23671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon 24a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordonimport android.os.Handler; 25a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordonimport android.os.Message; 26a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 2796b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordonimport com.android.services.telephony.common.Call; 28d7effd30eca546cabb5f1d70858b4038fa4a31c3Santos Cordonimport com.android.services.telephony.common.Call.DisconnectCause; 2996b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 3010196fd2f7cc922693e2a7c6c932725a52157943Christine Chenimport java.util.ArrayList; 3196b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordonimport java.util.HashMap; 3296b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordonimport java.util.List; 33a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordonimport java.util.Set; 3496b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 3596b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon/** 36671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon * Maintains the list of active calls received from CallHandlerService and notifies interested 37671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon * classes of changes to the call list as they are received from the telephony stack. 38671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon * Primary lister of changes to this class is InCallPresenter. 3996b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon */ 4096b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordonpublic class CallList { 41671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon 42ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon private static final int DISCONNECTED_CALL_SHORT_TIMEOUT_MS = 200; 43ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon private static final int DISCONNECTED_CALL_MEDIUM_TIMEOUT_MS = 2000; 44ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon private static final int DISCONNECTED_CALL_LONG_TIMEOUT_MS = 5000; 45a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 46a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon private static final int EVENT_DISCONNECTED_TIMEOUT = 1; 47a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 488b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng private static CallList sInstance = new CallList(); 49a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 50a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon private final HashMap<Integer, Call> mCallMap = Maps.newHashMap(); 5110196fd2f7cc922693e2a7c6c932725a52157943Christine Chen private final HashMap<Integer, ArrayList<String>> mCallTextReponsesMap = 5210196fd2f7cc922693e2a7c6c932725a52157943Christine Chen Maps.newHashMap(); 53a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon private final Set<Listener> mListeners = Sets.newArraySet(); 548b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng private final HashMap<Integer, List<CallUpdateListener>> mCallUpdateListenerMap = Maps 558b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng .newHashMap(); 568b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 57a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 58a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon /** 59a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Static singleton accessor method. 60a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 618b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public static CallList getInstance() { 62a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon return sInstance; 638b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 6496b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 65a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon /** 66a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Private constructor. Instance should only be acquired through getInstance(). 67a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 688b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng private CallList() { 69a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 7096b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 71a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon /** 72a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Called when a single call has changed. 73a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 7496b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon public void onUpdate(Call call) { 751a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "onUpdate - ", call); 76a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 77a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon updateCallInMap(call); 78a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon notifyListenersOfChange(); 79a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 80a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 81a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon /** 82a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * Called when a single call disconnects. 83a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon */ 84a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon public void onDisconnect(Call call) { 851a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "onDisconnect: ", call); 86a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 877fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon boolean updated = updateCallInMap(call); 8810196fd2f7cc922693e2a7c6c932725a52157943Christine Chen 897fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon if (updated) { 907fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon // notify those listening for changes on this specific change 917fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon notifyCallUpdateListeners(call); 927fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon 937fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon // notify those listening for all disconnects 947fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon notifyListenersOfDisconnect(call); 957fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon } 9610196fd2f7cc922693e2a7c6c932725a52157943Christine Chen } 9710196fd2f7cc922693e2a7c6c932725a52157943Christine Chen 9810196fd2f7cc922693e2a7c6c932725a52157943Christine Chen /** 9910196fd2f7cc922693e2a7c6c932725a52157943Christine Chen * Called when a single call has changed. 10010196fd2f7cc922693e2a7c6c932725a52157943Christine Chen */ 1018b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public void onIncoming(Call call, List<String> textMessages) { 1028b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng Log.d(this, "onIncoming - " + call); 10310196fd2f7cc922693e2a7c6c932725a52157943Christine Chen 1048b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng updateCallInMap(call); 1058b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng updateCallTextMap(call, textMessages); 10610196fd2f7cc922693e2a7c6c932725a52157943Christine Chen 1078b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng for (Listener listener : mListeners) { 1088b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng listener.onIncomingCall(call); 1098b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 11096b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon } 11196b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 112a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon /** 113a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Called when multiple calls have changed. 114a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 11596b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon public void onUpdate(List<Call> callsToUpdate) { 1161a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "onUpdate(...)"); 117671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon 11896b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon Preconditions.checkNotNull(callsToUpdate); 11996b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon for (Call call : callsToUpdate) { 1201a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "\t" + call); 121671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon 12296b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon updateCallInMap(call); 12310196fd2f7cc922693e2a7c6c932725a52157943Christine Chen updateCallTextMap(call, null); 1248b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 1258b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng notifyCallUpdateListeners(call); 12696b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon } 127a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 128a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon notifyListenersOfChange(); 129a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 130a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 1318b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public void notifyCallUpdateListeners(Call call) { 1328b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng final List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(call.getCallId()); 1338b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (listeners != null) { 1348b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng for (CallUpdateListener listener : listeners) { 1358b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng listener.onCallStateChanged(call); 1368b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 1378b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 1388b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 1398b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 1408b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng /** 1418b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng * Add a call update listener for a call id. 1428b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng * 1438b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng * @param callId The call id to get updates for. 1448b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng * @param listener The listener to add. 1458b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng */ 1468b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public void addCallUpdateListener(int callId, CallUpdateListener listener) { 1478b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(callId); 1488b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (listeners == null) { 1498b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng listeners = Lists.newArrayList(); 1508b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng mCallUpdateListenerMap.put(callId, listeners); 1518b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 1528b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng listeners.add(listener); 1538b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 1548b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 1558b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng /** 1568b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng * Remove a call update listener for a call id. 1578b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng * 1588b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng * @param callId The call id to remove the listener for. 1598b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng * @param listener The listener to remove. 1608b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng */ 1618b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public void removeCallUpdateListener(int callId, CallUpdateListener listener) { 1628b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(callId); 1638b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (listeners != null) { 1648b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng listeners.remove(listener); 1658b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 1668b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 1678b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 168a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon public void addListener(Listener listener) { 169a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon Preconditions.checkNotNull(listener); 170150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon 171a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon mListeners.add(listener); 172150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon 173150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon // Let the listener know about the active calls immediately. 174150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon listener.onCallListChange(this); 175a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 176a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 177a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon public void removeListener(Listener listener) { 178a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon Preconditions.checkNotNull(listener); 179a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon mListeners.remove(listener); 180a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 181a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 182a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon /** 183e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon * TODO: Change so that this function is not needed. Instead of assuming there is an active 184a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * call, the code should rely on the status of a specific Call and allow the presenters to 185a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * update the Call object when the active call changes. 186a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 187a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon public Call getIncomingOrActive() { 188150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon Call retval = getIncomingCall(); 189150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon if (retval == null) { 190671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon retval = getActiveCall(); 191150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon } 192150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon return retval; 193150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon } 194150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon 195e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon public Call getOutgoingCall() { 196672b16d0620d033e10fab30ccd70f5dd23e823b7Santos Cordon Call call = getFirstCallWithState(Call.State.DIALING); 197672b16d0620d033e10fab30ccd70f5dd23e823b7Santos Cordon if (call == null) { 198672b16d0620d033e10fab30ccd70f5dd23e823b7Santos Cordon call = getFirstCallWithState(Call.State.REDIALING); 199672b16d0620d033e10fab30ccd70f5dd23e823b7Santos Cordon } 200672b16d0620d033e10fab30ccd70f5dd23e823b7Santos Cordon return call; 201e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon } 202e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon 203671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon public Call getActiveCall() { 204671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon return getFirstCallWithState(Call.State.ACTIVE); 205671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon } 206671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon 207150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon public Call getBackgroundCall() { 208150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon return getFirstCallWithState(Call.State.ONHOLD); 209150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon } 210150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon 211a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon public Call getDisconnectedCall() { 212a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon return getFirstCallWithState(Call.State.DISCONNECTED); 213a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 214a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 215ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen public Call getDisconnectingCall() { 216ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen return getFirstCallWithState(Call.State.DISCONNECTING); 217ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen } 218ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen 219efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon public Call getSecondBackgroundCall() { 220efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon return getCallWithState(Call.State.ONHOLD, 1); 221efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon } 222efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon 223efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon public Call getActiveOrBackgroundCall() { 224efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon Call call = getActiveCall(); 225efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon if (call == null) { 226efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon call = getBackgroundCall(); 227efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon } 228efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon return call; 229efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon } 230efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon 231150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon public Call getIncomingCall() { 232efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon Call call = getFirstCallWithState(Call.State.INCOMING); 233efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon if (call == null) { 234efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon call = getFirstCallWithState(Call.State.CALL_WAITING); 235efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon } 236efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon 237efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon return call; 238150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon } 239a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 2408b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public Call getFirstCall() { 2418b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng Call result = getIncomingCall(); 2428b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (result == null) { 243672b16d0620d033e10fab30ccd70f5dd23e823b7Santos Cordon result = getOutgoingCall(); 2448b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 2458b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (result == null) { 2468b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng result = getFirstCallWithState(Call.State.ACTIVE); 2478b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 2487fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon if (result == null) { 2497fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon result = getDisconnectingCall(); 2507fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon } 2517fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon if (result == null) { 2527fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon result = getDisconnectedCall(); 2537fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon } 2548b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng return result; 2558b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 2568b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 25714dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon public Call getCall(int callId) { 25814dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon return mCallMap.get(callId); 25914dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon } 26014dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon 261150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon public boolean existsLiveCall() { 262a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon for (Call call : mCallMap.values()) { 263150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon if (!isCallDead(call)) { 264150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon return true; 265150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon } 266150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon } 267150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon return false; 268150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon } 269150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon 2708b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public ArrayList<String> getTextResponses(int callId) { 2718b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng return mCallTextReponsesMap.get(callId); 27210196fd2f7cc922693e2a7c6c932725a52157943Christine Chen } 27310196fd2f7cc922693e2a7c6c932725a52157943Christine Chen 274150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon /** 275150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon * Returns first call found in the call map with the specified state. 276150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon */ 277150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon public Call getFirstCallWithState(int state) { 278efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon return getCallWithState(state, 0); 279efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon } 280efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon 281efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon /** 282efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon * Returns the [position]th call found in the call map with the specified state. 283046386ed5ae615c8d83bb5a9eccc15e5f79b61ccChristine Chen * TODO: Improve this logic to sort by call time. 284efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon */ 285efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon public Call getCallWithState(int state, int positionToFind) { 286150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon Call retval = null; 287efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon int position = 0; 288150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon for (Call call : mCallMap.values()) { 289150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon if (call.getState() == state) { 290efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon if (position >= positionToFind) { 291efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon retval = call; 292efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon break; 293efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon } else { 294efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon position++; 295efd4282ec4221ec5eefd4155a4ad915adcedca70Santos Cordon } 296a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 297a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 298a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 299a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon return retval; 300a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 301a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 302a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon /** 3033c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon * This is called when the service disconnects, either expectedly or unexpectedly. 3043c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon * For the expected case, it's because we have no calls left. For the unexpected case, 3053c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon * it is likely a crash of phone and we need to clean up our calls manually. Without phone, 3063c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon * there can be no active calls, so this is relatively safe thing to do. 3073c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon */ 3083c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon public void clearOnDisconnect() { 3093c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon for (Call call : mCallMap.values()) { 3103c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon final int state = call.getState(); 3113c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon if (state != Call.State.IDLE && 3123c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon state != Call.State.INVALID && 3133c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon state != Call.State.DISCONNECTED) { 314d7effd30eca546cabb5f1d70858b4038fa4a31c3Santos Cordon 3153c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon call.setState(Call.State.DISCONNECTED); 316d7effd30eca546cabb5f1d70858b4038fa4a31c3Santos Cordon call.setDisconnectCause(DisconnectCause.UNKNOWN); 3173c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon updateCallInMap(call); 3183c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon } 3193c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon } 3203c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon notifyListenersOfChange(); 3213c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon } 3223c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon 3233c5581a67ba89fd96fc19e64f6c4780d0a58f640Santos Cordon /** 324a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Sends a generic notification to all listeners that something has changed. 325a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * It is up to the listeners to call back to determine what changed. 326a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 327a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon private void notifyListenersOfChange() { 328a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon for (Listener listener : mListeners) { 329a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon listener.onCallListChange(this); 330a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 33196b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon } 33296b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 3337fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon private void notifyListenersOfDisconnect(Call call) { 3347fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon for (Listener listener : mListeners) { 3357fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon listener.onDisconnect(call); 3367fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon } 3377fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon } 3387fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon 3397fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon /** 3407fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * Updates the call entry in the local map. 3417fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * @return false if no call previously existed and no call was added, otherwise true. 3427fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon */ 3437fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon private boolean updateCallInMap(Call call) { 34496b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon Preconditions.checkNotNull(call); 34596b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 3467fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon boolean updated = false; 3477fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon 34896b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon final Integer id = new Integer(call.getCallId()); 34996b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 350a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon if (call.getState() == Call.State.DISCONNECTED) { 3511df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // update existing (but do not add!!) disconnected calls 3521df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon if (mCallMap.containsKey(id)) { 353a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 3541df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // For disconnected calls, we want to keep them alive for a few seconds so that the 3551df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // UI has a chance to display anything it needs when a call is disconnected. 3561df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon 3571df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // Set up a timer to destroy the call after X seconds. 3581df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon final Message msg = mHandler.obtainMessage(EVENT_DISCONNECTED_TIMEOUT, call); 359ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon mHandler.sendMessageDelayed(msg, getDelayForDisconnect(call)); 360a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 361a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon mCallMap.put(id, call); 3627fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon updated = true; 363a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 364a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } else if (!isCallDead(call)) { 365a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon mCallMap.put(id, call); 3667fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon updated = true; 367a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } else if (mCallMap.containsKey(id)) { 368a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon mCallMap.remove(id); 3697fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon updated = true; 37096b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon } 3717fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon 3727fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon return updated; 37396b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon } 37496b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon 375ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon private int getDelayForDisconnect(Call call) { 376ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon Preconditions.checkState(call.getState() == Call.State.DISCONNECTED); 377ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon 378ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon 379ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon final Call.DisconnectCause cause = call.getDisconnectCause(); 380ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon final int delay; 381ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon switch (cause) { 382ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon case LOCAL: 383ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon delay = DISCONNECTED_CALL_SHORT_TIMEOUT_MS; 384ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon break; 385ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon case NORMAL: 386d7effd30eca546cabb5f1d70858b4038fa4a31c3Santos Cordon case UNKNOWN: 387ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon delay = DISCONNECTED_CALL_MEDIUM_TIMEOUT_MS; 388ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon break; 389ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon case INCOMING_REJECTED: 390ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon case INCOMING_MISSED: 391ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon // no delay for missed/rejected incoming calls 392ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon delay = 0; 393ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon break; 394ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon default: 395ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon delay = DISCONNECTED_CALL_LONG_TIMEOUT_MS; 396ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon break; 397ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon } 398ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon 399ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon return delay; 400ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon } 401ea83891eb10811d5020cc5fdaf34b711012dab32Santos Cordon 40210196fd2f7cc922693e2a7c6c932725a52157943Christine Chen private void updateCallTextMap(Call call, List<String> textResponses) { 40310196fd2f7cc922693e2a7c6c932725a52157943Christine Chen Preconditions.checkNotNull(call); 40410196fd2f7cc922693e2a7c6c932725a52157943Christine Chen 40510196fd2f7cc922693e2a7c6c932725a52157943Christine Chen final Integer id = new Integer(call.getCallId()); 40610196fd2f7cc922693e2a7c6c932725a52157943Christine Chen 40710196fd2f7cc922693e2a7c6c932725a52157943Christine Chen if (!isCallDead(call)) { 40810196fd2f7cc922693e2a7c6c932725a52157943Christine Chen if (textResponses != null) { 40910196fd2f7cc922693e2a7c6c932725a52157943Christine Chen mCallTextReponsesMap.put(id, (ArrayList<String>) textResponses); 41010196fd2f7cc922693e2a7c6c932725a52157943Christine Chen } 41110196fd2f7cc922693e2a7c6c932725a52157943Christine Chen } else if (mCallMap.containsKey(id)) { 41210196fd2f7cc922693e2a7c6c932725a52157943Christine Chen mCallTextReponsesMap.remove(id); 41310196fd2f7cc922693e2a7c6c932725a52157943Christine Chen } 41410196fd2f7cc922693e2a7c6c932725a52157943Christine Chen } 41510196fd2f7cc922693e2a7c6c932725a52157943Christine Chen 416a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon private boolean isCallDead(Call call) { 41796b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon final int state = call.getState(); 418a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon return Call.State.IDLE == state || Call.State.INVALID == state; 419a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 420a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 421671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon /** 422a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * Sets up a call for deletion and notifies listeners of change. 423a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon */ 424a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon private void finishDisconnectedCall(Call call) { 425a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon call.setState(Call.State.IDLE); 426a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon updateCallInMap(call); 427a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon notifyListenersOfChange(); 428a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 429a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 430a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon /** 431a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * Handles the timeout for destroying disconnected calls. 432a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon */ 433a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon private Handler mHandler = new Handler() { 434a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon @Override 435a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon public void handleMessage(Message msg) { 436a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon switch (msg.what) { 437a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon case EVENT_DISCONNECTED_TIMEOUT: 4381a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "EVENT_DISCONNECTED_TIMEOUT ", msg.obj); 439a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon finishDisconnectedCall((Call) msg.obj); 440a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon break; 441a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon default: 4421a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.wtf(this, "Message not expected: " + msg.what); 443a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon break; 444a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 445a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 446a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon }; 447a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 448a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon /** 449a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Listener interface for any class that wants to be notified of changes 450a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * to the call list. 451a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 452a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon public interface Listener { 4537fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon /** 4547fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * Called when a new incoming call comes in. 4557fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * This is the only method that gets called for incoming calls. Listeners 4567fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * that want to perform an action on incoming call should respond in this method 4577fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * because {@link #onCallListChange} does not automatically get called for 4587fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * incoming calls. 4597fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon */ 4608b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public void onIncomingCall(Call call); 4617fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon 4627fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon /** 4637fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * Called anytime there are changes to the call list. The change can be switching call 4647fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * states, updating information, etc. This method will NOT be called for new incoming 4657fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * calls and for calls that switch to disconnected state. Listeners must add actions 4667fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * to those method implementations if they want to deal with those actions. 4677fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon */ 4687fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon public void onCallListChange(CallList callList); 4697fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon 4707fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon /** 4717fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * Called when a call switches to the disconnected state. This is the only method 4727fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon * that will get called upon disconnection. 4737fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon */ 4747fff6a25f65e0949c8e2682d6470cf065e76a63fSantos Cordon public void onDisconnect(Call call); 4758b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 4768b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 4778b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public interface CallUpdateListener { 4788b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // TODO: refactor and limit arg to be call state. Caller info is not needed. 4798b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng public void onCallStateChanged(Call call); 48096b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon } 48196b8ba57ac2399336478ffa7a2ccc9423bda0a52Santos Cordon} 482