diff options
| author | 2018-10-26 10:25:57 -0700 | |
|---|---|---|
| committer | 2018-11-08 10:14:04 -0800 | |
| commit | efed9824e4ae5c1dced700f13a16abbbd1a293b2 (patch) | |
| tree | 3b2a18b963d723c2448690edf5c57be1e588db25 | |
| parent | 3ef1990e7ce45b27194c886af594b5de25a7d091 (diff) | |
Expose SRVCC state changes as @SystemAPI
ImsService needs to be able to register for SRVCC state
changes.
Test: Telephony Unit tests
Bug: 117555643
Change-Id: I87631b51a19cdd46d6b4d15f3631345de03bb771
7 files changed, 118 insertions, 33 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 0f172a33453c..83584f689cc5 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5160,7 +5160,9 @@ package android.telephony { public class PhoneStateListener { method public void onRadioPowerStateChanged(int); + method public void onSrvccStateChanged(int); field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000 + field public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000 } public class ServiceState implements android.os.Parcelable { @@ -5389,6 +5391,11 @@ package android.telephony { field public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; // 0x0 field public static final int SIM_STATE_LOADED = 10; // 0xa field public static final int SIM_STATE_PRESENT = 11; // 0xb + field public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; // 0x3 + field public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; // 0x1 + field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2 + field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff + field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0 } public final class UiccAccessRule implements android.os.Parcelable { diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index e410302457a8..4bfcd25c56db 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -47,7 +47,6 @@ import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.telephony.VoLteServiceState; import android.util.LocalLog; import android.util.StatsLog; @@ -196,7 +195,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private ArrayList<List<PhysicalChannelConfig>> mPhysicalChannelConfigs; - private VoLteServiceState mVoLteServiceState = new VoLteServiceState(); + private int[] mSrvccState; private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -230,8 +229,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { static final int ENFORCE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | - PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR | - PhoneStateListener.LISTEN_VOLTE_STATE; + PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR; static final int PRECISE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_PRECISE_CALL_STATE | @@ -356,6 +354,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallForwarding = new boolean[numPhones]; mCellLocation = new Bundle[numPhones]; mCellInfo = new ArrayList<List<CellInfo>>(); + mSrvccState = new int[numPhones]; mPhysicalChannelConfigs = new ArrayList<List<PhysicalChannelConfig>>(); for (int i = 0; i < numPhones; i++) { mCallState[i] = TelephonyManager.CALL_STATE_IDLE; @@ -371,6 +370,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallForwarding[i] = false; mCellLocation[i] = new Bundle(); mCellInfo.add(i, null); + mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; mPhysicalChannelConfigs.add(i, new ArrayList<PhysicalChannelConfig>()); } @@ -772,6 +772,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } + if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) { + try { + r.callback.onSrvccStateChanged(mSrvccState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); + } + } } } } else { @@ -1522,19 +1529,30 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); } - public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { - if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) { + @Override + public void notifySrvccStateChanged(int subId, @TelephonyManager.SrvccState int state) { + if (!checkNotifyPermission("notifySrvccStateChanged()")) { return; } + if (VDBG) { + log("notifySrvccStateChanged: subId=" + subId + " srvccState=" + state); + } + int phoneId = SubscriptionManager.getPhoneId(subId); synchronized (mRecords) { - mVoLteServiceState = lteState; - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_VOLTE_STATE)) { - try { - r.callback.onVoLteServiceStateChanged( - new VoLteServiceState(mVoLteServiceState)); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); + if (validatePhoneId(phoneId)) { + mSrvccState[phoneId] = state; + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) && + idMatch(r.subId, subId, phoneId)) { + try { + if (DBG_LOC) { + log("notifySrvccStateChanged: mSrvccState=" + state + " r=" + r); + } + r.callback.onSrvccStateChanged(state); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } } } } @@ -1680,7 +1698,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mRingingCallState=" + mRingingCallState); pw.println("mForegroundCallState=" + mForegroundCallState); pw.println("mBackgroundCallState=" + mBackgroundCallState); - pw.println("mVoLteServiceState=" + mVoLteServiceState); + pw.println("mSrvccState=" + mSrvccState); pw.println("mPhoneCapability=" + mPhoneCapability); pw.println("mPreferredDataSubId=" + mPreferredDataSubId); pw.println("mRadioPowerState=" + mRadioPowerState); @@ -1931,6 +1949,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); } + if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); + } + + return true; } diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 0ec85360908b..0fd8368729f9 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -16,7 +16,9 @@ package android.telephony; +import android.Manifest; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Bundle; @@ -201,12 +203,13 @@ public class PhoneStateListener { public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000; /** - * Listen for changes to LTE network state - * - * @see #onLteNetworkStateChanged + * Listen for changes to the SRVCC state of the active call. + * @see #onServiceStateChanged(ServiceState) * @hide */ - public static final int LISTEN_VOLTE_STATE = 0x00004000; + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int LISTEN_SRVCC_STATE_CHANGED = 0x00004000; /** * Listen for OEM hook raw event @@ -401,8 +404,8 @@ public class PhoneStateListener { PhoneStateListener.this.onDataConnectionRealTimeInfoChanged( (DataConnectionRealTimeInfo)msg.obj); break; - case LISTEN_VOLTE_STATE: - PhoneStateListener.this.onVoLteServiceStateChanged((VoLteServiceState)msg.obj); + case LISTEN_SRVCC_STATE_CHANGED: + PhoneStateListener.this.onSrvccStateChanged((int) msg.obj); break; case LISTEN_VOICE_ACTIVATION_STATE: PhoneStateListener.this.onVoiceActivationStateChanged((int)msg.obj); @@ -605,13 +608,13 @@ public class PhoneStateListener { } /** - * Callback invoked when the service state of LTE network - * related to the VoLTE service has changed. - * @param stateInfo is the current LTE network information + * Callback invoked when there has been a change in the Single Radio Voice Call Continuity + * (SRVCC) state for the currently active call. * @hide */ - @UnsupportedAppUsage - public void onVoLteServiceStateChanged(VoLteServiceState stateInfo) { + @SystemApi + public void onSrvccStateChanged(@TelephonyManager.SrvccState int srvccState) { + } /** @@ -795,8 +798,8 @@ public class PhoneStateListener { send(LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0, dcRtInfo); } - public void onVoLteServiceStateChanged(VoLteServiceState lteState) { - send(LISTEN_VOLTE_STATE, 0, 0, lteState); + public void onSrvccStateChanged(int state) { + send(LISTEN_SRVCC_STATE_CHANGED, 0, 0, state); } public void onVoiceActivationStateChanged(int activationState) { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index e4f766f28d01..364d573608f8 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -177,6 +177,57 @@ public class TelephonyManager { /** @hide */ static public final int KEY_TYPE_WLAN = 2; + /** + * No Single Radio Voice Call Continuity (SRVCC) handover is active. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_NONE = -1; + + /** + * Single Radio Voice Call Continuity (SRVCC) handover has been started on the network. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_STARTED = 0; + + /** + * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has successfully completed. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; + + /** + * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has failed. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_FAILED = 2; + + /** + * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has been canceled. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SRVCC_STATE_"}, + value = { + SRVCC_STATE_HANDOVER_NONE, + SRVCC_STATE_HANDOVER_STARTED, + SRVCC_STATE_HANDOVER_COMPLETED, + SRVCC_STATE_HANDOVER_FAILED, + SRVCC_STATE_HANDOVER_CANCELED}) + public @interface SrvccState {} + private final Context mContext; private final int mSubId; @UnsupportedAppUsage diff --git a/telephony/java/android/telephony/VoLteServiceState.java b/telephony/java/android/telephony/VoLteServiceState.java index 25bb8b4a414e..cf961d0be10c 100644 --- a/telephony/java/android/telephony/VoLteServiceState.java +++ b/telephony/java/android/telephony/VoLteServiceState.java @@ -24,9 +24,11 @@ import android.telephony.Rlog; /** * Contains LTE network state related information. - * + * @deprecated Only contains SRVCC state, which isn't specific to LTE handovers. For SRVCC + * indications, use {@link PhoneStateListener#onSrvccStateChanged(int)}. * @hide */ +@Deprecated public final class VoLteServiceState implements Parcelable { private static final String LOG_TAG = "VoLteServiceState"; diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index 64ea6083d63d..442fc34d4b71 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -25,7 +25,6 @@ import android.telephony.PhoneCapability; import android.telephony.PhysicalChannelConfig; import android.telephony.PreciseCallState; import android.telephony.PreciseDataConnectionState; -import android.telephony.VoLteServiceState; oneway interface IPhoneStateListener { void onServiceStateChanged(in ServiceState serviceState); @@ -45,7 +44,7 @@ oneway interface IPhoneStateListener { void onPreciseCallStateChanged(in PreciseCallState callState); void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState); void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo); - void onVoLteServiceStateChanged(in VoLteServiceState lteState); + void onSrvccStateChanged(in int state); void onVoiceActivationStateChanged(int activationState); void onDataActivationStateChanged(int activationState); void onOemHookRawEvent(in byte[] rawData); diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 0bbfa9a83b8b..e50cdcdedcf3 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -25,7 +25,6 @@ import android.telephony.PhoneCapability; import android.telephony.PhysicalChannelConfig; import android.telephony.ServiceState; import android.telephony.SignalStrength; -import android.telephony.VoLteServiceState; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.IOnSubscriptionsChangedListener; @@ -70,7 +69,7 @@ interface ITelephonyRegistry { void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause); void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); - void notifyVoLteServiceStateChanged(in VoLteServiceState lteState); + void notifySrvccStateChanged(in int subId, in int lteState); void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, int activationState, int activationType); void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData); |