Show notifications in case of some IMS Registration errors

Change-Id: I3aded2ee422f070f19399bd3f6f56bf4f6f7272c
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index cd73894..24689fd 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -16,7 +16,12 @@
 
 package com.android.internal.telephony.imsphone;
 
+import android.app.Activity;
 import android.app.ActivityManagerNative;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncResult;
@@ -101,6 +106,11 @@
 
     public static final String CS_FALLBACK = "cs_fallback";
 
+    public static final String REGISTRATION_ERROR = "android.telephony.ims.REGISTRATION_ERROR";
+    public static final String EXTRA_KEY_ALERT_TITLE = "alertTitle";
+    public static final String EXTRA_KEY_ALERT_MESSAGE = "alertMessage";
+    public static final String EXTRA_KEY_ALERT_SHOW = "alertShow";
+
     static final int RESTART_ECM_TIMER = 0; // restart Ecm timer
     static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer
 
@@ -1261,4 +1271,108 @@
     public void callEndCleanupHandOverCallIfAny() {
         mCT.callEndCleanupHandOverCallIfAny();
     }
+
+    private BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Add notification only if alert was not shown by WfcSettings
+            if (getResultCode() == Activity.RESULT_OK) {
+                // Default result code (as passed to sendOrderedBroadcast)
+                // means that intent was not received by WfcSettings.
+
+                CharSequence title = intent.getCharSequenceExtra(EXTRA_KEY_ALERT_TITLE);
+                CharSequence message = intent.getCharSequenceExtra(EXTRA_KEY_ALERT_MESSAGE);
+
+                Intent resultIntent = new Intent(Intent.ACTION_MAIN);
+                resultIntent.setClassName("com.android.settings",
+                        "com.android.settings.Settings$WifiCallingSettingsActivity");
+                resultIntent.putExtra(EXTRA_KEY_ALERT_SHOW, true);
+                resultIntent.putExtra(EXTRA_KEY_ALERT_TITLE, title);
+                resultIntent.putExtra(EXTRA_KEY_ALERT_MESSAGE, message);
+                PendingIntent resultPendingIntent =
+                        PendingIntent.getActivity(
+                                mContext,
+                                0,
+                                resultIntent,
+                                PendingIntent.FLAG_UPDATE_CURRENT
+                        );
+
+                final Notification notification =
+                        new Notification.Builder(mContext)
+                                .setSmallIcon(android.R.drawable.stat_sys_warning)
+                                .setContentTitle(title)
+                                .setContentText(message)
+                                .setAutoCancel(true)
+                                .setContentIntent(resultPendingIntent)
+                                .setStyle(new Notification.BigTextStyle().bigText(message))
+                                .build();
+                final String notificationTag = "wifi_calling";
+                final int notificationId = 1;
+
+                NotificationManager notificationManager =
+                        (NotificationManager) mContext.getSystemService(
+                                Context.NOTIFICATION_SERVICE);
+                notificationManager.notify(notificationTag, notificationId,
+                        notification);
+            }
+        }
+    };
+
+    /**
+     * Show notification in case of some error codes.
+     */
+    public void processDisconnectReason(ImsReasonInfo imsReasonInfo) {
+        if (imsReasonInfo.mCode == imsReasonInfo.CODE_REGISTRATION_ERROR
+                && imsReasonInfo.mExtraMessage != null) {
+
+            final String[] wfcOperatorErrorCodes =
+                    mContext.getResources().getStringArray(
+                            com.android.internal.R.array.wfcOperatorErrorCodes);
+            final String[] wfcOperatorErrorMessages =
+                    mContext.getResources().getStringArray(
+                            com.android.internal.R.array.wfcOperatorErrorMessages);
+
+            for (int i = 0; i < wfcOperatorErrorCodes.length; i++) {
+                // Match error code.
+                if (!imsReasonInfo.mExtraMessage.startsWith(
+                        wfcOperatorErrorCodes[i])) {
+                    continue;
+                }
+                // If there is no delimiter at the end of error code string
+                // then we need to verify that we are not matching partial code.
+                // EXAMPLE: "REG9" must not match "REG99".
+                // NOTE: Error code must not be empty.
+                int codeStringLength = wfcOperatorErrorCodes[i].length();
+                char lastChar = wfcOperatorErrorCodes[i].charAt(codeStringLength-1);
+                if (Character.isLetterOrDigit(lastChar)) {
+                    if (imsReasonInfo.mExtraMessage.length() > codeStringLength) {
+                        char nextChar = imsReasonInfo.mExtraMessage.charAt(codeStringLength);
+                        if (Character.isLetterOrDigit(nextChar)) {
+                            continue;
+                        }
+                    }
+                }
+
+                final CharSequence title = mContext.getText(
+                        com.android.internal.R.string.wfcRegErrorTitle);
+
+                CharSequence message = imsReasonInfo.mExtraMessage;
+                if (!wfcOperatorErrorMessages[i].isEmpty()) {
+                    message = wfcOperatorErrorMessages[i];
+                }
+
+                // If WfcSettings are active then alert will be shown
+                // otherwise notification will be added.
+                Intent intent = new Intent(REGISTRATION_ERROR);
+                intent.putExtra(EXTRA_KEY_ALERT_TITLE, title);
+                intent.putExtra(EXTRA_KEY_ALERT_MESSAGE, message);
+                mContext.sendOrderedBroadcast(intent, null, mResultReceiver,
+                        null, Activity.RESULT_OK, null, null);
+
+                // We can only match a single error code
+                // so should break the loop after a successful match.
+                break;
+            }
+        }
+    }
 }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 9280357..2e05789 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -1303,6 +1303,7 @@
             if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo);
             mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
             mPhone.setImsRegistered(false);
+            mPhone.processDisconnectReason(imsReasonInfo);
         }
 
         @Override