1a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon/*
2a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * Copyright (C) 2014 The Android Open Source Project
3a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon *
4a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
5a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * you may not use this file except in compliance with the License.
6a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * You may obtain a copy of the License at
7a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon *
8a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
9a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon *
10a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * Unless required by applicable law or agreed to in writing, software
11a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
12a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * See the License for the specific language governing permissions and
14a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * limitations under the License.
15a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon */
16a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
17a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonpackage com.android.services.telephony;
18a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
194d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.Conference;
204d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.Connection;
214d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneAccountHandle;
224d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneCapabilities;
23a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
24a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonimport com.android.internal.telephony.Call;
25a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonimport com.android.internal.telephony.CallStateException;
26a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
27a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonimport java.util.List;
28a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
29a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon/**
30a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon * CDMA-based conference call.
31a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon */
32a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordonpublic class CdmaConference extends Conference {
33a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
34154063ca9072731712af0e9d5200939e56ff37a7Nancy Chen    private int mCapabilities = PhoneCapabilities.MUTE;
35a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
36154063ca9072731712af0e9d5200939e56ff37a7Nancy Chen    public CdmaConference(PhoneAccountHandle phoneAccount, int capabilities) {
37a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        super(phoneAccount);
38154063ca9072731712af0e9d5200939e56ff37a7Nancy Chen        setCapabilities(mCapabilities | capabilities);
39a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        setActive();
40a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
41a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
42a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private void updateCapabilities() {
43a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        setCapabilities(mCapabilities);
44a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
45a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    /**
46a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     * Invoked when the Conference and all it's {@link Connection}s should be disconnected.
47a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     */
48a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
49a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    public void onDisconnect() {
50a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Call call = getOriginalCall();
51a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (call != null) {
52a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            Log.d(this, "Found multiparty call to hangup for conference.");
53a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            try {
54a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                call.hangup();
55a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            } catch (CallStateException e) {
56a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                Log.e(this, e, "Exception thrown trying to hangup conference");
57a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            }
58a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
59a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
60a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
61a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
62a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    public void onSeparate(Connection connection) {
63a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Log.e(this, new Exception(), "Separate not supported for CDMA conference call.");
64a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
65a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
66a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
67a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    public void onHold() {
68a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Log.e(this, new Exception(), "Hold not supported for CDMA conference call.");
69a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
70a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
71a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    /**
72a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     * Invoked when the conference should be moved from hold to active.
73a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon     */
74a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
75a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    public void onUnhold() {
76a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Log.e(this, new Exception(), "Unhold not supported for CDMA conference call.");
77a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
78a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
79a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
80a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    public void onMerge() {
81a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Log.i(this, "Merging CDMA conference call.");
82a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        // Can only merge once
83a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        mCapabilities &= ~PhoneCapabilities.MERGE_CONFERENCE;
84a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        // Once merged, swap is enabled.
85a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        mCapabilities |= PhoneCapabilities.SWAP_CONFERENCE;
86a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        updateCapabilities();
87a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        sendFlash();
88a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
89a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
90a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    @Override
91293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee    public void onPlayDtmfTone(char c) {
92293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        final CdmaConnection connection = getFirstConnection();
93293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        if (connection != null) {
94293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee            connection.onPlayDtmfTone(c);
95293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        } else {
96293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee            Log.w(this, "No CDMA connection found while trying to play dtmf tone.");
97293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        }
98293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee    }
99293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee
100293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee    @Override
101293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee    public void onStopDtmfTone() {
102293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        final CdmaConnection connection = getFirstConnection();
103293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        if (connection != null) {
104293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee            connection.onStopDtmfTone();
105293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        } else {
106293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee            Log.w(this, "No CDMA connection found while trying to stop dtmf tone.");
107293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        }
108293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee    }
109293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee
110293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee    @Override
111a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    public void onSwap() {
112a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Log.i(this, "Swapping CDMA conference call.");
113a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        sendFlash();
114a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
115a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
116a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private void sendFlash() {
117a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        Call call = getOriginalCall();
118a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (call != null) {
119a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            try {
120a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                // For CDMA calls, this just sends a flash command.
121a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                call.getPhone().switchHoldingAndActive();
122a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            } catch (CallStateException e) {
123a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                Log.e(this, e, "Error while trying to send flash command.");
124a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            }
125a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
126a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
127a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
128a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private Call getMultipartyCallForConnection(Connection connection) {
129a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        com.android.internal.telephony.Connection radioConnection =
130a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                getOriginalConnection(connection);
131a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (radioConnection != null) {
132a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            Call call = radioConnection.getCall();
133a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            if (call != null && call.isMultiparty()) {
134a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                return call;
135a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            }
136a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
137a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        return null;
138a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
139a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
140a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private Call getOriginalCall() {
141a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        List<Connection> connections = getConnections();
142a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (!connections.isEmpty()) {
143a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            com.android.internal.telephony.Connection originalConnection =
144a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                    getOriginalConnection(connections.get(0));
145a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            if (originalConnection != null) {
146a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon                return originalConnection.getCall();
147a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            }
148a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
149a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        return null;
150a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
151a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon
152a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    private com.android.internal.telephony.Connection getOriginalConnection(Connection connection) {
153a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        if (connection instanceof CdmaConnection) {
154a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            return ((CdmaConnection) connection).getOriginalConnection();
155a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        } else {
156a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            Log.e(this, null, "Non CDMA connection found in a CDMA conference");
157a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon            return null;
158a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon        }
159a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon    }
160293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee
161293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee    private CdmaConnection getFirstConnection() {
162293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        final List<Connection> connections = getConnections();
163293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        if (connections.isEmpty()) {
164293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee            return null;
165293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        }
166293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee        return (CdmaConnection) connections.get(0);
167293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee    }
168a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon}
169