153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon/* 253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * Copyright (C) 2014 The Android Open Source Project 353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * 453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * you may not use this file except in compliance with the License. 653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * You may obtain a copy of the License at 753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * 853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * 1053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * Unless required by applicable law or agreed to in writing, software 1153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 1253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * See the License for the specific language governing permissions and 1453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * limitations under the License. 1553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon */ 1653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 1753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordonpackage com.android.services.telephony; 1853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 194d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneCapabilities; 204d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.Conference; 214d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.Connection; 224d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneAccountHandle; 2353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 2453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordonimport com.android.internal.telephony.Call; 2553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordonimport com.android.internal.telephony.CallStateException; 263197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awadimport com.android.internal.telephony.Phone; 2753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 2853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordonimport java.util.List; 2953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 3053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon/** 3153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * GSM-based conference call. 3253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon */ 3353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordonpublic class GsmConference extends Conference { 3453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 3553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon public GsmConference(PhoneAccountHandle phoneAccount) { 3653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon super(phoneAccount); 3753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon setCapabilities( 3853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon PhoneCapabilities.SUPPORT_HOLD | 3953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon PhoneCapabilities.HOLD | 4053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon PhoneCapabilities.MUTE | 41a956f73382c3aa2619c73b880a11ee1899c2fe18Santos Cordon PhoneCapabilities.MANAGE_CONFERENCE); 4253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon setActive(); 4353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 4453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 4553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon /** 4653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * Invoked when the Conference and all it's {@link Connection}s should be disconnected. 4753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon */ 4853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon @Override 4953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon public void onDisconnect() { 5053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon for (Connection connection : getConnections()) { 5153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon Call call = getMultipartyCallForConnection(connection, "onDisconnect"); 5253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon if (call != null) { 531c25892dc5f0170441422f15242df8887b7903edSantos Cordon Log.d(this, "Found multiparty call to hangup for conference."); 5453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon try { 5553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon call.hangup(); 561c25892dc5f0170441422f15242df8887b7903edSantos Cordon break; 5753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } catch (CallStateException e) { 5853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon Log.e(this, e, "Exception thrown trying to hangup conference"); 5953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 6053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 6153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 6253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 6353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 6453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon /** 6553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * Invoked when the specified {@link Connection} should be separated from the conference call. 6653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * 6753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * @param connection The connection to separate. 6853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon */ 6953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon @Override 7053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon public void onSeparate(Connection connection) { 7153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon com.android.internal.telephony.Connection radioConnection = 7253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon getOriginalConnection(connection, "onSeparate"); 7353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon try { 7453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon radioConnection.separate(); 7553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } catch (CallStateException e) { 7653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon Log.e(this, e, "Exception thrown trying to separate a conference call"); 7753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 7853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 793197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad 803197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad @Override 813197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad public void onMerge(Connection connection) { 823197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad try { 833197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad Phone phone = ((TelephonyConnection) connection).getPhone(); 843197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad if (phone != null) { 853197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad phone.conference(); 863197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad } 873197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad } catch (CallStateException e) { 883197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad Log.e(this, e, "Exception thrown trying to merge call into a conference"); 893197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad } 903197ea821dcdee1c30549f850b99c2cfc7f668cbIhab Awad } 9153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 9253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon /** 9353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * Invoked when the conference should be put on hold. 9453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon */ 9553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon @Override 9653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon public void onHold() { 97293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee final GsmConnection connection = getFirstConnection(); 98293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee if (connection != null) { 99293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee connection.performHold(); 10053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 10153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 10253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 10353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon /** 10453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon * Invoked when the conference should be moved from hold to active. 10553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon */ 10653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon @Override 10753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon public void onUnhold() { 108293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee final GsmConnection connection = getFirstConnection(); 109293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee if (connection != null) { 110293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee connection.performUnhold(); 111293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee } 112293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee } 113293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee 114293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee @Override 115293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee public void onPlayDtmfTone(char c) { 116293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee final GsmConnection connection = getFirstConnection(); 117293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee if (connection != null) { 118293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee connection.onPlayDtmfTone(c); 119293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee } 120293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee } 121293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee 122293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee @Override 123293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee public void onStopDtmfTone() { 124293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee final GsmConnection connection = getFirstConnection(); 125293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee if (connection != null) { 126293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee connection.onStopDtmfTone(); 12753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 12853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 12953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 13053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon private Call getMultipartyCallForConnection(Connection connection, String tag) { 13153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon com.android.internal.telephony.Connection radioConnection = 13253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon getOriginalConnection(connection, tag); 13353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon if (radioConnection != null) { 13453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon Call call = radioConnection.getCall(); 13553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon if (call != null && call.isMultiparty()) { 13653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon return call; 13753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 13853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 13953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon return null; 14053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 14153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 14253b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon private com.android.internal.telephony.Connection getOriginalConnection( 14353b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon Connection connection, String tag) { 14453b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon 14553b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon if (connection instanceof GsmConnection) { 14653b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon return ((GsmConnection) connection).getOriginalConnection(); 14753b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } else { 14853b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon Log.e(this, null, "Non GSM connection found in a Gsm conference (%s)", tag); 14953b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon return null; 15053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 15153b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon } 152293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee 153293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee private GsmConnection getFirstConnection() { 154293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee final List<Connection> connections = getConnections(); 155293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee if (connections.isEmpty()) { 156293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee return null; 157293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee } 158293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee return (GsmConnection) connections.get(0); 159293b7bbbc7fb53fe62cd64a40324e11088153398Yorke Lee } 16053b84fe2dc796ef172d7c0f4b9bdc177cdeb0c0fSantos Cordon} 161