1810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal/* 2810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * Copyright (C) 2014 The Android Open Source Project 3810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * 4810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * Licensed under the Apache License, Version 2.0 (the "License"); 5810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * you may not use this file except in compliance with the License. 6810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * You may obtain a copy of the License at 7810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * 8810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * http://www.apache.org/licenses/LICENSE-2.0 9810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * 10810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * Unless required by applicable law or agreed to in writing, software 11810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * distributed under the License is distributed on an "AS IS" BASIS, 12810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * See the License for the specific language governing permissions and 14810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * limitations under the License. 15810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal */ 16810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnpackage com.android.server.telecom; 18810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 19e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Leeimport android.os.RemoteException; 20e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Leeimport android.os.ServiceManager; 21810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepalimport android.telephony.TelephonyManager; 22810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 23e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Leeimport com.android.internal.telephony.ITelephonyRegistry; 24e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee 25810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal/** 26810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * Send a {@link TelephonyManager#ACTION_PHONE_STATE_CHANGED} broadcast when the call state 27810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * changes. 28810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal */ 29810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepalfinal class PhoneStateBroadcaster extends CallsManagerListenerBase { 30e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee 318de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad private final CallsManager mCallsManager; 32e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee private final ITelephonyRegistry mRegistry; 33e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee private int mCurrentState = TelephonyManager.CALL_STATE_IDLE; 34e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee 358de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad public PhoneStateBroadcaster(CallsManager callsManager) { 368de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad mCallsManager = callsManager; 37e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( 38e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee "telephony.registry")); 39e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee if (mRegistry == null) { 40e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee Log.w(this, "TelephonyRegistry is null"); 41e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee } 42e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee } 43e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee 44810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal @Override 456fb37c87836b5245046bd3b14320823ab839a10cIhab Awad public void onCallStateChanged(Call call, int oldState, int newState) { 46f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn if (call.isExternalCall()) { 47f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn return; 48f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn } 49880b98372368b1d2be2ed34edaeb1e2f338d121aSantos Cordon updateStates(call); 50810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal } 51810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 52e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee @Override 53e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee public void onCallAdded(Call call) { 541a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn if (call.isExternalCall()) { 551a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn return; 561a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn } 57880b98372368b1d2be2ed34edaeb1e2f338d121aSantos Cordon updateStates(call); 58880b98372368b1d2be2ed34edaeb1e2f338d121aSantos Cordon } 59810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 60e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee @Override 61e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee public void onCallRemoved(Call call) { 621a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn if (call.isExternalCall()) { 631a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn return; 641a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn } 651a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn updateStates(call); 661a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn } 671a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn 681a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn /** 691a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn * Handles changes to a call's external property. If the call becomes external, we end up 701a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn * updating the call state to idle. If the call becomes non-external, then the call state can 711a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn * update to off hook. 721a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn * 731a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn * @param call The call. 741a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn * @param isExternalCall {@code True} if the call is external, {@code false} otherwise. 751a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn */ 761a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn @Override 771a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn public void onExternalCallChanged(Call call, boolean isExternalCall) { 78880b98372368b1d2be2ed34edaeb1e2f338d121aSantos Cordon updateStates(call); 79880b98372368b1d2be2ed34edaeb1e2f338d121aSantos Cordon } 80880b98372368b1d2be2ed34edaeb1e2f338d121aSantos Cordon 81880b98372368b1d2be2ed34edaeb1e2f338d121aSantos Cordon private void updateStates(Call call) { 82677e811379dba9b0cce2230b770697d474ed8e56Yorke Lee // Recalculate the current phone state based on the consolidated state of the remaining 83677e811379dba9b0cce2230b770697d474ed8e56Yorke Lee // calls in the call list. 841a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn // Note: CallsManager#hasRingingCall() and CallsManager#getFirstCallWithState(..) do not 851a40c4f4daf2cdfba3f67383c726f93b85a98b00Tyler Gunn // consider external calls, so an external call is going to cause the state to be idle. 86677e811379dba9b0cce2230b770697d474ed8e56Yorke Lee int callState = TelephonyManager.CALL_STATE_IDLE; 878de76915ea2772faeb41705aaaeb65f5b3478ac4Ihab Awad if (mCallsManager.hasRingingCall()) { 88677e811379dba9b0cce2230b770697d474ed8e56Yorke Lee callState = TelephonyManager.CALL_STATE_RINGING; 891e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn } else if (mCallsManager.getFirstCallWithState(CallState.DIALING, CallState.PULLING, 901e37be5dd86a51b90e461f09dc8a89effe4aee21Tyler Gunn CallState.ACTIVE, CallState.ON_HOLD) != null) { 91677e811379dba9b0cce2230b770697d474ed8e56Yorke Lee callState = TelephonyManager.CALL_STATE_OFFHOOK; 92e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee } 93677e811379dba9b0cce2230b770697d474ed8e56Yorke Lee sendPhoneStateChangedBroadcast(call, callState); 94e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee } 95810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 96f86db2e63ec71781ac8214ed6d2603d02266143dYorke Lee int getCallState() { 97f86db2e63ec71781ac8214ed6d2603d02266143dYorke Lee return mCurrentState; 98f86db2e63ec71781ac8214ed6d2603d02266143dYorke Lee } 99f86db2e63ec71781ac8214ed6d2603d02266143dYorke Lee 100e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee private void sendPhoneStateChangedBroadcast(Call call, int phoneState) { 101e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee if (phoneState == mCurrentState) { 102e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee return; 10312de5495028142b15c5e25508c77ff4506e29b57Ihab Awad } 104810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 105e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee mCurrentState = phoneState; 106e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee 107e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee String callHandle = null; 108e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee if (call.getHandle() != null) { 109e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee callHandle = call.getHandle().getSchemeSpecificPart(); 110810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal } 11153fb8c103ab542608e0225eae1edfdf43bfa2273Sailesh Nepal 112e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee try { 113e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee if (mRegistry != null) { 114e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee mRegistry.notifyCallState(phoneState, callHandle); 115e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee Log.i(this, "Broadcasted state change: %s", mCurrentState); 11653fb8c103ab542608e0225eae1edfdf43bfa2273Sailesh Nepal } 117e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee } catch (RemoteException e) { 118e19d33e309b1024261c085ddc1ee1e438442bb14Yorke Lee Log.w(this, "RemoteException when notifying TelephonyRegistry of call state change."); 11953fb8c103ab542608e0225eae1edfdf43bfa2273Sailesh Nepal } 120810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal } 121810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal} 122