SipService: deliver connectivity change to all sessions.

+ add DATA_CONNECTION_LOST to SipErrorCode
+ convert it to Connection.DisconnectCause.LOST_SIGNAL in SipPhone

http://b/issue?id=2992548

Change-Id: Ie8983c1b81077b21f46304cf60b8e61df1ffd241
diff --git a/services/java/com/android/server/sip/SipService.java b/services/java/com/android/server/sip/SipService.java
index c3786f5..803cc96 100644
--- a/services/java/com/android/server/sip/SipService.java
+++ b/services/java/com/android/server/sip/SipService.java
@@ -404,6 +404,7 @@
 
         public void onConnectivityChanged(boolean connected)
                 throws SipException {
+            mSipGroup.onConnectivityChanged();
             if (connected) {
                 resetGroup(mLocalIp);
                 if (mOpened) openToReceiveCalls();
diff --git a/services/java/com/android/server/sip/SipSessionGroup.java b/services/java/com/android/server/sip/SipSessionGroup.java
index da8e9b8..94769d8 100644
--- a/services/java/com/android/server/sip/SipSessionGroup.java
+++ b/services/java/com/android/server/sip/SipSessionGroup.java
@@ -153,6 +153,13 @@
         mSessionMap.clear();
     }
 
+    synchronized void onConnectivityChanged() {
+        for (SipSessionImpl s : mSessionMap.values()) {
+            s.onError(SipErrorCode.DATA_CONNECTION_LOST,
+                    "data connection lost");
+        }
+    }
+
     public SipProfile getLocalProfile() {
         return mLocalProfile;
     }
@@ -210,10 +217,10 @@
 
     private synchronized SipSessionImpl getSipSession(EventObject event) {
         String key = SipHelper.getCallId(event);
-        Log.d(TAG, " sesssion key from event: " + key);
-        Log.d(TAG, " active sessions:");
+        Log.d(TAG, "sesssion key from event: " + key);
+        Log.d(TAG, "active sessions:");
         for (String k : mSessionMap.keySet()) {
-            Log.d(TAG, "   .....  '" + k + "': " + mSessionMap.get(k));
+            Log.d(TAG, " ..." + k + ": " + mSessionMap.get(k));
         }
         SipSessionImpl session = mSessionMap.get(key);
         return ((session != null) ? session : mCallReceiverSession);
@@ -222,7 +229,7 @@
     private synchronized void addSipSession(SipSessionImpl newSession) {
         removeSipSession(newSession);
         String key = newSession.getCallId();
-        Log.d(TAG, " +++++  add a session with key:  '" + key + "'");
+        Log.d(TAG, "+++  add a session with key:  '" + key + "'");
         mSessionMap.put(key, newSession);
         for (String k : mSessionMap.keySet()) {
             Log.d(TAG, "   .....  " + k + ": " + mSessionMap.get(k));
@@ -998,7 +1005,8 @@
                     onRegistrationFailed(errorCode, message);
                     break;
                 default:
-                    if (mInCall) {
+                    if ((errorCode != SipErrorCode.DATA_CONNECTION_LOST)
+                            && mInCall) {
                         fallbackToPreviousInCall(errorCode, message);
                     } else {
                         endCallOnError(errorCode, message);
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 2c99145..7fe76cd 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -635,9 +635,9 @@
             @Override
             protected void onError(DisconnectCause cause) {
                 Log.w(LOG_TAG, "SIP error: " + cause);
-                if (mSipAudioCall.isInCall()) {
-                    // Don't end the call when in call.
-                    // TODO: how to deliver the error to PhoneApp
+                if (mSipAudioCall.isInCall()
+                        && (cause != DisconnectCause.LOST_SIGNAL)) {
+                    // Don't end the call when in a call.
                     return;
                 }
 
@@ -829,6 +829,9 @@
                 case TRANSACTION_TERMINTED:
                     onError(Connection.DisconnectCause.TIMED_OUT);
                     break;
+                case DATA_CONNECTION_LOST:
+                    onError(Connection.DisconnectCause.LOST_SIGNAL);
+                    break;
                 case INVALID_CREDENTIALS:
                     onError(Connection.DisconnectCause.INVALID_CREDENTIALS);
                     break;
diff --git a/voip/java/android/net/sip/SipErrorCode.java b/voip/java/android/net/sip/SipErrorCode.java
index 8624811..963733e 100644
--- a/voip/java/android/net/sip/SipErrorCode.java
+++ b/voip/java/android/net/sip/SipErrorCode.java
@@ -47,5 +47,8 @@
     INVALID_CREDENTIALS,
 
     /** The client is in a transaction and cannot initiate a new one. */
-    IN_PROGRESS;
+    IN_PROGRESS,
+
+    /** When data connection is lost. */
+    DATA_CONNECTION_LOST;
 }