IMS: Deflect call feature

UI related code changes for IMS Deflect Call feature.

Change-Id: Ic0be9f56fbd7193f342fd15f970e521683b1cf9e
CRs-Fixed: 713856
diff --git a/InCallUI/res/drawable/qti_ic_lockscreen_deflect.xml b/InCallUI/res/drawable/qti_ic_lockscreen_deflect.xml
index 3184111..75f6d23 100644
--- a/InCallUI/res/drawable/qti_ic_lockscreen_deflect.xml
+++ b/InCallUI/res/drawable/qti_ic_lockscreen_deflect.xml
@@ -17,11 +17,11 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:state_enabled="true" android:state_active="false" android:state_focused="false"
-        android:drawable="@drawable/ic_lockscreen_answer_normal_layer"/>
+        android:drawable="@drawable/qti_ic_lockscreen_deflect_normal_layer"/>
     <item
         android:state_enabled="true" android:state_active="true"  android:state_focused="false"
-        android:drawable="@drawable/ic_lockscreen_answer_activated_layer" />
+        android:drawable="@drawable/qti_ic_lockscreen_deflect_activated_layer" />
    <item
         android:state_enabled="true" android:state_active="false"  android:state_focused="true"
-        android:drawable="@drawable/ic_lockscreen_answer_activated_layer" />
+        android:drawable="@drawable/qti_ic_lockscreen_deflect_activated_layer" />
 </selector>
diff --git a/InCallUI/res/values/qtiarray.xml b/InCallUI/res/values/qtiarray.xml
index b994523..80ae13c 100644
--- a/InCallUI/res/values/qtiarray.xml
+++ b/InCallUI/res/values/qtiarray.xml
@@ -141,4 +141,51 @@
         <item>@string/description_target_decline_upgrade_to_video_receive_request</item>
     </array>
 
+    <!-- For audio calls, if respond via SMS is disabled & call deflection is enabled:
+         - Answer (drag right)
+         - Decline (drag left)
+         - Deflect (drag down) -->
+    <array name="qti_incoming_call_widget_audio_without_sms_targets">
+        <item>@drawable/ic_lockscreen_answer</item>
+        <item>@null</item>
+        <item>@drawable/ic_lockscreen_decline</item>
+        <item>@drawable/qti_ic_lockscreen_deflect</item>
+    </array>
+    <array name="qti_incoming_call_widget_audio_without_sms_target_descriptions">
+        <item>@string/description_target_answer</item>
+        <item>@null</item>
+        <item>@string/description_target_decline</item>
+        <item>@string/qti_description_target_deflect</item>
+    </array>
+    <array name="qti_incoming_call_widget_audio_without_sms_direction_descriptions">
+        <item>@string/description_direction_right</item>
+        <item>@null</item>
+        <item>@string/description_direction_left</item>
+        <item>@string/description_direction_down</item>
+    </array>
+
+    <!-- For audio calls, if respond via SMS is enabled & call deflection is enabled:
+         - Answer (drag right)
+         - Respond via SMS (drag up)
+         - Decline (drag left)
+         - Deflect (drag down) -->
+    <array name="qti_incoming_call_widget_audio_with_sms_targets">
+        <item>@drawable/ic_lockscreen_answer</item>
+        <item>@drawable/ic_lockscreen_text</item>
+        <item>@drawable/ic_lockscreen_decline</item>
+        <item>@drawable/qti_ic_lockscreen_deflect</item>
+    </array>
+    <array name="qti_incoming_call_widget_audio_with_sms_target_descriptions">
+        <item>@string/description_target_answer</item>
+        <item>@string/description_target_send_sms</item>
+        <item>@string/description_target_decline</item>
+        <item>@string/qti_description_target_deflect</item>
+    </array>
+    <array name="qti_incoming_call_widget_audio_with_sms_direction_descriptions">
+        <item>@string/description_direction_right</item>
+        <item>@string/description_direction_up</item>
+        <item>@string/description_direction_left</item>
+        <item>@string/description_direction_down</item>
+    </array>
+
 </resources>
diff --git a/InCallUI/res/values/qtistrings.xml b/InCallUI/res/values/qtistrings.xml
index e4ed18f..ee325ff 100644
--- a/InCallUI/res/values/qtistrings.xml
+++ b/InCallUI/res/values/qtistrings.xml
@@ -87,4 +87,9 @@
     <string name="qti_ims_onscreenAssuredTransfer">Assured Transfer</string>
     <!-- Text for the onscreen "consultative transfer" button -->
     <string name="qti_ims_onscreenConsultativeTransfer">Consultative Transfer</string>
+
+    <!-- Description of the deflect target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="qti_description_target_deflect">Deflect</string>
+    <string name="qti_description_deflect_error">Number not set. Provide the number via IMS settings and retry.</string>
+    <string name="qti_description_deflect_service_error">Call Deflection service is not supported.</string>
 </resources>
diff --git a/InCallUI/src/com/android/incallui/AnswerFragment.java b/InCallUI/src/com/android/incallui/AnswerFragment.java
index 581054b..78580c0 100644
--- a/InCallUI/src/com/android/incallui/AnswerFragment.java
+++ b/InCallUI/src/com/android/incallui/AnswerFragment.java
@@ -57,6 +57,8 @@
     public static final int TARGET_SET_FOR_QTI_BIDIRECTIONAL_VIDEO_ACCEPT_REJECT_REQUEST = 1004;
     public static final int TARGET_SET_FOR_QTI_VIDEO_TRANSMIT_ACCEPT_REJECT_REQUEST = 1005;
     public static final int TARGET_SET_FOR_QTI_VIDEO_RECEIVE_ACCEPT_REJECT_REQUEST = 1006;
+    public static final int TARGET_SET_FOR_QTI_AUDIO_WITHOUT_SMS = 1007;
+    public static final int TARGET_SET_FOR_QTI_AUDIO_WITH_SMS = 1008;
 
     /**
      * This fragment implement no UI at all. Derived class should do it.
@@ -268,6 +270,10 @@
         getPresenter().onText();
     }
 
+    public void onDeflect(Context context) {
+        getPresenter().onDeflect(context);
+    }
+
     /**
      * OnItemClickListener for the "Respond via SMS" popup.
      */
diff --git a/InCallUI/src/com/android/incallui/AnswerPresenter.java b/InCallUI/src/com/android/incallui/AnswerPresenter.java
index 60fff66..d22bef4 100644
--- a/InCallUI/src/com/android/incallui/AnswerPresenter.java
+++ b/InCallUI/src/com/android/incallui/AnswerPresenter.java
@@ -17,6 +17,7 @@
 package com.android.incallui;
 
 import android.content.Context;
+import android.provider.Settings;
 
 import com.android.dialer.compat.UserManagerCompat;
 import com.android.dialer.util.TelecomUtil;
@@ -24,6 +25,12 @@
 
 import java.util.List;
 
+import org.codeaurora.ims.internal.IQtiImsExt;
+import org.codeaurora.ims.QtiImsException;
+import org.codeaurora.ims.QtiImsExtListenerBaseImpl;
+import org.codeaurora.ims.QtiImsExtManager;
+import org.codeaurora.ims.utils.QtiImsExtUtils;
+
 /**
  * Presenter for the Incoming call widget. The {@link AnswerPresenter} handles the logic during
  * incoming calls. It is also in charge of responding to incoming calls, so there needs to be
@@ -44,6 +51,17 @@
     private Call mCall = null;
     private boolean mHasTextMessages = false;
 
+    /* QtiImsExtListenerBaseImpl instance to handle call deflection response */
+    private QtiImsExtListenerBaseImpl imsInterfaceListener =
+            new QtiImsExtListenerBaseImpl() {
+
+        /* Handles call deflect response */
+        @Override
+        public void receiveCallDeflectResponse(int result) {
+            Log.w(this, "receiveCallDeflectResponse: " + result);
+        }
+    };
+
     @Override
     public void onUiShowing(boolean showing) {
         if (showing) {
@@ -266,6 +284,36 @@
         }
     }
 
+    /**
+     * Deflect the incoming call.
+     */
+    public void onDeflect(Context context) {
+        if (mCallId == null) {
+            return;
+        }
+        Log.d(this, "onDeflect " + mCallId);
+
+        String deflectCallNumber = QtiImsExtUtils.getCallDeflectNumber(
+                                           context.getContentResolver());
+        /* If not set properly, inform user via toast */
+        if (deflectCallNumber == null) {
+            Log.w(this, "getCallDeflectNumber is null or Empty.");
+            QtiCallUtils.displayToast(context, R.string.qti_description_deflect_error);
+        } else {
+            int phoneId = 0;
+            try {
+                Log.d(this, "Sending deflect request with Phone id " + phoneId +
+                        " to " + deflectCallNumber);
+                QtiImsExtManager.getInstance().sendCallDeflectRequest(phoneId,
+                        deflectCallNumber, imsInterfaceListener);
+             } catch (QtiImsException e) {
+                 Log.e(this, "sendCallDeflectRequest exception " + e);
+                 QtiCallUtils.displayToast(getUi().getContext(),
+                         R.string.qti_description_deflect_service_error);
+             }
+        }
+    }
+
     public void rejectCallWithMessage(String message) {
         Log.d(this, "sendTextToDefaultActivity()...");
         TelecomAdapter.getInstance().rejectCall(mCall.getId(), true, message);
@@ -297,6 +345,17 @@
                 getUi().showTargets(QtiCallUtils.getIncomingCallAnswerOptions(
                         getUi().getContext(), withSms));
             }
+        } else if (isCallDeflectSupported()) {
+            /**
+             * Only present the user with the option to deflect call,
+             * if the incoming call is only an audio call.
+             */
+            if (withSms) {
+                getUi().showTargets(AnswerFragment.TARGET_SET_FOR_QTI_AUDIO_WITH_SMS);
+                getUi().configureMessageDialog(textMsgs);
+            } else {
+                getUi().showTargets(AnswerFragment.TARGET_SET_FOR_QTI_AUDIO_WITHOUT_SMS);
+            }
         } else {
             if (withSms) {
                 getUi().showTargets(AnswerFragment.TARGET_SET_FOR_AUDIO_WITH_SMS);
@@ -307,6 +366,23 @@
         }
     }
 
+    /**
+     * Checks the Settings to conclude on the call deflect support.
+     * Returns true if call deflect is possible, false otherwise.
+     */
+    private boolean isCallDeflectSupported() {
+        int value = 0;
+        try{
+            value = android.provider.Settings.Global.getInt(
+                    getUi().getContext().getContentResolver(),
+                    QtiImsExtUtils.QTI_IMS_DEFLECT_ENABLED);
+        } catch(Settings.SettingNotFoundException e) {
+            //do Nothing
+            Log.e(this, "isCallDeflectSupported exception " + e);
+        }
+        return (value == 1);
+    }
+
     interface AnswerUi extends Ui {
         public void onShowAnswerUi(boolean shown);
         public void showTargets(int targetSet);
diff --git a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
index 0ef0bd7..7762d2f 100644
--- a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
+++ b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
@@ -177,6 +177,24 @@
                         .qti_incoming_call_widget_video_request_target_direction_descriptions;
                 handleDrawableResourceId = R.drawable.ic_incall_video_handle;
                 break;
+
+            case TARGET_SET_FOR_QTI_AUDIO_WITH_SMS:
+                targetResourceId = R.array.qti_incoming_call_widget_audio_with_sms_targets;
+                targetDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_audio_with_sms_target_descriptions;
+                directionDescriptionsResourceId = R.array
+                        .qti_incoming_call_widget_audio_with_sms_direction_descriptions;
+                handleDrawableResourceId = R.drawable.ic_incall_audio_handle;
+                break;
+            case TARGET_SET_FOR_QTI_AUDIO_WITHOUT_SMS:
+                targetResourceId = R.array.qti_incoming_call_widget_audio_without_sms_targets;
+                targetDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_audio_without_sms_target_descriptions;
+                directionDescriptionsResourceId = R.array
+                        .qti_incoming_call_widget_audio_without_sms_direction_descriptions;
+                handleDrawableResourceId = R.drawable.ic_incall_audio_handle;
+                break;
+
             case TARGET_SET_FOR_AUDIO_WITHOUT_SMS:
             default:
                 targetResourceId = R.array.incoming_call_widget_audio_without_sms_targets;
diff --git a/InCallUI/src/com/android/incallui/GlowPadWrapper.java b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
index 0c01f18..bc2d4da 100644
--- a/InCallUI/src/com/android/incallui/GlowPadWrapper.java
+++ b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
@@ -133,6 +133,9 @@
         } else if (resId == R.drawable.qti_ic_lockscreen_answer_rx_video) {
             mAnswerFragment.onAnswer(VideoProfile.STATE_RX_ENABLED, getContext());
             mTargetTriggered = true;
+        } else if (resId == R.drawable.qti_ic_lockscreen_deflect) {
+            mAnswerFragment.onDeflect(getContext());
+            mTargetTriggered = true;
         } else {
             // Code should never reach here.
             Log.e(this, "Trigger detected on unhandled resource. Skipping.");