IMS-VT: Support for one way video

- Support for answer as one way video
- Answer with VT_TX and VT_RX
- Revert "Cleanup AnswerFragment glowpad UI"
  This reverts commit 7ba13e9d001014d1ad23be29ad6847ad65951fbb.
- Upgrade/Downgrade one way video support

Change-Id: I7d9b631e0c6084cf4e8d59f8ee3088952ba9b9fb

IMS-VT: Show glowpad view with accept/reject for most video upgrade cases

- Show the glowpad view with all options only when upgrading
  from Volte to VT

- For all other cases, show the glowpad with accept/reject only

Change-Id: I41ecbda40db7c3c69428fc4272f8bfbd258e2980

IMS-VT: Align answer targets array for VT call properly

Align answer targets array for VT call properly in both
with and without sms cases such that user should always
swipe to the right to answer the call as video call and
swipe to left always answers the call as audio call

Change-Id: I07c4e68451db87f7e127ce1ed2aed25be5131471
CRs-Fixed: 921097
diff --git a/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video.xml b/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video.xml
new file mode 100644
index 0000000..5f86565
--- /dev/null
+++ b/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+  ~ Not a Contribution.
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<!-- Used with incoming call wigdet. -->
+<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/qti_ic_lockscreen_answer_rx_video_normal_layer"/>
+    <item
+        android:state_enabled="true" android:state_active="true"  android:state_focused="false"
+        android:drawable="@drawable/qti_ic_lockscreen_answer_rx_video_activated_layer" />
+    <item
+        android:state_enabled="true" android:state_active="false"  android:state_focused="true"
+        android:drawable="@drawable/qti_ic_lockscreen_answer_rx_video_activated_layer" />
+</selector>
diff --git a/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video_activated_layer.xml b/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video_activated_layer.xml
new file mode 100644
index 0000000..24b14cc
--- /dev/null
+++ b/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video_activated_layer.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+  ~ Not a Contribution.
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/fab_red" />
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/ic_rx_videocam"
+            android:tint="@color/glowpad_widget_active_color"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video_normal_layer.xml b/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video_normal_layer.xml
new file mode 100644
index 0000000..affd928
--- /dev/null
+++ b/InCallUI/res/drawable/qti_ic_lockscreen_answer_rx_video_normal_layer.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+  ~ Not a Contribution.
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- A fake circle to fix the size of this layer asset. -->
+    <item>
+        <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
+            <solid android:color="#00000000"/>
+            <size
+                android:width="@dimen/incoming_call_widget_circle_size"
+                android:height="@dimen/incoming_call_widget_circle_size" />
+        </shape>
+    </item>
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/ic_rx_videocam"
+            android:tint="@color/glowpad_call_widget_normal_tint"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video.xml b/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video.xml
new file mode 100644
index 0000000..258c1be
--- /dev/null
+++ b/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+  ~ Not a Contribution.
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<!-- Used with incoming call wigdet. -->
+<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/qti_ic_lockscreen_answer_tx_video_normal_layer"/>
+    <item
+        android:state_enabled="true" android:state_active="true"  android:state_focused="false"
+        android:drawable="@drawable/qti_ic_lockscreen_answer_tx_video_activated_layer" />
+    <item
+        android:state_enabled="true" android:state_active="false"  android:state_focused="true"
+        android:drawable="@drawable/qti_ic_lockscreen_answer_tx_video_activated_layer" />
+</selector>
diff --git a/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video_activated_layer.xml b/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video_activated_layer.xml
new file mode 100644
index 0000000..42d09f9
--- /dev/null
+++ b/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video_activated_layer.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+  ~ Not a Contribution.
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/fab_green" />
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/ic_tx_videocam"
+            android:tint="@color/glowpad_widget_active_color"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video_normal_layer.xml b/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video_normal_layer.xml
new file mode 100644
index 0000000..dc208db
--- /dev/null
+++ b/InCallUI/res/drawable/qti_ic_lockscreen_answer_tx_video_normal_layer.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+  ~ Not a Contribution.
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- A fake circle to fix the size of this layer asset. -->
+    <item>
+        <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
+            <solid android:color="#00000000"/>
+            <size
+                android:width="@dimen/incoming_call_widget_circle_size"
+                android:height="@dimen/incoming_call_widget_circle_size" />
+        </shape>
+    </item>
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/ic_tx_videocam"
+            android:tint="@color/glowpad_call_widget_normal_tint"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/InCallUI/res/values/qtiarray.xml b/InCallUI/res/values/qtiarray.xml
new file mode 100644
index 0000000..b994523
--- /dev/null
+++ b/InCallUI/res/values/qtiarray.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved.
+  ~
+  ~ Redistribution and use in source and binary forms, with or without
+  ~ modification, are permitted provided that the following conditions are
+  ~ met:
+  ~     * Redistributions of source code must retain the above copyright
+  ~       notice, this list of conditions and the following disclaimer.
+  ~     * Redistributions in binary form must reproduce the above
+  ~       copyright notice, this list of conditions and the following
+  ~       disclaimer in the documentation and/or other materials provided
+  ~       with the distribution.
+  ~     * Neither the name of The Linux Foundation nor the names of its
+  ~       contributors may be used to endorse or promote products derived
+  ~       from this software without specific prior written permission.
+  ~
+  ~ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+  ~ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  ~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+  ~ ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+  ~ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  ~ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  ~ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+  ~ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  ~ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  ~ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+  ~ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  -->
+
+<!-- Array resources for the Phone app. -->
+<resources>
+    <!-- "Target" resources for the GlowPadView widget used for incoming calls;
+         see InCallTouchUi.showIncomingCallWidget() and incall_touch_ui.xml.  -->
+
+    <!-- For video calls, if respond via SMS is disabled:
+         - Answer as video call (drag right)
+         - Decline (drag left)
+         - Answer as audio call (drag down) -->
+    <array name="qti_incoming_call_widget_video_without_sms_targets">
+        <item>@drawable/ic_lockscreen_answer_video</item>
+        <item>@null</item>
+        <item>@drawable/ic_lockscreen_decline</item>
+        <item>@drawable/ic_lockscreen_answer</item>
+        <item>@drawable/qti_ic_lockscreen_answer_tx_video</item>
+        <item>@drawable/qti_ic_lockscreen_answer_rx_video</item>
+    </array>
+    <array name="qti_incoming_call_widget_video_without_sms_target_descriptions">
+        <item>@string/description_target_answer_video_call</item>
+        <item>@null</item>
+        <item>@string/description_target_decline</item>
+        <item>@string/description_target_answer_audio_call</item>
+    </array>
+    <array name="qti_incoming_call_widget_video_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 video calls, if respond via SMS is enabled:
+         - Answer as video call (drag right)
+         - Respond via SMS (drag up)
+         - Decline (drag left)
+         - Answer as audio call (drag down) -->
+    <array name="qti_incoming_call_widget_video_with_sms_targets">
+        <item>@drawable/ic_lockscreen_answer_video</item>
+        <item>@drawable/ic_lockscreen_text</item>
+        <item>@drawable/ic_lockscreen_decline</item>
+        <item>@drawable/ic_lockscreen_answer</item>
+        <item>@drawable/qti_ic_lockscreen_answer_tx_video</item>
+        <item>@drawable/qti_ic_lockscreen_answer_rx_video</item>
+    </array>
+    <array name="qti_incoming_call_widget_video_with_sms_target_descriptions">
+        <item>@string/description_target_answer_video_call</item>
+        <item>@string/description_target_send_sms</item>
+        <item>@string/description_target_decline</item>
+        <item>@string/description_target_answer_audio_call</item>
+    </array>
+    <array name="qti_incoming_call_widget_video_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>
+
+    <!-- For accept/reject upgrade to video in active video call
+         - Accept upgrade to video request (drag right)
+         - Decline upgrade to video request (drag left)-->
+    <array name="qti_incoming_call_widget_video_request_targets">
+        <item>@drawable/ic_lockscreen_answer_video</item>
+        <item>@drawable/ic_lockscreen_decline_video</item>
+        <item>@drawable/ic_lockscreen_answer</item>
+        <item>@drawable/qti_ic_lockscreen_answer_tx_video</item>
+        <item>@drawable/qti_ic_lockscreen_answer_rx_video</item>
+    </array>
+
+    <array name="qti_incoming_call_widget_video_request_target_descriptions">
+        <item>@string/description_target_accept_upgrade_to_video_request</item>
+        <item>@null</item>
+        <item>@string/description_target_decline_upgrade_to_video_request</item>
+        <item>@null</item>"
+    </array>
+    <array name="qti_incoming_call_widget_video_request_target_direction_descriptions">
+        <item>@string/description_direction_right</item>
+        <item>@null</item>
+        <item>@string/description_direction_left</item>
+        <item>@null</item>
+    </array>
+
+    <!-- For accept/reject upgrade to video in active video call
+         - Accept upgrade to video request (drag right)
+         - Decline upgrade to video request (drag left)-->
+    <array name="qti_incoming_call_widget_bidirectional_video_accept_reject_request_targets">
+        <item>@drawable/ic_lockscreen_answer_video</item>
+        <item>@drawable/ic_lockscreen_decline</item>
+    </array>
+
+    <!-- For accept/reject upgrade to video transmit in active video call
+         - Accept upgrade to video request (drag right)
+         - Decline upgrade to video request (drag left)-->
+    <array name="qti_incoming_call_widget_video_transmit_accept_reject_request_targets">
+        <item>@drawable/qti_ic_lockscreen_answer_tx_video</item>
+        <item>@drawable/ic_lockscreen_decline</item>
+    </array>
+    <array name="qti_incoming_call_widget_video_transmit_request_target_descriptions">
+        <item>@string/description_target_accept_upgrade_to_video_transmit_request</item>
+        <item>@string/description_target_decline_upgrade_to_video_transmit_request</item>
+    </array>
+
+    <!-- For accept/reject upgrade to video receive in active video call
+         - Accept upgrade to video request (drag right)
+         - Decline upgrade to video request (drag left)-->
+    <array name="qti_incoming_call_widget_video_receive_accept_reject_request_targets">
+        <item>@drawable/qti_ic_lockscreen_answer_rx_video</item>
+        <item>@drawable/ic_lockscreen_decline</item>
+    </array>
+    <array name="qti_incoming_call_widget_video_receive_request_target_descriptions">
+        <item>@string/description_target_accept_upgrade_to_video_receive_request</item>
+        <item>@string/description_target_decline_upgrade_to_video_receive_request</item>
+    </array>
+
+</resources>
diff --git a/InCallUI/res/values/qticonfig.xml b/InCallUI/res/values/qticonfig.xml
new file mode 100644
index 0000000..b822b2a
--- /dev/null
+++ b/InCallUI/res/values/qticonfig.xml
@@ -0,0 +1,32 @@
+<!--
+  ~ Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved.
+  ~
+  ~ Redistribution and use in source and binary forms, with or without
+  ~ modification, are permitted provided that the following conditions are
+  ~ met:
+  ~     * Redistributions of source code must retain the above copyright
+  ~       notice, this list of conditions and the following disclaimer.
+  ~     * Redistributions in binary form must reproduce the above
+  ~       copyright notice, this list of conditions and the following
+  ~       disclaimer in the documentation and/or other materials provided
+  ~       with the distribution.
+  ~     * Neither the name of The Linux Foundation nor the names of its
+  ~       contributors may be used to endorse or promote products derived
+  ~       from this software without specific prior written permission.
+  ~
+  ~ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+  ~ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  ~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+  ~ ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+  ~ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  ~ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  ~ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+  ~ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  ~ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  ~ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+  ~ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  -->
+<resources>
+    <!-- Determines UI extensions for video calls should be used. -->
+    <bool name="video_call_use_ext">true</bool>
+</resources>
diff --git a/InCallUI/res/values/qtistrings.xml b/InCallUI/res/values/qtistrings.xml
new file mode 100644
index 0000000..e2ba3c3
--- /dev/null
+++ b/InCallUI/res/values/qtistrings.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved.
+  ~
+  ~ Redistribution and use in source and binary forms, with or without
+  ~ modification, are permitted provided that the following conditions are
+  ~ met:
+  ~      Redistributions of source code must retain the above copyright
+  ~       notice, this list of conditions and the following disclaimer.
+  ~      Redistributions in binary form must reproduce the above
+  ~       copyright notice, this list of conditions and the following
+  ~       disclaimer in the documentation and/or other materials provided
+  ~       with the distribution.
+  ~      Neither the name of The Linux Foundation nor the names of its
+  ~       contributors may be used to endorse or promote products derived
+  ~       from this software without specific prior written permission.
+  ~
+  ~ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+  ~ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+  ~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+  ~ ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+  ~ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  ~ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  ~ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+  ~ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+  ~ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  ~ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+  ~ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  ~
+  -->
+
+<!-- The xml contains Qti specific resource strings neede for any value added features. -->
+<resources>
+    <!-- Call substate label -->
+    <string name="call_substate_label"> : Call substate - \u000a</string>
+    <!-- Call substate label for call resumed -->
+    <string name="call_substate_call_resumed">Resumed \u000a</string>
+    <!-- Call substate label for call connected suspended (audio) -->
+    <string name="call_substate_connected_suspended_audio">Connected Suspended (Audio) \u000a</string>
+    <!-- Call substate label for call connected suspended (video) -->
+    <string name="call_substate_connected_suspended_video">Connected Suspended (Video) \u000a</string>
+    <!-- Call substate label for avp retry -->
+    <string name="call_substate_avp_retry">Avp Retry \u000a</string>
+
+    <!-- Video quality changed message -->
+    <string name="video_quality_changed"> : Video quality changed to \u0020</string>
+    <!-- Video quality High -->
+    <string name="video_quality_high">High</string>
+    <!-- Video quality Medium -->
+    <string name="video_quality_medium">Medium</string>
+    <!-- Video quality Low -->
+    <string name="video_quality_low">Low</string>
+    <!-- Video quality Unknown -->
+    <string name="video_quality_unknown">Unknown</string>
+
+    <!-- Message indicating that Video Started flowing for IMS-VT calls -->
+    <string name="player_started">Player Started</string>
+    <!-- Message indicating that Video Stopped flowing for IMS-VT calls -->
+    <string name="player_stopped">Player Stopped</string>
+    <!-- Message indicating that camera failure has occurred for the selected camera and
+         as result camera is not ready -->
+    <string name="camera_not_ready">Camera not ready</string>
+    <!-- Message indicating that camera is ready/available -->
+    <string name="camera_ready">Camera ready</string>
+    <!-- Message indicating unknown call session event -->
+    <string name="unknown_call_session_event">"Unkown call session event"</string>
+
+    <!-- Message indicating data usage -->
+    <string name="data_usage_label">"Data usage : "</string>
+
+    <!-- In-call screen: Modify Call Options for IMS call -->
+    <string name="modify_call_option_title" translatable="false">Which type of call?</string>
+    <string name="modify_call_option_vt" translatable="false">Video bidirectional</string>
+    <string name="modify_call_option_vt_tx" translatable="false">Video Transmit</string>
+    <string name="modify_call_option_vt_rx" translatable="false">Video Receive</string>
+    <string name="modify_call_option_voice" translatable="false">Voice Only</string>
+</resources>
diff --git a/InCallUI/src/com/android/incallui/AnswerFragment.java b/InCallUI/src/com/android/incallui/AnswerFragment.java
index 44ddfcd..581054b 100644
--- a/InCallUI/src/com/android/incallui/AnswerFragment.java
+++ b/InCallUI/src/com/android/incallui/AnswerFragment.java
@@ -51,6 +51,13 @@
     public static final int TARGET_SET_FOR_VIDEO_WITH_SMS = 3;
     public static final int TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST = 4;
 
+    public static final int TARGET_SET_FOR_QTI_VIDEO_WITHOUT_SMS = 1000;
+    public static final int TARGET_SET_FOR_QTI_VIDEO_WITH_SMS = 1001;
+    public static final int TARGET_SET_FOR_QTI_VIDEO_ACCEPT_REJECT_REQUEST = 1003;
+    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;
+
     /**
      * This fragment implement no UI at all. Derived class should do it.
      */
diff --git a/InCallUI/src/com/android/incallui/AnswerPresenter.java b/InCallUI/src/com/android/incallui/AnswerPresenter.java
index 6757268..60fff66 100644
--- a/InCallUI/src/com/android/incallui/AnswerPresenter.java
+++ b/InCallUI/src/com/android/incallui/AnswerPresenter.java
@@ -195,8 +195,9 @@
             return;
         }
         showAnswerUi(true);
-        ui.showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST,
-                modifyToVideoState);
+        ui.showTargets(QtiCallUtils.getSessionModificationOptions(getUi().getContext(),
+                currentVideoState, modifyToVideoState));
+
     }
 
     private boolean isEnabled(int videoState, int mask) {
@@ -287,12 +288,14 @@
 
         // Only present the user with the option to answer as a video call if the incoming call is
         // a bi-directional video call.
-        if (VideoUtils.isBidirectionalVideoCall(call)) {
+        if (VideoUtils.isVideoCall(call)) {
             if (withSms) {
-                getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_WITH_SMS);
+                getUi().showTargets(QtiCallUtils.getIncomingCallAnswerOptions(
+                        getUi().getContext(), withSms));
                 getUi().configureMessageDialog(textMsgs);
             } else {
-                getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_WITHOUT_SMS);
+                getUi().showTargets(QtiCallUtils.getIncomingCallAnswerOptions(
+                        getUi().getContext(), withSms));
             }
         } else {
             if (withSms) {
diff --git a/InCallUI/src/com/android/incallui/CallButtonPresenter.java b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
index e8c2d4b..7bb0464 100644
--- a/InCallUI/src/com/android/incallui/CallButtonPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
@@ -272,6 +272,12 @@
     }
 
     public void changeToVideoClicked() {
+        final Context context = getUi().getContext();
+        if (QtiCallUtils.useExt(context)) {
+            QtiCallUtils.displayModifyCallOptions(mCall, context);
+            return;
+        }
+
         VideoCall videoCall = mCall.getVideoCall();
         if (videoCall == null) {
             return;
@@ -384,7 +390,8 @@
                 && UserManagerCompat.isUserUnlocked(ui.getContext());
         final boolean showMerge = call.can(
                 android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE);
-        final boolean showUpgradeToVideo = !isVideo && hasVideoCallCapabilities(call);
+        final boolean useExt = QtiCallUtils.useExt(ui.getContext());
+        final boolean showUpgradeToVideo = (!isVideo || useExt) && hasVideoCallCapabilities(call);
         final boolean showDowngradeToAudio = isVideo && isDowngradeToAudioSupported(call);
         final boolean showMute = call.can(android.telecom.Call.Details.CAPABILITY_MUTE);
 
@@ -394,10 +401,11 @@
         ui.setHold(isCallOnHold);
         ui.showButton(BUTTON_MUTE, showMute);
         ui.showButton(BUTTON_ADD_CALL, showAddCall);
-        ui.showButton(BUTTON_UPGRADE_TO_VIDEO, showUpgradeToVideo);
-        ui.showButton(BUTTON_DOWNGRADE_TO_AUDIO, showDowngradeToAudio);
+        ui.showButton(BUTTON_UPGRADE_TO_VIDEO, showUpgradeToVideo ||
+                 (useExt && showDowngradeToAudio));
+        ui.showButton(BUTTON_DOWNGRADE_TO_AUDIO, showDowngradeToAudio && !useExt);
         ui.showButton(BUTTON_SWITCH_CAMERA, isVideo);
-        ui.showButton(BUTTON_PAUSE_VIDEO, isVideo);
+        ui.showButton(BUTTON_PAUSE_VIDEO, isVideo && !useExt);
         ui.showButton(BUTTON_DIALPAD, true);
         ui.showButton(BUTTON_MERGE, showMerge);
 
diff --git a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
index 62a8e78..0ef0bd7 100644
--- a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
+++ b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
@@ -126,6 +126,57 @@
                         .incoming_call_widget_video_request_target_direction_descriptions;
                 handleDrawableResourceId = R.drawable.ic_incall_video_handle;
                 break;
+            case TARGET_SET_FOR_QTI_VIDEO_WITHOUT_SMS:
+                targetResourceId = R.array.qti_incoming_call_widget_video_without_sms_targets;
+                targetDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_video_without_sms_target_descriptions;
+                directionDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_video_without_sms_direction_descriptions;
+                handleDrawableResourceId = R.drawable.ic_incall_video_handle;
+                break;
+            case TARGET_SET_FOR_QTI_VIDEO_WITH_SMS:
+                targetResourceId = R.array.qti_incoming_call_widget_video_with_sms_targets;
+                targetDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_video_with_sms_target_descriptions;
+                directionDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_video_with_sms_direction_descriptions;
+                handleDrawableResourceId = R.drawable.ic_incall_video_handle;
+                break;
+            case TARGET_SET_FOR_QTI_VIDEO_ACCEPT_REJECT_REQUEST:
+                targetResourceId = R.array.qti_incoming_call_widget_video_request_targets;
+                targetDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_video_request_target_descriptions;
+                directionDescriptionsResourceId = R.array.
+                        qti_incoming_call_widget_video_request_target_direction_descriptions;
+                handleDrawableResourceId = R.drawable.ic_incall_video_handle;
+                break;
+            case TARGET_SET_FOR_QTI_BIDIRECTIONAL_VIDEO_ACCEPT_REJECT_REQUEST:
+                targetResourceId = R.array.
+                        qti_incoming_call_widget_bidirectional_video_accept_reject_request_targets;
+                targetDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_video_request_target_descriptions;
+                directionDescriptionsResourceId = R.array.
+                        qti_incoming_call_widget_video_request_target_direction_descriptions;
+                handleDrawableResourceId = R.drawable.ic_incall_video_handle;
+                break;
+            case TARGET_SET_FOR_QTI_VIDEO_TRANSMIT_ACCEPT_REJECT_REQUEST:
+                targetResourceId = R.array.
+                        qti_incoming_call_widget_video_transmit_accept_reject_request_targets;
+                targetDescriptionsResourceId = R.array.
+                        qti_incoming_call_widget_video_transmit_request_target_descriptions;
+                directionDescriptionsResourceId = R.array
+                        .qti_incoming_call_widget_video_request_target_direction_descriptions;
+                handleDrawableResourceId = R.drawable.ic_incall_video_handle;
+                break;
+            case TARGET_SET_FOR_QTI_VIDEO_RECEIVE_ACCEPT_REJECT_REQUEST:
+                targetResourceId = R.array.
+                        qti_incoming_call_widget_video_receive_accept_reject_request_targets;
+                targetDescriptionsResourceId =
+                        R.array.qti_incoming_call_widget_video_receive_request_target_descriptions;
+                directionDescriptionsResourceId = R.array
+                        .qti_incoming_call_widget_video_request_target_direction_descriptions;
+                handleDrawableResourceId = R.drawable.ic_incall_video_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 342f6b4..0c01f18 100644
--- a/InCallUI/src/com/android/incallui/GlowPadWrapper.java
+++ b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
@@ -127,6 +127,12 @@
         } else if (resId == R.drawable.ic_lockscreen_decline_video) {
             mAnswerFragment.onDeclineUpgradeRequest(getContext());
             mTargetTriggered = true;
+        } else if (resId == R.drawable.qti_ic_lockscreen_answer_tx_video) {
+            mAnswerFragment.onAnswer(VideoProfile.STATE_TX_ENABLED, getContext());
+            mTargetTriggered = true;
+        } else if (resId == R.drawable.qti_ic_lockscreen_answer_rx_video) {
+            mAnswerFragment.onAnswer(VideoProfile.STATE_RX_ENABLED, getContext());
+            mTargetTriggered = true;
         } else {
             // Code should never reach here.
             Log.e(this, "Trigger detected on unhandled resource. Skipping.");
diff --git a/InCallUI/src/com/android/incallui/QtiCallUtils.java b/InCallUI/src/com/android/incallui/QtiCallUtils.java
new file mode 100644
index 0000000..ec36fac
--- /dev/null
+++ b/InCallUI/src/com/android/incallui/QtiCallUtils.java
@@ -0,0 +1,256 @@
+/**
+ * Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.incallui;
+
+
+import android.telecom.VideoProfile;
+import android.telecom.Connection.VideoProvider;
+import android.widget.Toast;
+import android.content.Context;
+import android.content.res.Resources;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.telecom.InCallService.VideoCall;
+
+import java.util.ArrayList;
+
+/**
+ * This class contains Qti specific utiltity functions.
+ */
+public class QtiCallUtils {
+
+    private static final int INVALID_INDEX = -1;
+
+    private static String LOG_TAG = "QtiCallUtils";
+
+    /**
+     * Private constructor for QtiCallUtils as we don't want to instantiate this class
+     */
+    private QtiCallUtils() {
+    }
+
+    /**
+     * This utility method checks to see if bits in the mask are enabled in the value
+     * Returns true if all bits in {@code mask} are set in {@code value}
+     */
+    public static boolean isEnabled(final int mask, final int value) {
+        return (mask & value) == mask;
+    }
+
+    /**
+     * This utility method checks to see if none of the bits in the mask are enabled in the value
+     * Returns true if none of the bits in {@code mask} are set in {@code value}
+     */
+    public static boolean isNotEnabled(final int mask, final int value) {
+        return (mask & value) == 0;
+    }
+
+    /**
+     * Method to get the video quality display string resource id given the video quality
+     */
+    public static int getVideoQualityResourceId(int videoQuality) {
+        switch (videoQuality) {
+            case VideoProfile.QUALITY_HIGH:
+                return R.string.video_quality_high;
+            case VideoProfile.QUALITY_MEDIUM:
+                return R.string.video_quality_medium;
+            case VideoProfile.QUALITY_LOW:
+                return R.string.video_quality_low;
+            default:
+                return R.string.video_quality_unknown;
+        }
+    }
+
+    /**
+     * Returns the call session resource id given the call session event
+     */
+    public static int getCallSessionResourceId(int event) {
+        switch (event) {
+            case VideoProvider.SESSION_EVENT_RX_PAUSE:
+                return R.string.player_stopped;
+            case VideoProvider.SESSION_EVENT_RX_RESUME:
+                return R.string.player_started;
+            case VideoProvider.SESSION_EVENT_CAMERA_FAILURE:
+                return R.string.camera_not_ready;
+            case VideoProvider.SESSION_EVENT_CAMERA_READY:
+                return R.string.camera_ready;
+            default:
+                return R.string.unknown_call_session_event;
+        }
+    }
+
+    /**
+     * Displays the message as a Toast on the UI
+     */
+    public static void displayToast(Context context, String msg) {
+        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+    }
+
+    /**
+     * Displays the string corresponding to the resourceId as a Toast on the UI
+     */
+    public static void displayToast(Context context, int resourceId) {
+        displayToast(context, context.getResources().getString(resourceId));
+    }
+
+    /**
+     * The function is called when Modify Call button gets pressed. The function creates and
+     * displays modify call options.
+     */
+    public static void displayModifyCallOptions(final Call call, final Context context) {
+        if (call == null) {
+            Log.d(LOG_TAG, "Can't display modify call options. Call is null");
+            return;
+        }
+
+        final ArrayList<CharSequence> items = new ArrayList<CharSequence>();
+        final ArrayList<Integer> itemToCallType = new ArrayList<Integer>();
+        final Resources res = context.getResources();
+        // Prepare the string array and mapping.
+        items.add(res.getText(R.string.modify_call_option_voice));
+        itemToCallType.add(VideoProfile.STATE_AUDIO_ONLY);
+
+        items.add(res.getText(R.string.modify_call_option_vt_rx));
+        itemToCallType.add(VideoProfile.STATE_RX_ENABLED);
+
+        items.add(res.getText(R.string.modify_call_option_vt_tx));
+        itemToCallType.add(VideoProfile.STATE_TX_ENABLED);
+
+        items.add(res.getText(R.string.modify_call_option_vt));
+        itemToCallType.add(VideoProfile.STATE_BIDIRECTIONAL);
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        builder.setTitle(R.string.modify_call_option_title);
+        final AlertDialog alert;
+
+        DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int item) {
+                Toast.makeText(context, items.get(item), Toast.LENGTH_SHORT).show();
+                final int selCallType = itemToCallType.get(item);
+                Log.v(this, "Videocall: ModifyCall: upgrade/downgrade to "
+                        + callTypeToString(selCallType));
+                VideoProfile videoProfile = new VideoProfile(selCallType);
+                changeToVideoClicked(call, videoProfile);
+                dialog.dismiss();
+            }
+        };
+        final int currUnpausedVideoState = VideoUtils.getUnPausedVideoState(call.getVideoState());
+        final int index = itemToCallType.indexOf(currUnpausedVideoState);
+        if (index == INVALID_INDEX) {
+            return;
+        }
+        builder.setSingleChoiceItems(items.toArray(new CharSequence[0]), index, listener);
+        alert = builder.create();
+        alert.show();
+    }
+
+    /**
+     * Converts the call type to string
+     */
+    public static String callTypeToString(int callType) {
+        switch (callType) {
+            case VideoProfile.STATE_BIDIRECTIONAL:
+                return "VT";
+            case VideoProfile.STATE_TX_ENABLED:
+                return "VT_TX";
+            case VideoProfile.STATE_RX_ENABLED:
+                return "VT_RX";
+        }
+        return "";
+    }
+
+    /**
+     * Sends a session modify request to the telephony framework
+     */
+    private static void changeToVideoClicked(Call call, VideoProfile videoProfile) {
+        VideoCall videoCall = call.getVideoCall();
+        if (videoCall == null) {
+            return;
+        }
+        videoCall.sendSessionModifyRequest(videoProfile);
+        call.setSessionModificationState(Call.SessionModificationState.WAITING_FOR_RESPONSE);
+    }
+
+    /**
+     * Checks the boolean flag in config file to figure out if we are going to use Qti extension or
+     * not
+     */
+    public static boolean useExt(Context context) {
+        if (context == null) {
+            Log.w(context, "Context is null...");
+        }
+        return context != null && context.getResources().getBoolean(R.bool.video_call_use_ext);
+    }
+
+    /**
+     * Returns user options for accepting an incoming video call based on Qti extension flag
+     */
+    public static int getIncomingCallAnswerOptions(Context context, boolean withSms) {
+        if (!useExt(context)) {
+            return withSms ? AnswerFragment.TARGET_SET_FOR_VIDEO_WITH_SMS :
+                    AnswerFragment.TARGET_SET_FOR_VIDEO_WITHOUT_SMS;
+        } else {
+            return withSms ? AnswerFragment.TARGET_SET_FOR_QTI_VIDEO_WITH_SMS :
+                    AnswerFragment.TARGET_SET_FOR_QTI_VIDEO_WITHOUT_SMS;
+        }
+    }
+
+    /**
+     * Returns the session modification user options based on session modify request video states
+     * (current video state and modify request video state)
+     */
+    public static int getSessionModificationOptions(Context context, int currentVideoState,
+            int modifyToVideoState) {
+        if (!useExt(context)) {
+            return AnswerFragment.TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST;
+        }
+
+        if (showVideoUpgradeOptions(currentVideoState, modifyToVideoState)) {
+            return AnswerFragment.TARGET_SET_FOR_QTI_VIDEO_ACCEPT_REJECT_REQUEST;
+        } else if (isEnabled(VideoProfile.STATE_BIDIRECTIONAL, modifyToVideoState)) {
+            return AnswerFragment.TARGET_SET_FOR_QTI_BIDIRECTIONAL_VIDEO_ACCEPT_REJECT_REQUEST;
+        } else if (isEnabled(VideoProfile.STATE_TX_ENABLED, modifyToVideoState)) {
+            return AnswerFragment.TARGET_SET_FOR_QTI_VIDEO_TRANSMIT_ACCEPT_REJECT_REQUEST;
+        } else if (isEnabled(VideoProfile.STATE_RX_ENABLED, modifyToVideoState)) {
+            return AnswerFragment.TARGET_SET_FOR_QTI_VIDEO_RECEIVE_ACCEPT_REJECT_REQUEST;
+        }
+        return AnswerFragment.TARGET_SET_FOR_QTI_VIDEO_ACCEPT_REJECT_REQUEST;
+    }
+
+    /**
+     * Returns true if we are upgrading from Voice to Bidirectional video, false otherwise
+     */
+    private static boolean showVideoUpgradeOptions(int currentVideoState, int modifyToVideoState) {
+        return currentVideoState == VideoProfile.STATE_AUDIO_ONLY &&
+                isEnabled(VideoProfile.STATE_BIDIRECTIONAL, modifyToVideoState);
+    }
+}