summaryrefslogtreecommitdiff
path: root/InCallUI/src/com/android/incallui/ExternalCallList.java
blob: 06e0bb975a2cc9cc6680d4e51ea040e968a07e0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package com.android.incallui;

import com.google.common.base.Preconditions;

import com.android.contacts.common.compat.CallSdkCompat;

import android.os.Handler;
import android.os.Looper;
import android.telecom.Call;
import android.util.ArraySet;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Tracks the external calls known to the InCall UI.
 *
 * External calls are those with {@link android.telecom.Call.Details#PROPERTY_IS_EXTERNAL_CALL}.
 */
public class ExternalCallList {

    public interface ExternalCallListener {
        void onExternalCallAdded(Call call);
        void onExternalCallRemoved(Call call);
        void onExternalCallUpdated(Call call);
    }

    /**
     * Handles {@link android.telecom.Call.Callback} callbacks.
     */
    private final Call.Callback mTelecomCallCallback = new Call.Callback() {
        @Override
        public void onDetailsChanged(Call call, Call.Details details) {
            notifyExternalCallUpdated(call);
        }
    };

    private final Set<Call> mExternalCalls = new ArraySet<>();
    private final Set<ExternalCallListener> mExternalCallListeners = Collections.newSetFromMap(
            new ConcurrentHashMap<ExternalCallListener, Boolean>(8, 0.9f, 1));

    /**
     * Begins tracking an external call and notifies listeners of the new call.
     */
    public void onCallAdded(Call telecomCall) {
        Preconditions.checkArgument(telecomCall.getDetails()
                .hasProperty(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL));
        mExternalCalls.add(telecomCall);
        telecomCall.registerCallback(mTelecomCallCallback, new Handler(Looper.getMainLooper()));
        notifyExternalCallAdded(telecomCall);
    }

    /**
     * Stops tracking an external call and notifies listeners of the removal of the call.
     */
    public void onCallRemoved(Call telecomCall) {
        Preconditions.checkArgument(mExternalCalls.contains(telecomCall));
        mExternalCalls.remove(telecomCall);
        telecomCall.unregisterCallback(mTelecomCallCallback);
        notifyExternalCallRemoved(telecomCall);
    }

    /**
     * Adds a new listener to external call events.
     */
    public void addExternalCallListener(ExternalCallListener listener) {
        mExternalCallListeners.add(Preconditions.checkNotNull(listener));
    }

    /**
     * Removes a listener to external call events.
     */
    public void removeExternalCallListener(ExternalCallListener listener) {
        Preconditions.checkArgument(mExternalCallListeners.contains(listener));
        mExternalCallListeners.remove(Preconditions.checkNotNull(listener));
    }

    /**
     * Notifies listeners of the addition of a new external call.
     */
    private void notifyExternalCallAdded(Call call) {
        for (ExternalCallListener listener : mExternalCallListeners) {
            listener.onExternalCallAdded(call);
        }
    }

    /**
     * Notifies listeners of the removal of an external call.
     */
    private void notifyExternalCallRemoved(Call call) {
        for (ExternalCallListener listener : mExternalCallListeners) {
            listener.onExternalCallRemoved(call);
        }
    }

    /**
     * Notifies listeners of changes to an external call.
     */
    private void notifyExternalCallUpdated(Call call) {
        for (ExternalCallListener listener : mExternalCallListeners) {
            listener.onExternalCallUpdated(call);
        }
    }
}