diff options
5 files changed, 89 insertions, 1 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index b1f3303fc05e..6d03511e6f5f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -7573,6 +7573,7 @@ package android.telephony { public class PhoneStateListener { method public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes); method public void onCallDisconnectCauseChanged(int, int); + method public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo); method public void onPreciseCallStateChanged(android.telephony.PreciseCallState); method public void onPreciseDataConnectionStateChanged(android.telephony.PreciseDataConnectionState); method public void onRadioPowerStateChanged(int); @@ -7580,6 +7581,7 @@ package android.telephony { method public void onVoiceActivationStateChanged(int); field public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000 field public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000 + field public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 134217728; // 0x8000000 field public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800 field public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000 field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000 diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 10b126f17715..2f1510e32311 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -52,6 +52,7 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.ImsReasonInfo; import android.util.LocalLog; import android.util.StatsLog; @@ -227,6 +228,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private int mCallDisconnectCause = DisconnectCause.NOT_VALID; + private List<ImsReasonInfo> mImsReasonInfo = null; + private int mCallPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID; private boolean mCarrierNetworkChangeState = false; @@ -377,6 +380,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCellLocation = new Bundle[numPhones]; mCellInfo = new ArrayList<List<CellInfo>>(); mSrvccState = new int[numPhones]; + mImsReasonInfo = new ArrayList<ImsReasonInfo>(); mPhysicalChannelConfigs = new ArrayList<List<PhysicalChannelConfig>>(); mEmergencyNumberList = new HashMap<>(); for (int i = 0; i < numPhones; i++) { @@ -394,6 +398,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallForwarding[i] = false; mCellLocation[i] = new Bundle(); mCellInfo.add(i, null); + mImsReasonInfo.add(i, null); mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; mPhysicalChannelConfigs.add(i, new ArrayList<PhysicalChannelConfig>()); } @@ -739,6 +744,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } + if ((events & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) { + try { + r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId)); + } catch (RemoteException ex) { + remove(r.binder); + } + } if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { try { r.callback.onPreciseDataConnectionStateChanged( @@ -1591,6 +1603,34 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + public void notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo) { + if (!checkNotifyPermission("notifyImsCallDisconnectCause()")) { + return; + } + int phoneId = SubscriptionManager.getPhoneId(subId); + synchronized (mRecords) { + if (validatePhoneId(phoneId)) { + mImsReasonInfo.set(phoneId, imsReasonInfo); + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) + && idMatch(r.subId, subId, phoneId)) { + try { + if (DBG_LOC) { + log("notifyImsCallDisconnectCause: mImsReasonInfo=" + + imsReasonInfo + " r=" + r); + } + r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId)); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + } + handleRemoveListLocked(); + } + } + public void notifyPreciseDataConnectionFailed(String apnType, String apn, @DataFailCause.FailCause int failCause) { if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { @@ -1627,7 +1667,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { int phoneId = SubscriptionManager.getPhoneId(subId); synchronized (mRecords) { if (validatePhoneId(phoneId)) { - mSrvccState[phoneId] = state; + mSrvccState[phoneId] = state; for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) && @@ -1837,6 +1877,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mDataConnectionState=" + mDataConnectionState[i]); pw.println("mCellLocation=" + mCellLocation[i]); pw.println("mCellInfo=" + mCellInfo.get(i)); + pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i).toString()); pw.decreaseIndent(); } pw.println("mPreciseDataConnectionState=" + mPreciseDataConnectionState); @@ -2126,6 +2167,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); } + if ((events & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); + } + return true; } diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index af324debbd57..fea1b7b08a20 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -28,6 +28,7 @@ import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.ImsReasonInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IPhoneStateListener; @@ -347,6 +348,20 @@ public class PhoneStateListener { @SystemApi public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 0x04000000; + /** + * Listen for IMS call disconnect causes which contains + * {@link android.telephony.ims.ImsReasonInfo} + * + * {@more} + * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE + * READ_PRECISE_PHONE_STATE} + * + * @see #onImsCallDisconnectCauseChanged(ImsReasonInfo) + * @hide + */ + @SystemApi + public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 0x08000000; + /* * Subscription used to listen to the phone state changes * @hide @@ -578,6 +593,17 @@ public class PhoneStateListener { } /** + * Callback invoked when Ims call disconnect cause changes. + * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. + * + * @hide + */ + @SystemApi + public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) { + // default implementation empty + } + + /** * Callback invoked when data connection state changes with precise information. * @param dataConnectionState {@link PreciseDataConnectionState} * @@ -981,6 +1007,16 @@ public class PhoneStateListener { Binder.withCleanCallingIdentity( () -> mExecutor.execute(() -> psl.onPreferredDataSubIdChanged(subId))); } + + public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onImsCallDisconnectCauseChanged(disconnectCause))); + + } } diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index 3dbebe832fac..322ce45797ec 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -27,6 +27,7 @@ import android.telephony.PreciseDataConnectionState; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.ImsReasonInfo; oneway interface IPhoneStateListener { void onServiceStateChanged(in ServiceState serviceState); @@ -58,5 +59,6 @@ oneway interface IPhoneStateListener { void onCallAttributesChanged(in CallAttributes callAttributes); void onEmergencyNumberListChanged(in Map emergencyNumberList); void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause); + void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo); } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 2be1f419db4d..e9eba324acb0 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -22,6 +22,7 @@ import android.net.NetworkCapabilities; import android.os.Bundle; import android.telephony.CallQuality; import android.telephony.CellInfo; +import android.telephony.ims.ImsReasonInfo; import android.telephony.PhoneCapability; import android.telephony.PhysicalChannelConfig; import android.telephony.ServiceState; @@ -84,4 +85,5 @@ interface ITelephonyRegistry { void notifyRadioPowerStateChanged(in int state); void notifyEmergencyNumberList(); void notifyCallQualityChanged(in CallQuality callQuality, int phoneId); + void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo); } |