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
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index e410302..4bfcd25 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.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 @@
 
     private ArrayList<List<PhysicalChannelConfig>> mPhysicalChannelConfigs;
 
-    private VoLteServiceState mVoLteServiceState = new VoLteServiceState();
+    private int[] mSrvccState;
 
     private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
@@ -230,8 +229,7 @@
 
     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 @@
         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 @@
             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 @@
                             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 @@
                 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 @@
             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 @@
                     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;
     }