Add redirection of voicemail notification to a custom component.

Change-Id: If08ad7043987fd070f243a6c707a3f6d5c5f6915
diff --git a/res/values/config.xml b/res/values/config.xml
index 826cd74..50bfe85 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -194,5 +194,9 @@
     <!-- Class name for the SIM unlock dialog.[DO NOT TRANSLATE] -->
     <string name="config_simUnlockUiClass" translatable="false">@null</string>
 
+    <!-- Flag indicating whether to allow visual voicemail if available on the device.[DO NOT TRANSLATE] -->
     <bool name="allow_visual_voicemail">true</bool>
+
+    <!-- Component for custom voicemail notification handling. [DO NOT TRANSLATE] -->
+    <string name="config_customVoicemailComponent">@null</string>
 </resources>
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index c579fe0..4d5316a 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -93,6 +93,7 @@
 
     private Context mContext;
     private NotificationManager mNotificationManager;
+    private final ComponentName mNotificationComponent;
     private StatusBarManager mStatusBarManager;
     private UserManager mUserManager;
     private Toast mToast;
@@ -125,6 +126,12 @@
         mSubscriptionManager = SubscriptionManager.from(mContext);
         mTelecomManager = TelecomManager.from(mContext);
         mTelephonyManager = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
+
+        final String notificationComponent = mContext.getString(
+                R.string.config_customVoicemailComponent);
+
+        mNotificationComponent = notificationComponent != null
+                ? ComponentName.unflattenFromString(notificationComponent) : null;
     }
 
     /**
@@ -352,8 +359,10 @@
                 return;
             }
 
+            Integer vmCount = null;
+
             if (TelephonyCapabilities.supportsVoiceMessageCount(phone)) {
-                int vmCount = phone.getVoiceMessageCount();
+                vmCount = phone.getVoiceMessageCount();
                 String titleFormat = mContext.getString(R.string.notification_voicemail_title_count);
                 notificationTitle = String.format(titleFormat, vmCount);
             }
@@ -363,7 +372,9 @@
 
             Intent intent;
             String notificationText;
-            if (TextUtils.isEmpty(vmNumber)) {
+            boolean isSettingsIntent = TextUtils.isEmpty(vmNumber);
+
+            if (isSettingsIntent) {
                 notificationText = mContext.getString(
                         R.string.notification_voicemail_no_vm_number);
 
@@ -423,22 +434,75 @@
                 if (!mUserManager.hasUserRestriction(
                         UserManager.DISALLOW_OUTGOING_CALLS, userHandle)
                         && !user.isManagedProfile()) {
-                    mNotificationManager.notifyAsUser(
-                            Integer.toString(subId) /* tag */,
-                            VOICEMAIL_NOTIFICATION,
-                            notification,
-                            userHandle);
+                    if (!sendNotificationCustomComponent(vmCount, vmNumber, pendingIntent,
+                            isSettingsIntent)) {
+                        mNotificationManager.notifyAsUser(
+                                Integer.toString(subId) /* tag */,
+                                VOICEMAIL_NOTIFICATION,
+                                notification,
+                                userHandle);
+                    }
                 }
             }
         } else {
-            mNotificationManager.cancelAsUser(
-                    Integer.toString(subId) /* tag */,
-                    VOICEMAIL_NOTIFICATION,
-                    UserHandle.ALL);
+            if (!sendNotificationCustomComponent(0, null, null, false)) {
+                mNotificationManager.cancelAsUser(
+                        Integer.toString(subId) /* tag */,
+                        VOICEMAIL_NOTIFICATION,
+                        UserHandle.ALL);
+            }
         }
     }
 
     /**
+     * Sends a broadcast with the voicemail notification information to a custom component to
+     * handle. This method is also used to indicate to the custom component when to clear the
+     * notification. A pending intent can be passed to the custom component to indicate an action to
+     * be taken as it would by a notification produced in this class.
+     * @param count The number of pending voicemail messages to indicate on the notification. A
+     *              Value of 0 is passed here to indicate that the notification should be cleared.
+     * @param number The voicemail phone number if specified.
+     * @param pendingIntent The intent that should be passed as the action to be taken.
+     * @param isSettingsIntent {@code true} to indicate the pending intent is to launch settings.
+     *                         otherwise, {@code false} to indicate the intent launches voicemail.
+     * @return {@code true} if a custom component was notified of the notification.
+     */
+    private boolean sendNotificationCustomComponent(Integer count, String number,
+            PendingIntent pendingIntent, boolean isSettingsIntent) {
+        if (mNotificationComponent != null) {
+            Intent intent = new Intent();
+            intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+            intent.setComponent(mNotificationComponent);
+            intent.setAction(TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION);
+
+            if (count != null) {
+                intent.putExtra(TelephonyManager.EXTRA_NOTIFICATION_COUNT, count);
+            }
+
+            // Additional information about the voicemail notification beyond the count is only
+            // present when the count not specified or greater than 0. The value of 0 represents
+            // clearing the notification, which does not require additional information.
+            if (count == null || count > 0) {
+                if (!TextUtils.isEmpty(number)) {
+                    intent.putExtra(TelephonyManager.EXTRA_VOICEMAIL_NUMBER, number);
+                }
+
+                if (pendingIntent != null) {
+                    intent.putExtra(isSettingsIntent
+                            ? TelephonyManager.EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT
+                            : TelephonyManager.EXTRA_CALL_VOICEMAIL_INTENT,
+                            pendingIntent);
+                }
+            }
+
+            mContext.sendBroadcast(intent);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
      * Updates the message call forwarding indicator notification.
      *
      * @param visible true if there are messages waiting