Phone/SipSettings: add timeout feedback, enhance registration status feedback

http://b/issue?id=2984419
http://b/issue?id=2991065

Change-Id: I043409ef51aef0a4b2ee1324ec737e7c198aab64
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7c7c52e..e38c25b 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -47,6 +47,8 @@
     <string name="callFailed_userBusy">Line busy</string>
     <!-- In-call screen: call failure reason (network congestion) -->
     <string name="callFailed_congestion">Network busy</string>
+    <!-- In-call screen: call failure reason (client timed out) -->
+    <string name="callFailed_timedOut">No response, timed out</string>
     <!-- In-call screen: call failure reason (no signal) -->
     <string name="callFailed_noSignal">No signal</string>
     <!-- In-call screen: call failure reason (GSM ACM limit exceeded) -->
@@ -1276,14 +1278,26 @@
     <string name="primary_account_title">Make this my primary account</string>
     <!-- Summary text of the account type checkbox. [CHAR LIMIT=NONE] -->
     <string name="primary_account_summary">Used for outbound calls.</string>
-    <!-- Text of the account status. 'Active' means the account is managed by SIP service. [CHAR LIMIT=NONE] -->
-    <string name="active_account">Receiving calls</string>
-    <!-- Text of the account status. 'Inactive' means the account is not managed by SIP service. [CHAR LIMIT=NONE] -->
-    <string name="inactive_account">Not receiving calls</string>
     <!-- Title of the advanced settings button. The button will show the advanced settings of a SIP account in the SIP editor [CHAR LIMIT=NONE] -->
     <string name="advanced_settings_title">Advanced settings</string>
+    <!-- Text of a primary account summary with registration status [CHAR LIMIT=NONE] -->
+    <string name="primary_account_summary_with">primary account, %s</string>
+    <!-- Text of registration status, checking status [CHAR LIMIT=NONE] -->
+    <string name="registration_status_checking_status">checking status...</string>
+    <!-- Text of registration status, registering [CHAR LIMIT=NONE] -->
+    <string name="registration_status_registering">registering...</string>
+    <!-- Text of registration status, still trying [CHAR LIMIT=NONE] -->
+    <string name="registration_status_still_trying">still trying...</string>
+    <!-- Text of registration status, not receiving calls [CHAR LIMIT=NONE] -->
+    <string name="registration_status_not_receiving">not receiving calls</string>
+    <!-- Text of registration status, receiving calls [CHAR LIMIT=NONE] -->
+    <string name="registration_status_done">receiving calls</string>
+    <!-- Text of registration status, failed with a reason [CHAR LIMIT=NONE] -->
+    <string name="registration_status_failed_try_later">registration failed (<xliff:g id="registration_error_message" example="timed out">%s</xliff:g>); will try later</string>
+    <!-- Text of registration status, failed with a reason [CHAR LIMIT=NONE] -->
+    <string name="registration_status_failed">registration failed (<xliff:g id="registration_error_message" example="timed out">%s</xliff:g>)</string>
     <!-- Text for describing the account's owner and status. For example, 'Active, in use by Google Talk', it means that the account managed by SIP service was registered by the application 'Google Talk' and the status is active. [CHAR LIMIT=NONE] -->
-    <string name="account_summary"><xliff:g id="account_status" example="Active">%1$s</xliff:g>, in use by <xliff:g id="account_owner" example="Google Talk">%2$s</xliff:g></string>
+    <string name="third_party_account_summary">active, in use by <xliff:g id="account_owner" example="Google Talk">%s</xliff:g></string>
 
 
     <!-- Title of the sip editor screen. [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/phone/CallCard.java b/src/com/android/phone/CallCard.java
index 28eaafa..3a0f7e2 100755
--- a/src/com/android/phone/CallCard.java
+++ b/src/com/android/phone/CallCard.java
@@ -975,6 +975,10 @@
                     resID = R.string.callFailed_congestion;
                     break;
 
+                case TIMED_OUT:
+                    resID = R.string.callFailed_timedOut;
+                    break;
+
                 case LOST_SIGNAL:
                 case CDMA_DROP:
                     resID = R.string.callFailed_noSignal;
diff --git a/src/com/android/phone/sip/SipSettings.java b/src/com/android/phone/sip/SipSettings.java
index 2ba484f..49e1966 100644
--- a/src/com/android/phone/sip/SipSettings.java
+++ b/src/com/android/phone/sip/SipSettings.java
@@ -25,6 +25,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.net.sip.SipException;
+import android.net.sip.SipErrorCode;
 import android.net.sip.SipProfile;
 import android.net.sip.SipManager;
 import android.net.sip.SipRegistrationListener;
@@ -77,8 +78,6 @@
     private SipManager mSipManager;
 
     private String mProfilesDirectory;
-    private String mActiveString;
-    private String mInactiveString;
 
     private SipProfile mProfile;
 
@@ -103,33 +102,32 @@
         void setProfile(SipProfile p) {
             mProfile = p;
             setTitle(p.getProfileName());
-            updateSummary();
+            updateSummary(mSipSharedPreferences.isReceivingCallsEnabled()
+                    ? getString(R.string.registration_status_checking_status)
+                    : getString(R.string.registration_status_not_receiving));
         }
 
-        void updateSummary() {
+        void updateSummary(String registrationStatus) {
             int profileUid = mProfile.getCallingUid();
             boolean isPrimary = mProfile.getUriString().equals(
                     mSipSharedPreferences.getPrimaryAccount());
-            boolean isReceivingCall = (profileUid > 0) && ((profileUid != mUid)
-                    || mSipSharedPreferences.isReceivingCallsEnabled());
-            Log.v(TAG, "profile uid is " + profileUid + " receivingCall:"
-                    + isReceivingCall + " isPrimary:" + isPrimary + " Primary:"
-                    + mSipSharedPreferences.getPrimaryAccount());
-            String summary = !isReceivingCall
-                    ? mInactiveString
-                    : ((profileUid == mUid)
-                            ? mActiveString
-                            : getString(R.string.account_summary, mActiveString,
-                                    getPackageNameFromUid(profileUid)));
-            if (isPrimary) {
-                summary += " (Primary) ";
+            Log.v(TAG, "profile uid is " + profileUid + " isPrimary:"
+                    + isPrimary + " registration:" + registrationStatus
+                    + " Primary:" + mSipSharedPreferences.getPrimaryAccount()
+                    + " status:" + registrationStatus);
+            String summary = "";
+            if ((profileUid > 0) && (profileUid != mUid)) {
+                // from third party apps
+                summary = getString(R.string.third_party_account_summary,
+                        getPackageNameFromUid(profileUid));
+            } else if (isPrimary) {
+                summary = getString(R.string.primary_account_summary_with,
+                        registrationStatus);
+            } else {
+                summary = registrationStatus;
             }
             setSummary(summary);
         }
-        void updateSummary(String msg) {
-            updateSummary();
-            setSummary(getSummary() + " [" + msg + "]");
-        }
     }
 
     private String getPackageNameFromUid(int uid) {
@@ -155,8 +153,6 @@
         addPreferencesFromResource(R.xml.sip_setting);
         mProfilesDirectory = getFilesDir().getAbsolutePath() + PROFILES_DIR;
         mSipListContainer = getPreferenceScreen();
-        mActiveString = getString(R.string.active_account);
-        mInactiveString = getString(R.string.inactive_account);
         registerForAddSipListener();
 
         updateProfilesStatus();
@@ -263,27 +259,25 @@
         mSipListContainer.removeAll();
         for (SipProfile p : mSipProfileList) {
             addPreferenceFor(p);
+            if (mUid == p.getCallingUid()) {
+                try {
+                    mSipManager.setRegistrationListener(
+                            p.getUriString(), createRegistrationListener());
+                } catch (SipException e) {
+                    Log.e(TAG, "cannot set registration listener", e);
+                }
+            }
         }
     }
 
     private void processActiveProfilesFromSipService() {
         SipProfile[] activeList = mSipManager.getListOfProfiles();
         for (SipProfile activeProfile : activeList) {
-            int uid = activeProfile.getCallingUid();
-            if (uid == mUid) {
-                try {
-                    mSipManager.setRegistrationListener(
-                            activeProfile.getUriString(),
-                            createRegistrationListener());
-                } catch (SipException e) {
-                    Log.e(TAG, "cannot set registration listener", e);
-                }
-            }
             SipProfile profile = getProfileFromList(activeProfile);
             if (profile == null) {
                 mSipProfileList.add(activeProfile);
             } else {
-                profile.setCallingUid(uid);
+                profile.setCallingUid(activeProfile.getCallingUid());
             }
         }
     }
@@ -412,17 +406,13 @@
         startActivityForResult(intent, REQUEST_ADD_OR_EDIT_SIP_PROFILE);
     }
 
-    private void showRegistrationError(final String profileUri,
+    private void showRegistrationMessage(final String profileUri,
             final String message) {
         runOnUiThread(new Runnable() {
             public void run() {
-                try {
-                    SipPreference pref = mSipPreferenceMap.get(profileUri);
-                    if (pref != null) {
-                        pref.updateSummary(message);
-                    }
-                } catch (Exception e) {
-                    Log.e(TAG, "showRegistrationError failed:" + e);
+                SipPreference pref = mSipPreferenceMap.get(profileUri);
+                if (pref != null) {
+                    pref.updateSummary(message);
                 }
             }
         });
@@ -431,14 +421,31 @@
     private SipRegistrationListener createRegistrationListener() {
         return new SipRegistrationListener() {
             public void onRegistrationDone(String profileUri, long expiryTime) {
+                showRegistrationMessage(profileUri, getString(
+                        R.string.registration_status_done));
             }
 
             public void onRegistering(String profileUri) {
+                showRegistrationMessage(profileUri, getString(
+                        R.string.registration_status_registering));
             }
 
             public void onRegistrationFailed(String profileUri,
-                    String className, String message) {
-                showRegistrationError(profileUri, message);
+                    String errorCodeString, String message) {
+                switch (Enum.valueOf(SipErrorCode.class, errorCodeString)) {
+                    case IN_PROGRESS:
+                        showRegistrationMessage(profileUri, getString(
+                                R.string.registration_status_still_trying));
+                        break;
+                    case INVALID_CREDENTIALS:
+                        showRegistrationMessage(profileUri, getString(
+                                R.string.registration_status_failed, message));
+                        break;
+                    default:
+                        showRegistrationMessage(profileUri, getString(
+                                R.string.registration_status_failed_try_later,
+                                message));
+                }
             }
         };
     }