add actions to the incoming call notification

Bug: 12605720
Change-Id: Ic3593da8693e9fd51e9d3d87aa3ede770aa598cc
diff --git a/InCallUI/AndroidManifest.xml b/InCallUI/AndroidManifest.xml
index 56cd5e8..3232d10 100644
--- a/InCallUI/AndroidManifest.xml
+++ b/InCallUI/AndroidManifest.xml
@@ -54,6 +54,8 @@
         <receiver android:name="InCallApp$NotificationBroadcastReceiver" android:exported="false">
             <intent-filter>
                 <action android:name="com.android.incallui.ACTION_HANG_UP_ONGOING_CALL" />
+                <action android:name="com.android.incallui.ACTION_ANSWER_INCOMING_CALL" />
+                <action android:name="com.android.incallui.ACTION_DECLINE_INCOMING_CALL" />
             </intent-filter>
         </receiver>
 
diff --git a/InCallUI/src/com/android/incallui/InCallApp.java b/InCallUI/src/com/android/incallui/InCallApp.java
index 7d276bc..01bdf3b 100644
--- a/InCallUI/src/com/android/incallui/InCallApp.java
+++ b/InCallUI/src/com/android/incallui/InCallApp.java
@@ -34,6 +34,10 @@
      */
     public static final String ACTION_HANG_UP_ONGOING_CALL =
             "com.android.incallui.ACTION_HANG_UP_ONGOING_CALL";
+    public static final String ACTION_ANSWER_INCOMING_CALL =
+            "com.android.incallui.ACTION_ANSWER_INCOMING_CALL";
+    public static final String ACTION_DECLINE_INCOMING_CALL =
+            "com.android.incallui.ACTION_DECLINE_INCOMING_CALL";
 
     public InCallApp() {
     }
@@ -59,11 +63,15 @@
             final String action = intent.getAction();
             Log.i(this, "Broadcast from Notification: " + action);
 
+            // TODO: Commands of this nature should exist in the CallList or a
+            //       CallController class that has access to CallCommandClient and
+            //       CallList.
             if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) {
-                // TODO: Commands of this nature should exist in the CallList or a
-                //       CallController class that has access to CallCommandClient and
-                //       CallList.
                 InCallPresenter.getInstance().hangUpOngoingCall(context);
+            } else if (action.equals(ACTION_ANSWER_INCOMING_CALL)) {
+                InCallPresenter.getInstance().answerIncomingCall(context);
+            } else if (action.equals(ACTION_DECLINE_INCOMING_CALL)) {
+                InCallPresenter.getInstance().declineIncomingCall(context);
             }
         }
     }
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index e4967aa..31e8d75 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -364,6 +364,41 @@
     }
 
     /**
+     * Answers any incoming call.
+     */
+    public void answerIncomingCall(Context context) {
+        // By the time we receive this intent, we could be shut down and call list
+        // could be null.  Bail in those cases.
+        if (mCallList == null) {
+            StatusBarNotifier.clearInCallNotification(context);
+            return;
+        }
+
+        Call call = mCallList.getIncomingCall();
+        if (call != null) {
+            CallCommandClient.getInstance().answerCall(call.getCallId());
+            showInCall(false);
+        }
+    }
+
+    /**
+     * Declines any incoming call.
+     */
+    public void declineIncomingCall(Context context) {
+        // By the time we receive this intent, we could be shut down and call list
+        // could be null.  Bail in those cases.
+        if (mCallList == null) {
+            StatusBarNotifier.clearInCallNotification(context);
+            return;
+        }
+
+        Call call = mCallList.getIncomingCall();
+        if (call != null) {
+            CallCommandClient.getInstance().rejectCall(call, false, null);
+        }
+    }
+
+    /**
      * Returns true if the incall app is the foreground application.
      */
     public boolean isShowingInCallUi() {
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index 83878a5..dccef22 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -302,6 +302,12 @@
                 Call.State.isDialing(state)) {
             addHangupAction(builder);
         }
+        // Add answer/decline options for incomng calls (incoming | call_waiting)
+        if (state == Call.State.INCOMING ||
+                state == Call.State.CALL_WAITING) {
+            addAnswerAction(builder);
+            addDeclineAction(builder);
+        }
 
         /*
          * Fire off the notification
@@ -452,6 +458,24 @@
                 createHangUpOngoingCallPendingIntent(mContext));
     }
 
+    private void addAnswerAction(Notification.Builder builder) {
+        Log.i(this, "Will show \"answer\" action in the incoming call Notification");
+
+        // TODO: use better asset and string
+        builder.addAction(R.drawable.stat_sys_phone_call,
+                mContext.getText(R.string.description_target_answer),
+                createAnswerCallPendingIntent(mContext));
+    }
+
+    private void addDeclineAction(Notification.Builder builder) {
+        Log.i(this, "Will show \"decline\" action in the incoming call Notification");
+
+        // TODO: use better asset and string
+        builder.addAction(R.drawable.stat_sys_phone_call_end,
+                mContext.getText(R.string.description_target_decline),
+                createDeclineCallPendingIntent(mContext));
+    }
+
     /**
      * Adds fullscreen intent to the builder.
      */
@@ -530,8 +554,33 @@
      * Notification context.
      */
     private static PendingIntent createHangUpOngoingCallPendingIntent(Context context) {
-        final Intent intent = new Intent(InCallApp.ACTION_HANG_UP_ONGOING_CALL, null,
+        return createNotificationPendingIntent(context, InCallApp.ACTION_HANG_UP_ONGOING_CALL);
+    }
+
+    /**
+     * Returns PendingIntent for answering a phone call. This will typically be used from
+     * Notification context.
+     */
+    private static PendingIntent createAnswerCallPendingIntent(Context context) {
+        return createNotificationPendingIntent(context, InCallApp.ACTION_ANSWER_INCOMING_CALL);
+    }
+
+    /**
+     * Returns PendingIntent for declining a phone call. This will typically be used from
+     * Notification context.
+     */
+    private static PendingIntent createDeclineCallPendingIntent(Context context) {
+        return createNotificationPendingIntent(context, InCallApp.ACTION_DECLINE_INCOMING_CALL);
+    }
+
+    /**
+     * Returns PendingIntent for answering a phone call. This will typically be used from
+     * Notification context.
+     */
+    private static PendingIntent createNotificationPendingIntent(Context context, String action) {
+        final Intent intent = new Intent(action, null,
                 context, NotificationBroadcastReceiver.class);
         return PendingIntent.getBroadcast(context, 0, intent, 0);
     }
+
 }