Allow a custom component to receive notification of missed call.

By setting the custom component, the system notification is suppressed.

Change-Id: Idfc0354aaa97776e19ad642e44a88978577559a9
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ac3799f..6c20189 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,6 +20,9 @@
         coreApp="true"
         android:sharedUserId="android.uid.system">
 
+
+    <protected-broadcast android:name="android.intent.action.SHOW_MISSED_CALLS_NOTIFICATION" />
+
     <!-- Prevents the activity manager from delaying any activity-start
          requests by this package, including requests immediately after
          the user presses "home". -->
diff --git a/res/values/config.xml b/res/values/config.xml
index 365e758..e474d7e 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -38,4 +38,8 @@
 
     <!-- Flag indicating if the tty is enabled -->
     <bool name="tty_enabled">false</bool>
+
+    <!-- Component name for the notification handler. The presence of this value will disable
+         MissedCallNotifierImpl's presentation of missed call/voice notifications [DO NOT TRANSLATE] -->
+    <string name="notification_component" translatable="false"></string>
 </resources>
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 603ea7e..07137d2 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -48,6 +48,7 @@
 import com.android.server.telecom.ContactsAsyncHelper.OnImageLoadCompleteListener;
 import com.android.internal.util.Preconditions;
 
+import java.lang.String;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -666,6 +667,10 @@
         return mCallerInfo == null ? null : mCallerInfo.name;
     }
 
+    public String getPhoneNumber() {
+        return mCallerInfo == null ? null : mCallerInfo.phoneNumber;
+    }
+
     public Bitmap getPhotoIcon() {
         return mCallerInfo == null ? null : mCallerInfo.cachedPhotoIcon;
     }
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index ad6fc16..5455295 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -16,6 +16,8 @@
 
 package com.android.server.telecom.ui;
 
+import android.content.ComponentName;
+import android.telecom.TelecomManager;
 import com.android.server.telecom.Call;
 import com.android.server.telecom.CallState;
 import com.android.server.telecom.CallerInfoAsyncQueryFactory;
@@ -54,6 +56,9 @@
 import android.text.TextDirectionHeuristics;
 import android.text.TextUtils;
 
+import java.lang.Override;
+import java.lang.String;
+
 // TODO: Needed for move to system service: import com.android.internal.R;
 
 /**
@@ -89,6 +94,8 @@
     private final Context mContext;
     private final NotificationManager mNotificationManager;
 
+    private final ComponentName mNotificationComponent;
+
     // Used to track the number of missed calls.
     private int mMissedCallCount = 0;
 
@@ -96,6 +103,10 @@
         mContext = context;
         mNotificationManager =
                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        final String notificationComponent = context.getString(R.string.notification_component);
+
+        mNotificationComponent = notificationComponent != null
+                ? ComponentName.unflattenFromString(notificationComponent) : null;
     }
 
     /** {@inheritDoc} */
@@ -135,6 +146,37 @@
     }
 
     /**
+     * Broadcasts missed call notification to custom component if set.
+     * @param number The phone number associated with the notification. null if
+     *               no call.
+     * @param count The number of calls associated with the notification.
+     * @return {@code true} if the broadcast was sent. {@code false} otherwise.
+     */
+    private boolean sendNotificationCustomComponent(Call call, int count) {
+        if (mNotificationComponent != null) {
+            Intent intent = new Intent();
+            intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+            intent.setComponent(mNotificationComponent);
+            intent.setAction(TelecomManager.ACTION_SHOW_MISSED_CALLS_NOTIFICATION);
+            intent.putExtra(TelecomManager.EXTRA_NOTIFICATION_COUNT, count);
+            intent.putExtra(TelecomManager.EXTRA_NOTIFICATION_PHONE_NUMBER,
+                    call != null ? call.getPhoneNumber() : null);
+            intent.putExtra(TelecomManager.EXTRA_CLEAR_MISSED_CALLS_INTENT,
+                    createClearMissedCallsPendingIntent());
+
+            if (count == 1 && call != null) {
+                intent.putExtra(TelecomManager.EXTRA_CALL_BACK_INTENT,
+                    createCallBackPendingIntent(call.getHandle()));
+            }
+
+            mContext.sendBroadcast(intent);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
      * Create a system notification for the missed call.
      *
      * @param call The missed call.
@@ -143,6 +185,10 @@
     public void showMissedCallNotification(Call call) {
         mMissedCallCount++;
 
+        if (sendNotificationCustomComponent(call, mMissedCallCount)) {
+            return;
+        }
+
         final int titleResId;
         final String expandedText;  // The text in the notification's line 1 and 2.
 
@@ -218,6 +264,12 @@
     private void cancelMissedCallNotification() {
         // Reset the number of missed calls to 0.
         mMissedCallCount = 0;
+
+
+        if (sendNotificationCustomComponent(null, mMissedCallCount)) {
+            return;
+        }
+
         long token = Binder.clearCallingIdentity();
         try {
             mNotificationManager.cancelAsUser(null, MISSED_CALL_NOTIFICATION_ID,