Merge "MSIM: Dismiss pending dialog on incoming call notification." into atel.lnx.2.0-dev
diff --git a/Android.mk b/Android.mk
index 16c4adc..c8e950d 100755
--- a/Android.mk
+++ b/Android.mk
@@ -30,6 +30,8 @@
     $(phone_common_dir)/src-N
 
 LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
+LOCAL_SRC_FILES += src/org/codeaurora/presenceserv/IPresenceService.aidl \
+                   src/org/codeaurora/presenceserv/IPresenceServiceCB.aidl
 LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs)) \
     $(support_library_root_dir)/v7/cardview/res \
     $(support_library_root_dir)/v7/recyclerview/res \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 283a836..4930315 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -42,6 +42,7 @@
     <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
     <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
@@ -59,6 +60,7 @@
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <!-- This tells the activity manager to not delay any of our activity
      start requests, even if they happen immediately after the user
      presses home. -->
diff --git a/InCallUI/res/layout/call_button_fragment.xml b/InCallUI/res/layout/call_button_fragment.xml
index 2e9e40b..9e3ec0a 100644
--- a/InCallUI/res/layout/call_button_fragment.xml
+++ b/InCallUI/res/layout/call_button_fragment.xml
@@ -197,6 +197,24 @@
             android:contentDescription="@string/onscreenManageConferenceText"
             android:visibility="gone" />
 
+        <ImageButton android:id="@+id/rxtxVideoCallButton"
+            style="@style/InCallButton"
+            android:background="@drawable/btn_change_to_video"
+            android:contentDescription="@string/overflowBothCallMenuItemText"
+            android:visibility="gone" />
+
+        <ImageButton android:id="@+id/rxVedioCallButton"
+            style="@style/InCallButton"
+            android:background="@drawable/btn_change_to_hm_video"
+            android:contentDescription="@string/overflowRXCallMenuItemText"
+            android:visibility="gone" />
+
+        <ImageButton android:id="@+id/volteCallButton"
+            style="@style/InCallButton"
+            android:background="@drawable/btn_compound_audio"
+            android:contentDescription="@string/overflowVOCallMenuItemText"
+            android:visibility="gone" />
+
     </LinearLayout>
 
 </LinearLayout>
diff --git a/InCallUI/res/layout/primary_call_info.xml b/InCallUI/res/layout/primary_call_info.xml
index 1b6e01c..a9ef075 100644
--- a/InCallUI/res/layout/primary_call_info.xml
+++ b/InCallUI/res/layout/primary_call_info.xml
@@ -137,7 +137,7 @@
 
     <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="@dimen/in_call_layout_height"
         android:orientation="horizontal"
         android:clipChildren="false"
         android:clipToPadding="false">
@@ -145,7 +145,7 @@
         <ImageView android:id="@+id/hdAudioIcon"
             android:src="@drawable/ic_hd_24dp"
             android:layout_width="24dp"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
             android:layout_marginEnd="8dp"
             android:tint="@color/incall_call_banner_subtext_color"
             android:scaleType="fitCenter"
diff --git a/InCallUI/res/layout/video_call_views.xml b/InCallUI/res/layout/video_call_views.xml
index d514f6d..1926fcc 100644
--- a/InCallUI/res/layout/video_call_views.xml
+++ b/InCallUI/res/layout/video_call_views.xml
@@ -20,11 +20,15 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent" >
 
-    <TextureView
-        android:id="@+id/incomingVideo"
-        android:layout_gravity="center"
+    <FrameLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent" />
+        android:layout_height="match_parent">
+        <TextureView
+            android:id="@+id/incomingVideo"
+            android:layout_gravity="center"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+    </FrameLayout>
     <!-- The width and height are replaced at runtime based on the selected camera. -->
     <FrameLayout
         android:id="@+id/previewVideoContainer"
diff --git a/InCallUI/res/values-zh-rCN/qtistrings.xml b/InCallUI/res/values-zh-rCN/qtistrings.xml
index 1f0f2a5..63af255 100644
--- a/InCallUI/res/values-zh-rCN/qtistrings.xml
+++ b/InCallUI/res/values-zh-rCN/qtistrings.xml
@@ -40,4 +40,11 @@
     <!-- Title displayed in the overlay for incoming conference calls which include the name of the provider.
          [CHAR LIMIT=40] -->
     <string name="incoming_conf_via_template">"通过 <xliff:g id="provider_name">%s</xliff:g>会议来电"</string>
+
+    <!-- In-call screen: Modify Call Options for IMS call -->
+    <string name="modify_call_option_title">选择通话类型?</string>
+    <string name="modify_call_option_vt">双向视频</string>
+    <string name="modify_call_option_vt_tx">视频发送</string>
+    <string name="modify_call_option_vt_rx">视频接收</string>
+    <string name="modify_call_option_voice">仅限语音</string>
 </resources>
diff --git a/InCallUI/res/values/array.xml b/InCallUI/res/values/array.xml
index 7877ec8..afd9f55 100644
--- a/InCallUI/res/values/array.xml
+++ b/InCallUI/res/values/array.xml
@@ -132,4 +132,38 @@
         <item>@string/description_direction_left</item>
         <item>@null</item>
     </array>
+
+   <array name="enhance_incoming_call_widget_video_without_sms_targets">
+       <item>@drawable/ic_lockscreen_answer</item>
+       <item>@drawable/ic_enhance_answer_rx_video</item>
+       <item>@drawable/ic_lockscreen_decline</item>
+       <item>@drawable/ic_enhance_answer_video</item>
+   </array>
+   <array name="enhance_incoming_call_widget_video_with_sms_targets">
+       <item>@drawable/ic_enhance_answer_video</item>
+       <item>@drawable/ic_lockscreen_text</item>
+       <item>@drawable/ic_lockscreen_decline</item>
+       <item>@drawable/ic_lockscreen_answer</item>
+       <item>@drawable/ic_enhance_answer_rx_video</item>
+       <item>@null</item>
+   </array>
+   <array name="enhance_incoming_call_widget_video_upgrade_request_targets">
+       <item>@drawable/ic_enhance_answer_video</item>
+       <item>@null</item>
+       <item>@drawable/ic_enhance_decline_video</item>
+       <item>@drawable/ic_enhance_answer_rx_video</item>
+   </array>
+   <array name="enhance_incoming_call_bidirectional_video_accept_request_targets">
+       <item>@drawable/ic_enhance_answer_video</item>
+       <item>@drawable/ic_enhance_decline_video</item>
+   </array>
+   <array name="enhance_incoming_call_video_transmit_accept_request_targets">
+       <item>@drawable/ic_enhance_answer_tx_video</item>
+       <item>@drawable/ic_enhance_decline_video</item>
+   </array>
+   <array name="enhance_incoming_call_video_receive_accept_request_targets">
+       <item>@drawable/ic_enhance_answer_rx_video</item>
+       <item>@drawable/ic_enhance_decline_video</item>
+   </array>
+
 </resources>
diff --git a/InCallUI/res/values/config.xml b/InCallUI/res/values/config.xml
index 1512f6c..763b0e2 100644
--- a/InCallUI/res/values/config.xml
+++ b/InCallUI/res/values/config.xml
@@ -26,4 +26,8 @@
     <integer name="video_call_auto_fullscreen_timeout">5000</integer>
     <!-- When international prefix is enabled in CDMA mode, whether with international prefix -->
     <bool name="phone_number_with_intl_prefix">false</bool>
+
+    <bool name="config_regional_number_patterns_video_call">false</bool>
+     <!-- When set to true, this config enables enhance videocall ui -->
+    <bool name="config_enable_enhance_video_call_ui">false</bool>
 </resources>
diff --git a/InCallUI/res/values/dimens.xml b/InCallUI/res/values/dimens.xml
index 59da786..15520e5 100644
--- a/InCallUI/res/values/dimens.xml
+++ b/InCallUI/res/values/dimens.xml
@@ -63,6 +63,9 @@
     <dimen name="primary_call_elevation">0dp</dimen>
     <dimen name="dialpad_elevation">2dp</dimen>
 
+    <!-- layout height -->
+    <dimen name="in_call_layout_height">40dp</dimen>
+
     <!-- The InCallUI dialpad will sometimes want digits sizes that are different from dialer.
          Note: These are the default sizes for small (<600dp height) devices: larger screen sizes
          apply the values in values-h600dp/dimens.xml. -->
diff --git a/InCallUI/res/values/qticonfig.xml b/InCallUI/res/values/qticonfig.xml
index f0c7342..8483d84 100644
--- a/InCallUI/res/values/qticonfig.xml
+++ b/InCallUI/res/values/qticonfig.xml
@@ -52,4 +52,6 @@
     <bool name="add_multi_participants_enabled">false</bool>
     <!-- Config to add participant only in conferencall call-->
     <bool name="add_participant_only_in_conference">false</bool>
+    <!-- Config to if show preview before the receiver accepts a show me upgrade video call -->
+    <bool name="config_enable_modify_call_preview">false</bool>
 </resources>
diff --git a/InCallUI/res/values/qtistrings.xml b/InCallUI/res/values/qtistrings.xml
index 0c40fb6..ea8a952 100644
--- a/InCallUI/res/values/qtistrings.xml
+++ b/InCallUI/res/values/qtistrings.xml
@@ -72,11 +72,11 @@
     <string name="lte_data_usage_label">"Lte 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>
+    <string name="modify_call_option_title">Which type of call?</string>
+    <string name="modify_call_option_vt">Video bidirectional</string>
+    <string name="modify_call_option_vt_tx">Video Transmit</string>
+    <string name="modify_call_option_vt_rx">Video Receive</string>
+    <string name="modify_call_option_voice">Voice Only</string>
 
     <!-- Modify call error cause -->
     <string name="modify_call_failed_due_to_low_battery">Modify call failed due to low battery.</string>
@@ -177,4 +177,7 @@
     <string-array name="international_idp_values" translatable="false">
         <item>"0033"</item>
     </string-array>
+    <string name="video_call_downgrade_without_lte_toast">Move out of LTE coverage area downgrade the call.</string>
+    <string name="video_call">Video Calling</string>
+    <string name="video_call_cannot_upgrade">cannot accept video calls at this time</string>
 </resources>
diff --git a/InCallUI/src/com/android/incallui/AnswerPresenter.java b/InCallUI/src/com/android/incallui/AnswerPresenter.java
index 24ec7b2..b8b5185 100644
--- a/InCallUI/src/com/android/incallui/AnswerPresenter.java
+++ b/InCallUI/src/com/android/incallui/AnswerPresenter.java
@@ -163,7 +163,7 @@
         }
     }
 
-    public void onSessionModificationStateChange(int sessionModificationState) {
+    public void onSessionModificationStateChange(Call call, int sessionModificationState) {
         boolean isUpgradePending = sessionModificationState ==
                 Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST;
 
diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java
index d7289a2..db597b2 100644
--- a/InCallUI/src/com/android/incallui/CallButtonFragment.java
+++ b/InCallUI/src/com/android/incallui/CallButtonFragment.java
@@ -33,6 +33,9 @@
 import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_TRANSFER_CONSULTATIVE;
 import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_UPGRADE_TO_VIDEO;
 import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_RECORD;
+import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_RXTX_VIDEO_CALL;
+import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_RX_VIDEO_CALL;
+import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_VO_VIDEO_CALL;
 
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -44,6 +47,8 @@
 import android.graphics.drawable.StateListDrawable;
 import android.os.Bundle;
 import android.telecom.CallAudioState;
+import android.telecom.VideoProfile;
+import android.telephony.PhoneNumberUtils;
 import android.util.SparseIntArray;
 import android.view.ContextThemeWrapper;
 import android.view.HapticFeedbackConstants;
@@ -57,7 +62,9 @@
 import android.widget.PopupMenu;
 import android.widget.PopupMenu.OnDismissListener;
 import android.widget.PopupMenu.OnMenuItemClickListener;
+import android.widget.Toast;
 
+import com.android.contacts.common.CallUtil;
 import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
 import com.android.dialer.R;
 
@@ -98,7 +105,10 @@
         public static final int BUTTON_TRANSFER_ASSURED = 13;
         public static final int BUTTON_TRANSFER_CONSULTATIVE = 14;
         public static final int BUTTON_RECORD = 15;
-        public static final int BUTTON_COUNT = 16;
+        public static final int BUTTON_RXTX_VIDEO_CALL = 16;
+        public static final int BUTTON_RX_VIDEO_CALL = 17;
+        public static final int BUTTON_VO_VIDEO_CALL = 18;
+        public static final int BUTTON_COUNT = 19;
     }
 
     private SparseIntArray mButtonVisibilityMap = new SparseIntArray(BUTTON_COUNT);
@@ -121,6 +131,9 @@
     private ImageButton mConsultativeTransferButton;
     private ImageButton mAddParticipantButton;
     private ImageButton mRecordButton;
+    private ImageButton mRxTxVideoCallButton;
+    private ImageButton mRxVideoCallButton;
+    private ImageButton mVoVideoCallButton;
 
     private PopupMenu mAudioModePopup;
     private boolean mAudioModePopupVisible;
@@ -199,6 +212,12 @@
         mManageVideoCallConferenceButton.setOnClickListener(this);
         mRecordButton = (ImageButton) parent.findViewById(R.id.recordButton);
         mRecordButton.setOnClickListener(this);
+        mRxTxVideoCallButton = (ImageButton) parent.findViewById(R.id.rxtxVideoCallButton);
+        mRxTxVideoCallButton.setOnClickListener(this);
+        mRxVideoCallButton = (ImageButton) parent.findViewById(R.id.rxVedioCallButton);
+        mRxVideoCallButton.setOnClickListener(this);
+        mVoVideoCallButton = (ImageButton) parent.findViewById(R.id.volteCallButton);
+        mVoVideoCallButton.setOnClickListener(this);
         return parent;
     }
 
@@ -273,6 +292,12 @@
                 ((InCallActivity) getActivity()).stopInCallRecorder();
                 mRecordButton.setBackgroundResource(R.drawable.btn_start_record);
             }
+        } else if(id == R.id.rxtxVideoCallButton){
+            getPresenter().changeToVideo(VideoProfile.STATE_BIDIRECTIONAL);
+        } else if(id == R.id.rxVedioCallButton){
+            getPresenter().changeToVideo(VideoProfile.STATE_RX_ENABLED);
+        } else if(id == R.id.volteCallButton){
+            getPresenter().changeToVideo(VideoProfile.STATE_AUDIO_ONLY);
         } else {
             Log.wtf(this, "onClick: unexpected");
             return;
@@ -430,6 +455,9 @@
         mManageVideoCallConferenceButton.setEnabled(isEnabled);
         mAddParticipantButton.setEnabled(isEnabled);
         mRecordButton.setEnabled(isEnabled);
+        mRxTxVideoCallButton.setEnabled(isEnabled);
+        mRxVideoCallButton.setEnabled(isEnabled);
+        mVoVideoCallButton.setEnabled(isEnabled);
     }
 
     @Override
@@ -478,6 +506,12 @@
             return mConsultativeTransferButton;
         } else if (id == BUTTON_RECORD) {
             return mRecordButton;
+        } else if (id == BUTTON_RXTX_VIDEO_CALL) {
+            return mRxTxVideoCallButton;
+        } else if (id == BUTTON_RX_VIDEO_CALL) {
+            return mRxVideoCallButton;
+        } else if (id == BUTTON_VO_VIDEO_CALL) {
+            return mVoVideoCallButton;
         } else {
             Log.w(this, "Invalid button id");
             return null;
diff --git a/InCallUI/src/com/android/incallui/CallButtonPresenter.java b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
index 7f8e171..7ea2f7f 100644
--- a/InCallUI/src/com/android/incallui/CallButtonPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
@@ -31,6 +31,9 @@
 import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_TRANSFER_CONSULTATIVE;
 import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_UPGRADE_TO_VIDEO;
 import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_RECORD;
+import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_RXTX_VIDEO_CALL;
+import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_RX_VIDEO_CALL;
+import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_VO_VIDEO_CALL;
 
 import android.content.Context;
 import android.os.Build;
@@ -44,6 +47,7 @@
 
 import com.android.contacts.common.compat.CallSdkCompat;
 import com.android.contacts.common.compat.SdkVersionOverride;
+import com.android.dialer.util.PresenceHelper;
 import com.android.dialer.compat.UserManagerCompat;
 import com.android.incallui.AudioModeProvider.AudioModeListener;
 import com.android.incallui.InCallCameraManager.Listener;
@@ -69,6 +73,7 @@
     private boolean mAutomaticallyMuted = false;
     private boolean mPreviousMuteState = false;
     private static final int MAX_PARTICIPANTS_LIMIT = 6;
+    private boolean mEnhanceEnable = false;
 
     // NOTE: Capability constant definition has been duplicated to avoid bundling
     // the Dialer with Frameworks.
@@ -81,6 +86,8 @@
     public void onUiReady(CallButtonUi ui) {
         super.onUiReady(ui);
 
+        mEnhanceEnable = ui.getContext().getResources().getBoolean(
+                R.bool.config_enable_enhance_video_call_ui);
         AudioModeProvider.getInstance().addListener(this);
 
         // register for call state changes last
@@ -335,6 +342,21 @@
         mCall.setSessionModificationState(Call.SessionModificationState.WAITING_FOR_RESPONSE);
     }
 
+    public void changeToVideo(int videoState) {
+        final Context context = getUi().getContext();
+        if(mCall == null) {
+            return;
+        }
+
+        if(VideoProfile.isVideo(videoState) &&
+                !PresenceHelper.getVTCapability(mCall.getNumber())) {
+            Toast.makeText(context,context.getString(R.string.video_call_cannot_upgrade),
+                    Toast.LENGTH_SHORT).show();
+            return;
+        }
+        final VideoProfile videoProfile = new VideoProfile(videoState);
+        QtiCallUtils.changeToVideoCall(mCall, videoProfile, context);
+    }
     /**
      * Switches the camera between the front-facing and back-facing camera.
      * @param useFrontFacingCamera True if we should switch to using the front-facing camera, or
@@ -478,19 +500,33 @@
             showAddParticipant = showAddParticipant&&(call.isConferenceCall());
         }
 
+        boolean showRxTx = false;
+        boolean showRx = false;
+        boolean showVolte = false;
+
+        if (mEnhanceEnable && showUpgradeToVideo) {
+            boolean isAudioAndVtCap = (VideoProfile.isAudioOnly(mCall.getVideoState()) &&
+                    PresenceHelper.getVTCapability(call.getNumber()));
+            showRxTx = (VideoProfile.isReceptionEnabled(mCall.getVideoState()) || isAudioAndVtCap);
+            showRx = (VideoProfile.isBidirectional(mCall.getVideoState()) || isAudioAndVtCap);
+            showVolte = VideoProfile.isVideo(mCall.getVideoState());
+            Log.v(this, "updateButtonsState showRxTx = " + showRxTx +
+                    " showRx" + showRx + " showVolte = " + showVolte);
+        }
+
         ui.showButton(BUTTON_AUDIO, true);
         ui.showButton(BUTTON_SWAP, showSwap);
         ui.showButton(BUTTON_HOLD, showHold);
         ui.setHold(isCallOnHold);
         ui.showButton(BUTTON_MUTE, showMute);
         ui.showButton(BUTTON_ADD_CALL, showAddCall);
-        ui.showButton(BUTTON_UPGRADE_TO_VIDEO, showUpgradeToVideo);
+        ui.showButton(BUTTON_UPGRADE_TO_VIDEO, showUpgradeToVideo && !mEnhanceEnable);
         ui.showButton(BUTTON_DOWNGRADE_TO_AUDIO, showDowngradeToAudio && !useExt);
         ui.showButton(BUTTON_SWITCH_CAMERA, isVideo);
         ui.showButton(BUTTON_PAUSE_VIDEO, isVideo && !useExt);
         ui.showButton(BUTTON_DIALPAD, true);
         ui.showButton(BUTTON_MERGE, showMerge);
-        ui.enableAddParticipant(showAddParticipant);
+        ui.enableAddParticipant(showAddParticipant && !mEnhanceEnable);
 
         ui.showButton(BUTTON_RECORD, showRecord);
         /* Depending on the transfer capabilities, display the corresponding buttons */
@@ -507,6 +543,12 @@
             ui.showButton(BUTTON_TRANSFER_ASSURED, false);
             ui.showButton(BUTTON_TRANSFER_CONSULTATIVE, false);
         }
+        if (mEnhanceEnable) {
+            Log.v(this, "Add three new buttons");
+            ui.showButton(BUTTON_RXTX_VIDEO_CALL, showRxTx);
+            ui.showButton(BUTTON_RX_VIDEO_CALL, showRx);
+            ui.showButton(BUTTON_VO_VIDEO_CALL, showVolte);
+        }
 
         ui.updateButtonStates();
     }
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 70da98a..259de79 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -380,7 +380,7 @@
      * @param sessionModificationState The new session modification state.
      */
     @Override
-    public void onSessionModificationStateChange(int sessionModificationState) {
+    public void onSessionModificationStateChange(Call call, int sessionModificationState) {
         Log.d(this, "onSessionModificationStateChange : sessionModificationState = " +
                 sessionModificationState);
 
diff --git a/InCallUI/src/com/android/incallui/CallList.java b/InCallUI/src/com/android/incallui/CallList.java
index 14255cb..059345f 100644
--- a/InCallUI/src/com/android/incallui/CallList.java
+++ b/InCallUI/src/com/android/incallui/CallList.java
@@ -199,7 +199,7 @@
         final List<CallUpdateListener> listeners = mCallUpdateListenerMap.get(call.getId());
         if (listeners != null) {
             for (CallUpdateListener listener : listeners) {
-                listener.onSessionModificationStateChange(sessionModificationState);
+                listener.onSessionModificationStateChange(call, sessionModificationState);
             }
         }
     }
@@ -717,7 +717,7 @@
          *
          * @param sessionModificationState The new session modification state.
          */
-        public void onSessionModificationStateChange(int sessionModificationState);
+        public void onSessionModificationStateChange(Call call, int sessionModificationState);
 
         /**
          * Notifies of a change to the last forwarded number for a call.
diff --git a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
index 48e4730..d9b4dda 100644
--- a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
+++ b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java
@@ -91,6 +91,8 @@
         final int directionDescriptionsResourceId;
         final int handleDrawableResourceId;
         mGlowpad.setVideoState(videoState);
+        final boolean isEnhanceUIEnabled = getContext().getResources().getBoolean(
+                R.bool.config_enable_enhance_video_call_ui);
 
         switch (targetSet) {
             case TARGET_SET_FOR_AUDIO_WITH_SMS:
@@ -127,7 +129,12 @@
                 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;
+                if (isEnhanceUIEnabled) {
+                    targetResourceId =
+                            R.array.enhance_incoming_call_widget_video_without_sms_targets;
+                } else {
+                    targetResourceId = R.array.qti_incoming_call_widget_video_without_sms_targets;
+                }
                 targetDescriptionsResourceId =
                         R.array.qti_incoming_call_widget_video_without_sms_target_descriptions;
                 directionDescriptionsResourceId =
@@ -135,7 +142,11 @@
                 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;
+                if (isEnhanceUIEnabled) {
+                    targetResourceId = R.array.enhance_incoming_call_widget_video_with_sms_targets;
+                } else {
+                    targetResourceId = R.array.qti_incoming_call_widget_video_with_sms_targets;
+                }
                 targetDescriptionsResourceId =
                         R.array.qti_incoming_call_widget_video_with_sms_target_descriptions;
                 directionDescriptionsResourceId =
@@ -179,7 +190,12 @@
                 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;
+                if (isEnhanceUIEnabled) {
+                    targetResourceId =
+                            R.array.enhance_incoming_call_widget_video_upgrade_request_targets;
+                } else {
+                    targetResourceId = R.array.qti_incoming_call_widget_video_request_targets;
+                }
                 targetDescriptionsResourceId =
                         R.array.qti_incoming_call_widget_video_request_target_descriptions;
                 directionDescriptionsResourceId = R.array.
@@ -187,8 +203,13 @@
                 handleDrawableResourceId = R.drawable.ic_incall_video_handle;
                 break;
             case TARGET_SET_FOR_QTI_BIDIRECTIONAL_VIDEO_ACCEPT_REJECT_REQUEST:
-                targetResourceId = R.array.
+                if (isEnhanceUIEnabled) {
+                    targetResourceId = R.array.
+                        enhance_incoming_call_bidirectional_video_accept_request_targets;
+                } else {
+                    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.
@@ -196,8 +217,13 @@
                 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;
+                if (isEnhanceUIEnabled) {
+                    targetResourceId =
+                            R.array.enhance_incoming_call_video_transmit_accept_request_targets;
+                } else {
+                    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
@@ -205,8 +231,13 @@
                 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;
+                if (isEnhanceUIEnabled) {
+                    targetResourceId = R.array.
+                            enhance_incoming_call_video_receive_accept_request_targets;
+                } else {
+                    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
diff --git a/InCallUI/src/com/android/incallui/GlowPadWrapper.java b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
index bc2d4da..c88a984 100644
--- a/InCallUI/src/com/android/incallui/GlowPadWrapper.java
+++ b/InCallUI/src/com/android/incallui/GlowPadWrapper.java
@@ -115,22 +115,27 @@
         if (resId == R.drawable.ic_lockscreen_answer) {
             mAnswerFragment.onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext());
             mTargetTriggered = true;
-        } else if (resId == R.drawable.ic_lockscreen_decline) {
+        } else if (resId == R.drawable.ic_lockscreen_decline ||
+                resId == R.drawable.ic_enhance_decline_video) {
             mAnswerFragment.onDecline(getContext());
             mTargetTriggered = true;
         } else if (resId == R.drawable.ic_lockscreen_text) {
             mAnswerFragment.onText();
             mTargetTriggered = true;
-        } else if (resId == R.drawable.ic_videocam || resId == R.drawable.ic_lockscreen_answer_video) {
+        } else if (resId == R.drawable.ic_videocam ||
+                resId == R.drawable.ic_lockscreen_answer_video ||
+                resId == R.drawable.ic_enhance_answer_video) {
             mAnswerFragment.onAnswer(mVideoState, getContext());
             mTargetTriggered = true;
         } 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) {
+        } else if (resId == R.drawable.qti_ic_lockscreen_answer_tx_video ||
+                resId == R.drawable.ic_enhance_answer_tx_video) {
             mAnswerFragment.onAnswer(VideoProfile.STATE_TX_ENABLED, getContext());
             mTargetTriggered = true;
-        } else if (resId == R.drawable.qti_ic_lockscreen_answer_rx_video) {
+        } else if (resId == R.drawable.qti_ic_lockscreen_answer_rx_video ||
+                resId == R.drawable.ic_enhance_answer_rx_video) {
             mAnswerFragment.onAnswer(VideoProfile.STATE_RX_ENABLED, getContext());
             mTargetTriggered = true;
         } else if (resId == R.drawable.qti_ic_lockscreen_deflect) {
diff --git a/InCallUI/src/com/android/incallui/QtiCallUtils.java b/InCallUI/src/com/android/incallui/QtiCallUtils.java
index d6085b5..234fa4d 100644
--- a/InCallUI/src/com/android/incallui/QtiCallUtils.java
+++ b/InCallUI/src/com/android/incallui/QtiCallUtils.java
@@ -182,7 +182,7 @@
                 Log.v(this, "Videocall: ModifyCall: upgrade/downgrade to "
                         + callTypeToString(selCallType));
                 VideoProfile videoProfile = new VideoProfile(selCallType);
-                changeToVideoClicked(call, videoProfile);
+                changeToVideoClicked(call, videoProfile, context);
                 dialog.dismiss();
             }
         };
@@ -193,6 +193,9 @@
         alert.show();
     }
 
+    public static void changeToVideoCall(Call call, VideoProfile videoProfile, Context context) {
+            changeToVideoClicked(call, videoProfile, context);
+    }
     /**
      * Converts the call type to string
      */
@@ -212,11 +215,18 @@
      * Sends a session modify request to the telephony framework
      */
     private static void changeToVideoClicked(Call call, VideoProfile videoProfile) {
+        changeToVideoClicked(call, videoProfile, null);
+    }
+
+    private static void changeToVideoClicked(Call call, VideoProfile videoProfile, Context ctx) {
         VideoCall videoCall = call.getVideoCall();
         if (videoCall == null) {
             return;
         }
         videoCall.sendSessionModifyRequest(videoProfile);
+        if (shallShowPreviewWhileWaiting(ctx)) {
+            call.setRequestedVideoState(videoProfile.getVideoState());
+        }
         call.setSessionModificationState(Call.SessionModificationState.WAITING_FOR_RESPONSE);
         InCallAudioManager.getInstance().onModifyCallClicked(call, videoProfile.getVideoState());
     }
@@ -233,6 +243,19 @@
     }
 
     /**
+     * Checks the boolean flag in config file to figure out if it support preview before the accept
+     * video call or not
+     */
+    public static boolean shallShowPreviewWhileWaiting(Context context) {
+        if (context == null) {
+            Log.w(context, "Context is null...");
+            return false;
+        }
+        return context.getResources().getBoolean(
+                R.bool.config_enable_modify_call_preview);
+    }
+
+    /**
      * Returns user options for accepting an incoming video call based on Qti extension flag
      */
     public static int getIncomingCallAnswerOptions(Context context, int videoState,
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index 9504be1..8c09ff3 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -876,7 +876,7 @@
      * @param sessionModificationState The new session modification state.
      */
     @Override
-    public void onSessionModificationStateChange(int sessionModificationState) {
+    public void onSessionModificationStateChange(Call call, int sessionModificationState) {
         if (sessionModificationState == Call.SessionModificationState.NO_REQUEST) {
             if (mCallId != null) {
                 CallList.getInstance().removeCallUpdateListener(mCallId, this);
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index 2059519..eab6ca2 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -71,7 +71,8 @@
 public class VideoCallPresenter extends Presenter<VideoCallPresenter.VideoCallUi> implements
         IncomingCallListener, InCallOrientationListener, InCallStateListener,
         InCallDetailsListener, SurfaceChangeListener, VideoEventListener,
-        InCallPresenter.InCallEventListener, InCallUiStateNotifierListener {
+        InCallPresenter.InCallEventListener, InCallUiStateNotifierListener,
+        CallList.CallUpdateListener {
     public static final String TAG = "VideoCallPresenter";
 
     public static final boolean DEBUG = false;
@@ -291,6 +292,9 @@
         InCallVideoCallCallbackNotifier.getInstance().removeSurfaceChangeListener(this);
         InCallVideoCallCallbackNotifier.getInstance().removeVideoEventListener(this);
         InCallUiStateNotifier.getInstance().removeListener(this);
+        if(mPrimaryCall != null) {
+            CallList.getInstance().removeCallUpdateListener(mPrimaryCall.getId(), this);
+        }
     }
 
     /**
@@ -403,6 +407,10 @@
      * @param surfaceId The video surface receiving the click.
      */
     public void onSurfaceClick(int surfaceId) {
+        if (!mIsVideoMode) {
+            Log.d(this, "onSurfaceClick: Not in video mode ignoring.");
+            return;
+        }
         switch (surfaceId) {
             case VideoCallFragment.SURFACE_DISPLAY:
                 boolean isFullscreen = InCallPresenter.getInstance().toggleFullscreenMode();
@@ -522,8 +530,8 @@
     }
 
     private void checkForVideoStateChange(Call call) {
-        final boolean isVideoCall = VideoUtils.isVideoCall(call);
-        final boolean hasVideoStateChanged = mCurrentVideoState != call.getVideoState();
+        boolean isVideoCall = VideoUtils.isVideoCall(call);
+        boolean hasVideoStateChanged = mCurrentVideoState != call.getVideoState();
 
         Log.d(this, "checkForVideoStateChange: isVideoCall= " + isVideoCall
                 + " hasVideoStateChanged=" + hasVideoStateChanged + " isVideoMode="
@@ -531,6 +539,11 @@
                 VideoProfile.videoStateToString(mCurrentVideoState) + " newVideoState: "
                 + VideoProfile.videoStateToString(call.getVideoState()));
 
+        if (isModifyCallPreview(mContext, call)) {
+            isVideoCall |= VideoUtils.isVideoCall(call.getRequestedVideoState());
+            hasVideoStateChanged |= mCurrentVideoState != call.getRequestedVideoState();
+         }
+
         if (!hasVideoStateChanged) {
             return;
         }
@@ -589,6 +602,7 @@
         Log.d(this, "onPrimaryCallChanged: isVideoCall=" + isVideoCall + " isVideoMode="
                 + isVideoMode);
 
+        listenToCallUpdates(newPrimaryCall);
         if (!isVideoCall && isVideoMode) {
             // Terminate video mode if new primary call is not a video call
             // and we are currently in video mode.
@@ -728,6 +742,11 @@
             Log.e(this, "Error VideoCallUi is null so returning");
             return;
         }
+        if (isModifyCallPreview(mContext, call)) {
+           Log.d(this, "modifying video state = " + newVideoState +
+                " to video state: " + call.getRequestedVideoState());
+           newVideoState = call.getRequestedVideoState();
+        }
 
         showVideoUi(newVideoState, call.getState(), call.isConferenceCall());
 
@@ -1211,7 +1230,7 @@
         return ((audioRoute & audioRouteMask) != 0);
     }
 
-    private static void updateCameraSelection(Call call) {
+    private void updateCameraSelection(Call call) {
         Log.d(TAG, "updateCameraSelection: call=" + call);
         Log.d(TAG, "updateCameraSelection: call=" + toSimpleString(call));
 
@@ -1226,6 +1245,12 @@
                     + " Setting camera direction to default value (CAMERA_DIRECTION_UNKNOWN)");
         }
 
+        // for preview scenario if it is supported
+        else if(isModifyCallPreview(mContext, call)) {
+            cameraDir = toCameraDirection(call.getRequestedVideoState());
+            call.getVideoSettings().setCameraDir(cameraDir);
+        }
+
         // Clear camera direction if this is not a video call.
         else if (VideoUtils.isAudioCall(call)) {
             cameraDir = Call.VideoSettings.CAMERA_DIRECTION_UNKNOWN;
@@ -1404,4 +1429,69 @@
         void setPreviewRotation(int orientation);
         void showOutgoingVideoView(boolean show);
     }
+
+    /**
+     * Returns true if camera preview shall be shown till remote user react on the request.
+     */
+    private static boolean isModifyCallPreview(Context ctx, Call call) {
+        if (call == null || !QtiCallUtils.shallShowPreviewWhileWaiting(ctx)) {
+            return false;
+        }
+        return (call.getSessionModificationState() ==
+                Call.SessionModificationState.WAITING_FOR_RESPONSE) &&
+                VideoProfile.isTransmissionEnabled(call.getRequestedVideoState());
+    }
+
+    private void listenToCallUpdates(Call call) {
+        if (!QtiCallUtils.shallShowPreviewWhileWaiting(mContext)) {
+            return;
+        }
+
+        if (mPrimaryCall != null) {
+            CallList.getInstance().removeCallUpdateListener(mPrimaryCall.getId(), this);
+        }
+
+        if (call != null) {
+            CallList.getInstance().addCallUpdateListener(call.getId(), this);
+        }
+    }
+
+    @Override
+    public void onSessionModificationStateChange(Call call, int sessionModificationState) {
+        Log.d(this, "onSessionModificationStateChange : sessionModificationState = " +
+                sessionModificationState + " call:" + call);
+        if (call != mPrimaryCall ||
+                (sessionModificationState == Call.SessionModificationState.NO_REQUEST)) {
+            return;
+        }
+        if (!VideoProfile.isTransmissionEnabled(call.getRequestedVideoState())) {
+           call.setRequestedVideoState(VideoProfile.STATE_AUDIO_ONLY);
+           return;
+        }
+
+        if (sessionModificationState != Call.SessionModificationState.WAITING_FOR_RESPONSE) {
+            call.setRequestedVideoState(VideoProfile.STATE_AUDIO_ONLY);
+        }
+
+        checkForVideoStateChange(call);
+
+        if (sessionModificationState == Call.SessionModificationState.REQUEST_REJECTED
+                || sessionModificationState == Call.SessionModificationState.REQUEST_FAILED
+                || sessionModificationState ==
+                Call.SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT) {
+             mCurrentVideoState = call.getVideoState();
+        }
+    }
+
+    @Override
+    public void onLastForwardedNumberChange() {
+    }
+
+    @Override
+    public void onCallChanged(Call call) {
+    }
+
+    @Override
+    public void onChildNumberChange() {
+    }
 }
diff --git a/res/drawable-hdpi/fab_ic_wificall.png b/res/drawable-hdpi/fab_ic_wificall.png
new file mode 100755
index 0000000..1794845
--- /dev/null
+++ b/res/drawable-hdpi/fab_ic_wificall.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_hm_videocam.png b/res/drawable-hdpi/ic_hm_videocam.png
new file mode 100644
index 0000000..f80c2f3
--- /dev/null
+++ b/res/drawable-hdpi/ic_hm_videocam.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_m_videocam.png b/res/drawable-hdpi/ic_m_videocam.png
new file mode 100644
index 0000000..7724a8d
--- /dev/null
+++ b/res/drawable-hdpi/ic_m_videocam.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_videocam_off.png b/res/drawable-hdpi/ic_videocam_off.png
new file mode 100644
index 0000000..f59144c
--- /dev/null
+++ b/res/drawable-hdpi/ic_videocam_off.png
Binary files differ
diff --git a/res/drawable-hdpi/wifi_calling_on_notification.png b/res/drawable-hdpi/wifi_calling_on_notification.png
new file mode 100755
index 0000000..fc34ae3
--- /dev/null
+++ b/res/drawable-hdpi/wifi_calling_on_notification.png
Binary files differ
diff --git a/res/drawable-mdpi/fab_ic_wificall.png b/res/drawable-mdpi/fab_ic_wificall.png
new file mode 100755
index 0000000..611f0d2
--- /dev/null
+++ b/res/drawable-mdpi/fab_ic_wificall.png
Binary files differ
diff --git a/res/drawable-xhdpi/fab_ic_wificall.png b/res/drawable-xhdpi/fab_ic_wificall.png
new file mode 100755
index 0000000..f4d522e
--- /dev/null
+++ b/res/drawable-xhdpi/fab_ic_wificall.png
Binary files differ
diff --git a/res/drawable-xhdpi/wifi_calling_on_notification.png b/res/drawable-xhdpi/wifi_calling_on_notification.png
new file mode 100755
index 0000000..2c11f32
--- /dev/null
+++ b/res/drawable-xhdpi/wifi_calling_on_notification.png
Binary files differ
diff --git a/res/drawable-xxhdpi/fab_ic_wificall.png b/res/drawable-xxhdpi/fab_ic_wificall.png
new file mode 100755
index 0000000..ef9d17d
--- /dev/null
+++ b/res/drawable-xxhdpi/fab_ic_wificall.png
Binary files differ
diff --git a/res/drawable-xxhdpi/wifi_calling_on_notification.png b/res/drawable-xxhdpi/wifi_calling_on_notification.png
new file mode 100755
index 0000000..23bb6f9
--- /dev/null
+++ b/res/drawable-xxhdpi/wifi_calling_on_notification.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/fab_ic_wificall.png b/res/drawable-xxxhdpi/fab_ic_wificall.png
new file mode 100755
index 0000000..4d78f05
--- /dev/null
+++ b/res/drawable-xxxhdpi/fab_ic_wificall.png
Binary files differ
diff --git a/res/drawable/btn_change_to_hm_video.xml b/res/drawable/btn_change_to_hm_video.xml
new file mode 100644
index 0000000..af23bc2
--- /dev/null
+++ b/res/drawable/btn_change_to_hm_video.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:id="@+id/backgroundItem"
+          android:drawable="@drawable/btn_background" />
+
+    <item>
+        <bitmap android:src="@drawable/ic_hm_videocam"
+            android:gravity="center"
+            android:tint="@color/selectable_icon_tint"
+            android:autoMirrored="true" />
+    </item>
+
+</layer-list>
diff --git a/res/drawable/ic_enhance_answer_rx_video.xml b/res/drawable/ic_enhance_answer_rx_video.xml
new file mode 100644
index 0000000..0dedbcb
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_rx_video.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<!-- 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/ic_enhance_answer_rx_video_normal_layer"/>
+    <item
+        android:state_enabled="true" android:state_active="true"  android:state_focused="false"
+        android:drawable="@drawable/ic_enhance_answer_rx_video_activated_layer" />
+    <item
+        android:state_enabled="true" android:state_active="false"  android:state_focused="true"
+        android:drawable="@drawable/ic_enhance_answer_rx_video_activated_layer" />
+</selector>
diff --git a/res/drawable/ic_enhance_answer_rx_video_activated_layer.xml b/res/drawable/ic_enhance_answer_rx_video_activated_layer.xml
new file mode 100644
index 0000000..e0e19d5
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_rx_video_activated_layer.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/fab_blue" />
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/ic_hm_videocam"
+            android:tint="@color/glowpad_widget_active_color"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/res/drawable/ic_enhance_answer_rx_video_normal_layer.xml b/res/drawable/ic_enhance_answer_rx_video_normal_layer.xml
new file mode 100644
index 0000000..2d49b1d
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_rx_video_normal_layer.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<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_hm_videocam"
+            android:tint="@color/glowpad_call_widget_normal_tint"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/res/drawable/ic_enhance_answer_tx_video.xml b/res/drawable/ic_enhance_answer_tx_video.xml
new file mode 100644
index 0000000..33ba0e1
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_tx_video.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<!-- 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/ic_enhance_answer_tx_video_normal_layer"/>
+    <item
+        android:state_enabled="true" android:state_active="true"  android:state_focused="false"
+        android:drawable="@drawable/ic_enhance_answer_tx_video_activated_layer" />
+    <item
+        android:state_enabled="true" android:state_active="false"  android:state_focused="true"
+        android:drawable="@drawable/ic_enhance_answer_tx_video_activated_layer" />
+</selector>
diff --git a/res/drawable/ic_enhance_answer_tx_video_activated_layer.xml b/res/drawable/ic_enhance_answer_tx_video_activated_layer.xml
new file mode 100644
index 0000000..76e04e9
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_tx_video_activated_layer.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/fab_blue" />
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/ic_m_videocam"
+            android:tint="@color/glowpad_widget_active_color"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/res/drawable/ic_enhance_answer_tx_video_normal_layer.xml b/res/drawable/ic_enhance_answer_tx_video_normal_layer.xml
new file mode 100644
index 0000000..95d6c81
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_tx_video_normal_layer.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<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_m_videocam"
+            android:tint="@color/glowpad_call_widget_normal_tint"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/res/drawable/ic_enhance_answer_video.xml b/res/drawable/ic_enhance_answer_video.xml
new file mode 100644
index 0000000..a79cd97
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_video.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<!-- 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/ic_enhance_answer_video_normal_layer"/>
+    <item
+        android:state_enabled="true" android:state_active="true"  android:state_focused="false"
+        android:drawable="@drawable/ic_enhance_answer_video_activated_layer" />
+   <item
+        android:state_enabled="true" android:state_active="false"  android:state_focused="true"
+        android:drawable="@drawable/ic_enhance_answer_video_activated_layer" />
+</selector>
diff --git a/res/drawable/ic_enhance_answer_video_activated_layer.xml b/res/drawable/ic_enhance_answer_video_activated_layer.xml
new file mode 100644
index 0000000..76e04e9
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_video_activated_layer.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/fab_blue" />
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/ic_m_videocam"
+            android:tint="@color/glowpad_widget_active_color"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/res/drawable/ic_enhance_answer_video_normal_layer.xml b/res/drawable/ic_enhance_answer_video_normal_layer.xml
new file mode 100644
index 0000000..95d6c81
--- /dev/null
+++ b/res/drawable/ic_enhance_answer_video_normal_layer.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<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_m_videocam"
+            android:tint="@color/glowpad_call_widget_normal_tint"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/res/drawable/ic_enhance_decline_video.xml b/res/drawable/ic_enhance_decline_video.xml
new file mode 100644
index 0000000..854f7a2
--- /dev/null
+++ b/res/drawable/ic_enhance_decline_video.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<!-- 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/ic_enhance_decline_video_normal_layer"/>
+    <item
+        android:state_enabled="true" android:state_active="true"  android:state_focused="false"
+        android:drawable="@drawable/ic_enhance_decline_video_activated_layer" />
+   <item
+        android:state_enabled="true" android:state_active="false"  android:state_focused="true"
+        android:drawable="@drawable/ic_enhance_decline_video_activated_layer" />
+</selector>
diff --git a/res/drawable/ic_enhance_decline_video_activated_layer.xml b/res/drawable/ic_enhance_decline_video_activated_layer.xml
new file mode 100644
index 0000000..074fe95
--- /dev/null
+++ b/res/drawable/ic_enhance_decline_video_activated_layer.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<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_videocam_off"
+            android:tint="#ffffff"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/res/drawable/ic_enhance_decline_video_normal_layer.xml b/res/drawable/ic_enhance_decline_video_normal_layer.xml
new file mode 100644
index 0000000..30c7d9c
--- /dev/null
+++ b/res/drawable/ic_enhance_decline_video_normal_layer.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2015, 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.
+-->
+<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="56dp"
+                android:height="56dp" />
+        </shape>
+    </item>
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/ic_videocam_off"
+            android:tint="#0288d1"
+            android:autoMirrored="true" />
+    </item>
+</layer-list>
diff --git a/res/drawable/volte_video.xml b/res/drawable/volte_video.xml
new file mode 100644
index 0000000..0008559
--- /dev/null
+++ b/res/drawable/volte_video.xml
@@ -0,0 +1,36 @@
+<!--Copyright (c) 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. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="13dp"
+    android:height="11dp"
+    android:autoMirrored="true"
+    android:viewportHeight="11.0"
+    android:viewportWidth="13.0">
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M6.627,8.712c-0.404,0 -0.992,-0.063 -1.357,-0.185c-0.113,-0.039 -0.244,-0.01 -0.332,0.076L4.221,9.322C3.3,8.85 2.544,7.968 2.076,7.047l0.716,-0.718c0.091,-0.09 0.117,-0.218 0.081,-0.332c-0.12,-0.364 -0.186,-0.755 -0.186,-1.162c0,-0.181 -0.146,-0.326 -0.326,-0.326H1.223c-0.18,0 -0.326,0.146 -0.326,0.326c0,3.058 2.615,5.665 5.672,5.665c0.179,0 0.324,-0.146 0.324,-0.326V9.037C6.895,8.859 6.807,8.712 6.627,8.712zM10.857,0.5H4.212c-0.453,0 -0.683,0.379 -0.683,0.814v6.33c0,0.192 0.05,0.306 0.132,0.465C3.84,8.259 3.928,8.343 4.425,8.343l0.483,-0.483c0.188,-0.186 0.477,-0.254 0.725,-0.17C5.95,7.794 6.286,7.848 6.629,7.848c0.391,0 0.708,0.551 0.708,0.94v0.022h3.595c0.221,0 0.596,-0.19 0.596,-0.554V1.246C11.527,0.893 11.25,0.5 10.857,0.5zM4.561,7.166V1.514h5.972l0.001,5.652H4.561zM7.555,4.229c0.598,0 1.078,-0.48 1.078,-1.078c0,-0.599 -0.48,-1.137 -1.078,-1.137c-0.599,0 -1.08,0.538 -1.08,1.137C6.475,3.748 6.955,4.229 7.555,4.229zM8.178,4.877c-0.121,0 -1.02,-0.027 -1.186,-0.027c-0.506,0 -1.746,0.789 -1.746,0.899v0.76L9.87,6.492V5.746C9.869,5.624 8.504,4.877 8.178,4.877z" />
+</vector>
diff --git a/res/drawable/volte_voice.xml b/res/drawable/volte_voice.xml
new file mode 100644
index 0000000..1ce76fb
--- /dev/null
+++ b/res/drawable/volte_voice.xml
@@ -0,0 +1,36 @@
+<!--Copyright (c) 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. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="13dp"
+    android:height="11dp"
+    android:autoMirrored="true"
+    android:viewportHeight="11.0"
+    android:viewportWidth="13.0">
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M8.336,7.479c-0.574,0 -1.091,-0.093 -1.609,-0.264C6.564,7.158 6.379,7.199 6.254,7.326l-1.02,1.021C3.922,7.674 2.848,6.604 2.178,5.291L3.198,4.27c0.129,-0.13 0.167,-0.311 0.116,-0.475C3.143,3.276 3.05,2.586 3.05,2.006c0,-0.256 -0.209,-0.465 -0.464,-0.465H0.964C0.709,1.541 0.5,1.75 0.5,2.006c0,4.353 3.482,8.017 7.836,8.017c0.255,0 0.464,-0.21 0.464,-0.465V7.942C8.8,7.687 8.591,7.479 8.336,7.479zM5.453,4.054l0.689,-2.511H5.604l-0.402,1.82l-0.4,-1.82H4.266L4.95,4.054H5.453zM6.426,3.854c0.063,0.077 0.139,0.135 0.227,0.174c0.09,0.039 0.188,0.06 0.3,0.06c0.108,0 0.208,-0.021 0.296,-0.06c0.089,-0.039 0.165,-0.098 0.227,-0.174c0.063,-0.076 0.11,-0.171 0.145,-0.284c0.033,-0.113 0.05,-0.242 0.05,-0.389V3.059c0,-0.146 -0.019,-0.275 -0.052,-0.389C7.584,2.558 7.536,2.463 7.473,2.386C7.41,2.31 7.336,2.25 7.246,2.211c-0.088,-0.041 -0.188,-0.06 -0.298,-0.06c-0.109,0 -0.208,0.021 -0.296,0.06S6.488,2.31 6.426,2.386C6.364,2.463 6.316,2.558 6.282,2.67C6.248,2.783 6.23,2.912 6.23,3.059v0.123c0,0.146 0.018,0.277 0.052,0.389C6.316,3.684 6.364,3.777 6.426,3.854zM6.697,3.06c0,-0.17 0.021,-0.297 0.066,-0.378C6.809,2.6 6.87,2.558 6.949,2.558c0.082,0 0.145,0.042 0.189,0.124S7.205,2.89 7.205,3.06v0.123c0,0.173 -0.021,0.3 -0.063,0.38c-0.043,0.08 -0.106,0.12 -0.191,0.12c-0.08,0 -0.143,-0.041 -0.188,-0.12c-0.046,-0.08 -0.068,-0.207 -0.068,-0.38V3.06H6.697zM8.479,1.541H7.997v2.512h1.329v-0.42H8.48L8.479,1.541L8.479,1.541zM9.178,1.965h0.58v2.089h0.484V1.965h0.59V1.543H9.177L9.178,1.965L9.178,1.965zM11.609,3.633V2.967h0.75V2.558h-0.75V1.965h0.886V1.543h-1.368v2.511h1.372V3.633H11.609L11.609,3.633z" />
+</vector>
diff --git a/res/drawable/wifi_calling.xml b/res/drawable/wifi_calling.xml
new file mode 100644
index 0000000..87849c5
--- /dev/null
+++ b/res/drawable/wifi_calling.xml
@@ -0,0 +1,36 @@
+<!--Copyright (c) 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. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="13dp"
+    android:height="11dp"
+    android:autoMirrored="true"
+    android:viewportHeight="11.0"
+    android:viewportWidth="13.75">
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M8.608,7.242c-0.598,0 -1.223,-0.095 -1.762,-0.272C6.679,6.912 6.485,6.955 6.354,7.084L5.294,8.146C3.931,7.447 2.813,6.332 2.118,4.97l1.061,-1.062C3.313,3.774 3.352,3.586 3.3,3.416C3.122,2.877 3.024,2.299 3.024,1.697c0,-0.266 -0.217,-0.482 -0.48,-0.482H0.856c-0.266,0 -0.48,0.217 -0.48,0.482c0,4.525 3.707,8.193 8.233,8.193c0.265,0 0.481,-0.217 0.481,-0.482V7.727C9.089,7.459 8.874,7.242 8.608,7.242zM5.136,3.783l0.705,-2.574H5.29L4.878,3.076L4.466,1.209H3.919L4.62,3.783H5.136zM6.134,3.58c0.063,0.078 0.142,0.139 0.232,0.179c0.09,0.04 0.191,0.06 0.305,0.06s0.215,-0.02 0.305,-0.06c0.091,-0.04 0.168,-0.101 0.232,-0.179C7.271,3.5 7.319,3.404 7.354,3.289C7.389,3.174 7.405,3.041 7.405,2.89V2.765c0,-0.149 -0.018,-0.282 -0.052,-0.397C7.318,2.252 7.27,2.154 7.206,2.076c-0.063,-0.08 -0.143,-0.14 -0.232,-0.181C6.882,1.854 6.78,1.834 6.667,1.834c-0.111,0 -0.213,0.021 -0.304,0.062c-0.09,0.041 -0.167,0.101 -0.231,0.181C6.069,2.154 6.02,2.252 5.984,2.367C5.95,2.483 5.933,2.615 5.933,2.765V2.89c0,0.151 0.018,0.284 0.052,0.399C6.02,3.404 6.069,3.502 6.134,3.58zM6.411,2.766c0,-0.174 0.021,-0.305 0.067,-0.389s0.108,-0.125 0.188,-0.125c0.084,0 0.149,0.041 0.195,0.125c0.047,0.084 0.068,0.215 0.068,0.389v0.125c0,0.178 -0.021,0.309 -0.064,0.391C6.822,3.363 6.757,3.404 6.671,3.404c-0.082,0 -0.146,-0.041 -0.192,-0.123S6.409,3.068 6.409,2.891V2.766H6.411zM9.333,2.828L9.046,1.211H8.63L8.344,2.826L8.112,1.211H7.62l0.438,2.574h0.497l0.283,-1.518l0.285,1.518H9.62l0.437,-2.574h-0.49L9.333,2.828zM10.764,1.185c-0.022,-0.022 -0.05,-0.042 -0.081,-0.054C10.65,1.117 10.614,1.11 10.575,1.11s-0.074,0.007 -0.105,0.021c-0.031,0.013 -0.061,0.031 -0.081,0.054c-0.022,0.024 -0.041,0.052 -0.054,0.084s-0.019,0.067 -0.019,0.106s0.006,0.076 0.019,0.107c0.013,0.032 0.029,0.061 0.054,0.085c0.021,0.023 0.049,0.042 0.081,0.056c0.031,0.013 0.066,0.02 0.105,0.02s0.075,-0.006 0.107,-0.02c0.031,-0.014 0.059,-0.032 0.081,-0.056c0.022,-0.024 0.04,-0.053 0.052,-0.085c0.014,-0.033 0.02,-0.068 0.02,-0.107s-0.006,-0.074 -0.02,-0.106C10.804,1.236 10.786,1.209 10.764,1.185zM10.339,3.783h0.478V1.871h-0.478V3.783zM11.226,3.783h0.493v-1.05h0.769V2.303h-0.769v-0.66h0.862V1.209h-1.355V3.783zM13.356,1.269c-0.013,-0.033 -0.029,-0.062 -0.053,-0.084c-0.021,-0.022 -0.049,-0.042 -0.081,-0.054C13.19,1.117 13.155,1.11 13.116,1.11S13.04,1.117 13.01,1.131c-0.031,0.013 -0.06,0.031 -0.081,0.054c-0.021,0.024 -0.04,0.052 -0.053,0.084c-0.013,0.033 -0.019,0.067 -0.019,0.106s0.006,0.076 0.019,0.107c0.013,0.032 0.029,0.061 0.053,0.085c0.021,0.023 0.05,0.042 0.081,0.056c0.032,0.013 0.067,0.02 0.106,0.02s0.075,-0.006 0.106,-0.02c0.032,-0.014 0.06,-0.032 0.081,-0.056c0.021,-0.024 0.04,-0.053 0.053,-0.085c0.012,-0.033 0.018,-0.068 0.018,-0.107S13.368,1.302 13.356,1.269zM12.878,3.783h0.479V1.871h-0.479V3.783z" />
+</vector>
diff --git a/res/layout/call_log_list_item_actions.xml b/res/layout/call_log_list_item_actions.xml
index 78203b7..4cce073 100644
--- a/res/layout/call_log_list_item_actions.xml
+++ b/res/layout/call_log_list_item_actions.xml
@@ -64,6 +64,7 @@
         style="@style/CallLogActionStyle">
 
         <ImageView
+            android:id="@+id/videoCallIcon"
             style="@style/CallLogActionIconStyle"
             android:src="@drawable/ic_videocam_24dp" />
 
diff --git a/res/values-zh-rCN/qtistrings.xml b/res/values-zh-rCN/qtistrings.xml
new file mode 100644
index 0000000..25f18c0
--- /dev/null
+++ b/res/values-zh-rCN/qtistrings.xml
@@ -0,0 +1,35 @@
+<?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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="video_call_upgrade">不能升级!</string>
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 10b689e..8b1fa55 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -142,4 +142,5 @@
     <color name="searchview_edittext">#59ffffff</color>
     <color name="no_call_log">#42000000</color>
     <color name="list_all_call">#d3000000</color>
+    <bool name="config_regional_presence_enable">false</bool>
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 49babee..614cdf2 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -30,8 +30,7 @@
  */
 -->
 <resources>
-  <bool name="config_regional_call_data_usage_enable">true</bool>
-  <bool name="config_regional_pup_no_available_network">true</bool>
-  <bool name="config_regional_call_data_usage_enable">false</bool>
   <bool name="config_regional_video_call_welcome_dialog">false</bool>
+  <bool name="config_regional_pup_no_available_network">false</bool>
+  <bool name="config_regional_call_data_usage_enable">false</bool>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4f89b77..6d94d8e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -370,12 +370,39 @@
     <!-- Title for incoming 4G voice call in call details screen [CHAR LIMIT=60] -->
     <string name="type_incoming_volte">Incoming 4G voice call</string>
 
+     <!-- Title for incoming 4G video call in call details screen [CHAR LIMIT=60] -->
+    <string name="type_incoming_video_lte">Incoming 4G video call</string>
+
     <!-- Title for outgoing 4G voice call in call details screen [CHAR LIMIT=60] -->
     <string name="type_outgoing_volte">Outgoing 4G voice call</string>
 
+     <!-- Title for incoming 4G video call in call details screen [CHAR LIMIT=60] -->
+    <string name="type_outgoing_video_lte">Outgoing 4G video call</string>
+
     <!-- Title for missed 4G voice call in call details screen [CHAR LIMIT=60] -->
     <string name="type_missed_volte">Missed 4G voice call</string>
 
+     <!-- Title for missed 4G video call in call details screen [CHAR LIMIT=60] -->
+    <string name="type_missed_video_lte">Missed 4G video call</string>
+
+    <!-- Title for incoming wifi voice call in call details screen [CHAR LIMIT=60] -->
+    <string name="type_incoming_vowifi">Incoming WiFi voice call</string>
+
+     <!-- Title for incoming wifi video call in call details screen [CHAR LIMIT=60] -->
+     <string name="type_incoming_video_wifi">Incoming WiFi video call</string>
+
+    <!-- Title for outgoing wifi voice call in call details screen [CHAR LIMIT=60] -->
+    <string name="type_outgoing_vowifi">Outgoing WiFi voice call</string>
+
+     <!-- Title for outgoing wifi video call in call details screen [CHAR LIMIT=60] -->
+     <string name="type_outgoing_video_wifi">Outgoing WiFi video call</string>
+
+    <!-- Title for missed wifi voice call in call details screen [CHAR LIMIT=60] -->
+    <string name="type_missed_vowifi">Missed WiFi voice call</string>
+
+     <!-- Title for missed wifi video call in call details screen [CHAR LIMIT=60] -->
+     <string name="type_missed_video_wifi">Missed WiFi video call</string>
+
     <!-- Title for voicemail details screen -->
     <string name="type_voicemail">Voicemail</string>
 
@@ -1121,4 +1148,17 @@
     <string name="video_call_welcome_title"><b>Welcome to the new Video Calling Dialer</b></string>
     <string name="video_call_welcome_message">We all love to hear that familiar voice at the end of the line, but talking face-to-face is so much better! Here\'s what you should know to get your real-time (or FaceTime?) connections going: You\'ll need to be on 4G LTE or a Wi-Fi connection The device you\'re calling must also be video calling compatible Video calls use your high speed data You can also upgrade a voice call to a video call Check out <a>https://support.t-mobile.com/docs/DOC-23574</a> for more information.</string>
     <string name="video_call_welcome_message_repeat">Show this message every time</string>
+
+    <string name="toast_change_video_call_failed">Can not change to video call, incorrect number format</string>
+    <string name="toast_make_video_call_failed">Can not make video call, incorrect number format</string>
+    <!-- Add for enhance videocall ui -->
+    <string name="overflowBothCallMenuItemText">Video Call, show me</string>
+    <string name="overflowRXCallMenuItemText">Video Call, hide me</string>
+    <string name="overflowVOCallMenuItemText">Voice Call</string>
+    <string name="video_call">Video Calling</string>
+    <string name="call_data_info_label">Call/data Usage Timers</string>
+    <string name="call_data_info_description">Voice call usage time and data usage time</string>
+    <string name="alert_call_over_wifi">Calls will be made over Wi-Fi.</string>
+    <string name="alert_call_no_cellular_coverage">No cellular network available. Connect to available Wi-Fi to make calls.</string>
+    <string name="alert_user_connect_to_wifi_for_call">Connect to Wi-Fi to make calls.</string>
 </resources>
diff --git a/res/values/symbols.xml b/res/values/symbols.xml
new file mode 100644
index 0000000..2b1c756
--- /dev/null
+++ b/res/values/symbols.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (c) 2015, 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <java-symbol type="bool" name="config_regional_number_patterns_video_call" />
+</resources>
diff --git a/res/xml/video_calling_settings.xml b/res/xml/video_calling_settings.xml
new file mode 100644
index 0000000..65e1da6
--- /dev/null
+++ b/res/xml/video_calling_settings.xml
@@ -0,0 +1,39 @@
+<?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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <SwitchPreference
+        android:key="video_calling_preference"
+        android:persistent="false"
+        android:title="@string/video_call" />
+
+</PreferenceScreen>
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
old mode 100755
new mode 100644
index 8bcabd8..12304c0
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -58,6 +58,7 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.android.contacts.common.CallUtil;
 import com.android.contacts.common.dialog.ClearFrequentsDialog;
 import com.android.contacts.common.interactions.ImportExportDialogFragment;
 import com.android.contacts.common.interactions.TouchPointManager;
@@ -87,7 +88,9 @@
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.IntentUtil;
 import com.android.dialer.util.IntentUtil.CallIntentBuilder;
+import com.android.dialer.util.PresenceHelper;
 import com.android.dialer.util.TelecomUtil;
+import com.android.dialer.util.WifiCallUtils;
 import com.android.dialer.voicemail.VoicemailArchiveActivity;
 import com.android.dialer.widget.ActionBarController;
 import com.android.dialer.widget.SearchEditTextLayout;
@@ -139,7 +142,7 @@
     /* Define for Activity permission request for reading phone state */
     private static final int PERMISSION_REQUEST_CODE_PHONE_STATE_ENABLED = 0;
     private static final int PERMISSION_REQUEST_CODE_PHONE_STATE_DISABLED = 1;
-
+    private static final int PERMISSION_REQUEST_CODE_LOCATION = 2;
     /**
      * Just for backward compatibility. Should behave as same as {@link Intent#ACTION_DIAL}.
      */
@@ -212,6 +215,7 @@
     private boolean mClearSearchOnPause;
     private boolean mIsDialpadShown;
     private boolean mShowDialpadOnResume;
+    private WifiCallUtils mWifiCallUtils;
 
     /**
      * Whether or not the device is in landscape orientation.
@@ -513,6 +517,28 @@
         Trace.beginSection(TAG + " initialize smart dialing");
         mDialerDatabaseHelper = DatabaseHelperManager.getDatabaseHelper(this);
         SmartDialPrefix.initializeNanpSettings(this);
+
+        boolean isPresenceEnabled = this.getResources().getBoolean(
+                R.bool.config_regional_presence_enable);
+        if (isPresenceEnabled && !PresenceHelper.isBound()) {
+            PresenceHelper.bindService((Context) DialtactsActivity.this);
+        }
+
+        mWifiCallUtils = new WifiCallUtils();
+        if (resources.getBoolean(R.bool.config_regional_pup_no_available_network)
+                && mFirstLaunch) {
+            mWifiCallUtils.addWifiCallReadyMarqueeMessage((Context) DialtactsActivity.this);
+            if (ActivityCompat.checkSelfPermission(DialtactsActivity.this,
+                        Manifest.permission.ACCESS_COARSE_LOCATION) !=
+                        PackageManager.PERMISSION_GRANTED) {
+                    requestPermissions(
+                            new String[] {Manifest.permission.ACCESS_COARSE_LOCATION},
+                            PERMISSION_REQUEST_CODE_LOCATION);
+            } else {
+                mWifiCallUtils.showWifiCallNotification((Context) DialtactsActivity.this);
+            }
+        }
+
         Trace.endSection();
         Trace.endSection();
 
@@ -611,6 +637,14 @@
     }
 
     @Override
+    protected void onStop() {
+        if (PresenceHelper.isBound()) {
+            PresenceHelper.unbindService((Context) DialtactsActivity.this);
+        }
+        super.onStop();
+    }
+
+    @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putString(KEY_SEARCH_QUERY, mSearchQuery);
@@ -1405,6 +1439,12 @@
             // an error message.
             phoneNumber = "";
         }
+        if (getResources().getBoolean(R.bool.config_regional_number_patterns_video_call) &&
+                !CallUtil.isVideoCallNumValid(phoneNumber) &&
+                        isVideoCall && (CallUtil.isVideoEnabled(this))) {
+            Toast.makeText(this,R.string.toast_make_video_call_failed, Toast.LENGTH_LONG).show();
+            return;
+        }
 
         final Intent intent = new CallIntentBuilder(phoneNumber)
                 .setIsVideoCall(isVideoCall)
@@ -1543,6 +1583,12 @@
                             && !isCurrentTabAllContacts) ? View.VISIBLE : View.GONE);
                 }
                 break;
+            case PERMISSION_REQUEST_CODE_LOCATION:
+                if (grantResults.length > 0 && grantResults[0] ==
+                        PackageManager.PERMISSION_GRANTED) {
+                    WifiCallUtils.showWifiCallNotification((Context) DialtactsActivity.this);
+                }
+                break;
             default:
                 super.onRequestPermissionsResult(requestCode, permissions, grantResults);
         }
diff --git a/src/com/android/dialer/calllog/CallDetailHistoryAdapter.java b/src/com/android/dialer/calllog/CallDetailHistoryAdapter.java
index 85039f7..bbd632c 100644
--- a/src/com/android/dialer/calllog/CallDetailHistoryAdapter.java
+++ b/src/com/android/dialer/calllog/CallDetailHistoryAdapter.java
@@ -32,10 +32,13 @@
 import com.android.dialer.R;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.AppCompatConstants;
+import com.android.dialer.util.PresenceHelper;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
 
+import org.codeaurora.ims.utils.QtiImsExtUtils;
+
 /**
  * Adapter for a ListView containing history items from the details of a call.
  */
@@ -107,31 +110,24 @@
         TextView durationView = (TextView) result.findViewById(R.id.duration);
 
         int callType = details.callTypes[0];
-        boolean isVideoCall = (details.features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO
-                && CallUtil.isVideoEnabled(mContext);
-        boolean isVoLTE = (callType == AppCompatConstants.INCOMING_IMS_TYPE) ||
-                          (callType == AppCompatConstants.OUTGOING_IMS_TYPE) ||
-                          (callType == AppCompatConstants.MISSED_IMS_TYPE);
+        boolean isPresenceEnabled = mContext.getResources().getBoolean(
+                R.bool.config_regional_presence_enable);
+        boolean isVideoCall = (details.features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO;
+        if (isPresenceEnabled) {
+            isVideoCall &= PresenceHelper.startAvailabilityFetch(details.number.toString());
+        }
         Log.d("CallDetailHistoryAdapter", "isVideoCall = " + isVideoCall
-                    + ", isVoLTE = " + isVoLTE);
+                    + ", callType = " + callType);
         callTypeIconView.clear();
         callTypeIconView.add(callType);
-        callTypeIconView.setShowVideo(isVideoCall);
-        boolean imsCallLogEnabled = mContext.getResources()
-                .getBoolean(R.bool.ims_call_type_enabled);
-        if (!imsCallLogEnabled && isVoLTE) {
-            switch (callType) {
-                case AppCompatConstants.INCOMING_IMS_TYPE:
-                    callType = Calls.INCOMING_TYPE;
-                    break;
-                case AppCompatConstants.OUTGOING_IMS_TYPE:
-                    callType = Calls.OUTGOING_TYPE;
-                    break;
-                case AppCompatConstants.MISSED_IMS_TYPE:
-                    callType = Calls.MISSED_TYPE;
-                    break;
-                default:
-            }
+        /**
+         * Ims icon(VoLTE/VoWifi) or CarrierOne video icon will be shown if carrierOne is supported
+         * otherwise, default video icon will be shown if it is a video call.
+         */
+        if (QtiImsExtUtils.isCarrierOneSupported()) {
+             callTypeIconView.addImsOrVideoIcon(callType, isVideoCall);
+        } else {
+             callTypeIconView.setShowVideo(isVideoCall);
         }
         callTypeTextView.setText(mCallTypeHelper.getCallTypeText(callType, isVideoCall));
         // Set the date.
diff --git a/src/com/android/dialer/calllog/CallLogActivity.java b/src/com/android/dialer/calllog/CallLogActivity.java
index 32da3ac..f0c1ce6 100644
--- a/src/com/android/dialer/calllog/CallLogActivity.java
+++ b/src/com/android/dialer/calllog/CallLogActivity.java
@@ -61,7 +61,8 @@
 import com.android.dialer.logging.ScreenEvent;
 import com.android.dialer.util.DialerUtils;
 
-public class CallLogActivity extends TransactionSafeActivity implements ViewPager.OnPageChangeListener {
+public class CallLogActivity extends TransactionSafeActivity implements ViewPager.OnPageChangeListener,
+    CallLogFragment.HostInterface {
     private ViewPager mViewPager;
     private ViewPagerTabs mViewPagerTabs;
     private FragmentPagerAdapter mViewPagerAdapter;
@@ -445,6 +446,18 @@
                         LayoutParams.WRAP_CONTENT));
     }
 
+    /**
+     * Implemented to satisfy {@link CallLogFragment.HostInterface}
+     */
+    @Override
+    public void showDialpad() {
+        finish();
+        if (mInSearchUi) {
+           exitSearchUi();
+        }
+        startActivity(new Intent(CallLogActivity.this, DialtactsActivity.class));
+    }
+
     private void showInputMethod(View view) {
         InputMethodManager imm = (InputMethodManager) getSystemService(
                 Context.INPUT_METHOD_SERVICE);
diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java
index 3414129..b44d8ca 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -298,7 +298,7 @@
         mLayoutManager = new LinearLayoutManager(getActivity());
         mRecyclerView.setLayoutManager(mLayoutManager);
         mEmptyListView = (EmptyContentView) view.findViewById(R.id.empty_list_view);
-        //mEmptyListView.setImage(R.drawable.empty_call_log);
+        mEmptyListView.setImage(R.drawable.empty_call_log);
         mEmptyListView.setActionClickedListener(this);
 
         int activityType = mIsCallLogActivity ? CallLogAdapter.ACTIVITY_TYPE_CALL_LOG :
diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
index baf2e1a..4036f10 100644
--- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
+++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
@@ -20,6 +20,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.CallLog;
 import android.provider.CallLog.Calls;
@@ -60,6 +62,7 @@
 import com.android.dialer.service.ExtendedBlockingButtonRenderer;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.PhoneNumberUtil;
+import com.android.dialer.util.PresenceHelper;
 import com.android.dialer.voicemail.VoicemailPlaybackLayout;
 import com.android.dialer.voicemail.VoicemailPlaybackPresenter;
 import com.android.dialerbind.ObjectFactory;
@@ -67,6 +70,9 @@
 
 import java.util.List;
 
+import org.codeaurora.ims.utils.QtiImsExtUtils;
+import org.codeaurora.presenceserv.IPresenceService;
+
 /**
  * This is an object containing references to views contained by the call log list item. This
  * improves performance by reducing the frequency with which we need to find views by IDs.
@@ -104,6 +110,7 @@
     public View detailsButtonView;
     public View callWithNoteButtonView;
     public ImageView workIconView;
+    public ImageView videoCallIconView;
 
     /**
      * The row Id for the first call associated with the call log entry.  Used as a key for the
@@ -418,6 +425,8 @@
             videoCallButtonView = actionsView.findViewById(R.id.video_call_action);
             videoCallButtonView.setOnClickListener(this);
 
+            videoCallIconView = (ImageView) actionsView.findViewById(R.id.videoCallIcon);
+
             createNewContactButtonView = actionsView.findViewById(R.id.create_new_contact_action);
             createNewContactButtonView.setOnClickListener(this);
 
@@ -504,12 +513,22 @@
         } else {
             callButtonView.setVisibility(View.GONE);
         }
-
-        // If one of the calls had video capabilities, show the video call button.
-        if (mCallLogCache.isVideoEnabled() && canPlaceCallToNumber &&
-                phoneCallDetailsViews.callTypeIcons.isVideoShown()) {
+        boolean isPresenceEnabled = mContext.getResources().getBoolean(
+                R.bool.config_regional_presence_enable);
+        boolean showVideoCallBtn = isPresenceEnabled ? PresenceHelper.startAvailabilityFetch(number)
+                : phoneCallDetailsViews.callTypeIcons.isVideoShown();
+        //If presence is enabled,only both of sides had video capabilities,
+        //show the video call button,If not, one of the calls had video capabilities,
+        //the video call button will be shown.
+        if (mCallLogCache.isVideoEnabled() && canPlaceCallToNumber && showVideoCallBtn) {
             videoCallButtonView.setTag(IntentProvider.getReturnVideoCallIntentProvider(number));
             videoCallButtonView.setVisibility(View.VISIBLE);
+            if (QtiImsExtUtils.isCarrierOneSupported()) {
+                Drawable drawable =  mContext.getResources().getDrawable(R.drawable.volte_video);
+                drawable.setColorFilter(mContext.getResources().getColor(
+                    R.color.dialtacts_secondary_text_color), PorterDuff.Mode.MULTIPLY);
+                videoCallIconView.setImageDrawable(drawable);
+            }
         } else {
             videoCallButtonView.setVisibility(View.GONE);
         }
@@ -729,4 +748,4 @@
         viewHolder.workIconView = new ImageButton(context);
         return viewHolder;
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/dialer/calllog/CallLogQueryHandler.java b/src/com/android/dialer/calllog/CallLogQueryHandler.java
index f026420..116d9ef 100644
--- a/src/com/android/dialer/calllog/CallLogQueryHandler.java
+++ b/src/com/android/dialer/calllog/CallLogQueryHandler.java
@@ -231,18 +231,21 @@
 
             if ((callType == Calls.INCOMING_TYPE) || (callType == Calls.OUTGOING_TYPE)
                     || (callType == Calls.MISSED_TYPE)) {
-                where.append(String.format("(%s = ? OR %s = ?)",
-                        Calls.TYPE, Calls.TYPE));
+                where.append(String.format("(%s = ? OR %s = ? OR %s = ?)",
+                        Calls.TYPE, Calls.TYPE, Calls.TYPE));
             } else {
                 where.append(String.format("(%s = ?)", Calls.TYPE));
             }
             selectionArgs.add(Integer.toString(callType));
             if (callType == Calls.INCOMING_TYPE) {
                 selectionArgs.add(Integer.toString(AppCompatConstants.INCOMING_IMS_TYPE));
+                selectionArgs.add(Integer.toString(AppCompatConstants.INCOMING_WIFI_TYPE));
             } else if (callType == Calls.OUTGOING_TYPE) {
                 selectionArgs.add(Integer.toString(AppCompatConstants.OUTGOING_IMS_TYPE));
+                selectionArgs.add(Integer.toString(AppCompatConstants.OUTGOING_WIFI_TYPE));
             } else if (callType == Calls.MISSED_TYPE) {
                 selectionArgs.add(Integer.toString(AppCompatConstants.MISSED_IMS_TYPE));
+                selectionArgs.add(Integer.toString(AppCompatConstants.MISSED_WIFI_TYPE));
             }
         } else {
             // Add a clause to fetch only items of type voicemail.
@@ -285,8 +288,26 @@
 
         if (callType > CALL_TYPE_ALL) {
             where.append(" AND ");
-            where.append(String.format("(%s = ?)", Calls.TYPE));
+            if ((callType == Calls.INCOMING_TYPE) || (callType == Calls.OUTGOING_TYPE)
+                    || (callType == Calls.MISSED_TYPE)) {
+                where.append(String.format("(%s = ? OR %s = ? OR %s = ?)",
+                        Calls.TYPE, Calls.TYPE, Calls.TYPE));
+            } else {
+                // Add a clause to fetch only items of type voicemail.
+                where.append(String.format("(%s = ?)", Calls.TYPE));
+            }
+            // Add a clause to fetch only items newer than the requested date
             selectionArgs.add(Integer.toString(callType));
+            if (callType == Calls.INCOMING_TYPE) {
+                selectionArgs.add(Integer.toString(AppCompatConstants.INCOMING_IMS_TYPE));
+                selectionArgs.add(Integer.toString(AppCompatConstants.INCOMING_WIFI_TYPE));
+            } else if (callType == Calls.OUTGOING_TYPE) {
+                selectionArgs.add(Integer.toString(AppCompatConstants.OUTGOING_IMS_TYPE));
+                selectionArgs.add(Integer.toString(AppCompatConstants.OUTGOING_WIFI_TYPE));
+            } else if (callType == Calls.MISSED_TYPE) {
+                selectionArgs.add(Integer.toString(AppCompatConstants.MISSED_IMS_TYPE));
+                selectionArgs.add(Integer.toString(AppCompatConstants.MISSED_WIFI_TYPE));
+            }
         } else {
             where.append(" AND NOT ");
             where.append("(" + Calls.TYPE + " = " + Calls.VOICEMAIL_TYPE + ")");
diff --git a/src/com/android/dialer/calllog/CallTypeHelper.java b/src/com/android/dialer/calllog/CallTypeHelper.java
index 10736b2..045b604 100644
--- a/src/com/android/dialer/calllog/CallTypeHelper.java
+++ b/src/com/android/dialer/calllog/CallTypeHelper.java
@@ -43,6 +43,24 @@
     private final CharSequence mOutgoingVoLTEName;
     /** Name used to identify missed video calls. */
     private final CharSequence mMissedVoLTEName;
+    /** Name used to identify incoming videoLTE calls. */
+    private final CharSequence mIncomingVideoLTEName;
+    /** Name used to identify outgoing videoLTE calls. */
+    private final CharSequence mOutgoingVideoLTEName;
+    /** Name used to identify missed videoLTE calls. */
+    private final CharSequence mMissedVideoLTEName;
+    /** Name used to identify incoming VoWifi calls. */
+    private final CharSequence mIncomingVoWifiName;
+    /** Name used to identify outgoing VoWifi calls. */
+    private final CharSequence mOutgoingVoWifiName;
+    /** Name used to identify missed VoWifi calls. */
+    private final CharSequence mMissedVoWifiName;
+    /** Name used to identify incoming video wifi calls. */
+    private final CharSequence mIncomingVideoWifiName;
+    /** Name used to identify outgoing video wifi calls. */
+    private final CharSequence mOutgoingVideoWifiName;
+    /** Name used to identify missed video wifi calls. */
+    private final CharSequence mMissedVideoWifiName;
     /** Name used to identify voicemail calls. */
     private final CharSequence mVoicemailName;
     /** Name used to identify rejected calls. */
@@ -65,6 +83,15 @@
         mIncomingVoLTEName = resources.getString(R.string.type_incoming_volte);
         mOutgoingVoLTEName = resources.getString(R.string.type_outgoing_volte);
         mMissedVoLTEName = resources.getString(R.string.type_missed_volte);
+        mIncomingVideoLTEName = resources.getString(R.string.type_incoming_video_lte);
+        mOutgoingVideoLTEName = resources.getString(R.string.type_outgoing_video_lte);
+        mMissedVideoLTEName = resources.getString(R.string.type_missed_video_lte);
+        mIncomingVoWifiName = resources.getString(R.string.type_incoming_vowifi);
+        mOutgoingVoWifiName = resources.getString(R.string.type_outgoing_vowifi);
+        mMissedVoWifiName = resources.getString(R.string.type_missed_vowifi);
+        mIncomingVideoWifiName = resources.getString(R.string.type_incoming_video_wifi);
+        mOutgoingVideoWifiName = resources.getString(R.string.type_outgoing_video_wifi);
+        mMissedVideoWifiName = resources.getString(R.string.type_missed_video_wifi);
         mVoicemailName = resources.getString(R.string.type_voicemail);
         mRejectedName = resources.getString(R.string.type_rejected);
         mBlockedName = resources.getString(R.string.type_blocked);
@@ -84,11 +111,18 @@
 
             case AppCompatConstants.INCOMING_IMS_TYPE:
                 if (isVideoCall) {
-                    return mIncomingVideoName;
+                    return mIncomingVideoLTEName;
                 } else {
                     return mIncomingVoLTEName;
                 }
 
+            case AppCompatConstants.INCOMING_WIFI_TYPE:
+                if (isVideoCall) {
+                    return mIncomingVideoWifiName;
+                } else {
+                    return mIncomingVoWifiName;
+                }
+
             case AppCompatConstants.CALLS_OUTGOING_TYPE:
                 if (isVideoCall) {
                     return mOutgoingVideoName;
@@ -98,11 +132,18 @@
 
             case AppCompatConstants.OUTGOING_IMS_TYPE:
                 if (isVideoCall) {
-                    return mOutgoingVideoName;
+                    return mOutgoingVideoLTEName;
                 } else {
                     return mOutgoingVoLTEName;
                 }
 
+            case AppCompatConstants.OUTGOING_WIFI_TYPE:
+                if (isVideoCall) {
+                    return mOutgoingVideoWifiName;
+                } else {
+                    return mOutgoingVoWifiName;
+                }
+
             case AppCompatConstants.CALLS_MISSED_TYPE:
                 if (isVideoCall) {
                     return mMissedVideoName;
@@ -112,11 +153,18 @@
 
             case AppCompatConstants.MISSED_IMS_TYPE:
                 if (isVideoCall) {
-                    return mMissedVideoName;
+                    return mMissedVideoLTEName;
                 } else {
                     return mMissedVoLTEName;
                 }
 
+            case AppCompatConstants.MISSED_WIFI_TYPE:
+                if (isVideoCall) {
+                    return mMissedVideoWifiName;
+                } else {
+                    return mMissedVoWifiName;
+                }
+
             case AppCompatConstants.CALLS_VOICEMAIL_TYPE:
                 return mVoicemailName;
 
@@ -136,16 +184,19 @@
         switch (callType) {
             case AppCompatConstants.CALLS_INCOMING_TYPE:
             case AppCompatConstants.INCOMING_IMS_TYPE:
+            case AppCompatConstants.INCOMING_WIFI_TYPE:
                 // New incoming calls are not highlighted.
                 return null;
 
             case AppCompatConstants.CALLS_OUTGOING_TYPE:
             case AppCompatConstants.OUTGOING_IMS_TYPE:
+            case AppCompatConstants.OUTGOING_WIFI_TYPE:
                 // New outgoing calls are not highlighted.
                 return null;
 
             case AppCompatConstants.CALLS_MISSED_TYPE:
             case AppCompatConstants.MISSED_IMS_TYPE:
+            case AppCompatConstants.MISSED_WIFI_TYPE:
                 return mNewMissedColor;
 
             case AppCompatConstants.CALLS_VOICEMAIL_TYPE:
@@ -164,6 +215,8 @@
                 && callType != AppCompatConstants.CALLS_OUTGOING_TYPE
                 && callType != AppCompatConstants.INCOMING_IMS_TYPE
                 && callType != AppCompatConstants.OUTGOING_IMS_TYPE
+                && callType != AppCompatConstants.INCOMING_WIFI_TYPE
+                && callType != AppCompatConstants.OUTGOING_WIFI_TYPE
                 && callType != AppCompatConstants.CALLS_VOICEMAIL_TYPE);
     }
 }
diff --git a/src/com/android/dialer/calllog/CallTypeIconsView.java b/src/com/android/dialer/calllog/CallTypeIconsView.java
index b272ff6..56bd605 100644
--- a/src/com/android/dialer/calllog/CallTypeIconsView.java
+++ b/src/com/android/dialer/calllog/CallTypeIconsView.java
@@ -34,6 +34,8 @@
 
 import java.util.List;
 
+import org.codeaurora.ims.utils.QtiImsExtUtils;
+
 /**
  * View that draws one or more symbols for different types of calls (missed calls, outgoing etc).
  * The symbols are set up horizontally. As this view doesn't create subviews, it is better suited
@@ -47,12 +49,15 @@
 
     private static Resources sResources;
 
+    private static boolean mIsCarrierOneSupported = false;
+
     public CallTypeIconsView(Context context) {
         this(context, null);
     }
 
     public CallTypeIconsView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mIsCarrierOneSupported = QtiImsExtUtils.isCarrierOneSupported();
         if (sResources == null) {
           sResources = new Resources(context);
         }
@@ -74,6 +79,40 @@
         invalidate();
     }
 
+    public void addImsOrVideoIcon(int callType, boolean showVideo) {
+        mShowVideo = showVideo;
+        if (showVideo) {
+            mWidth += sResources.videoCall.getIntrinsicWidth();
+            mHeight = Math.max(mHeight, sResources.videoCall.getIntrinsicHeight());
+            invalidate();
+        } else {
+            final Drawable drawable = getImsOrWifiDrawable(callType);
+            if (drawable != null) {
+                // calculating drawable's width and adding it to total width for correct position
+                // of icon.
+                // calculating height by max of drawable height and other icons' height.
+                mWidth += drawable.getIntrinsicWidth();
+                mHeight = Math.max(mHeight, drawable.getIntrinsicHeight());
+                invalidate();
+            }
+        }
+    }
+
+    private Drawable getImsOrWifiDrawable(int callType) {
+       switch(callType) {
+         case AppCompatConstants.INCOMING_IMS_TYPE:
+         case AppCompatConstants.OUTGOING_IMS_TYPE:
+         case AppCompatConstants.MISSED_IMS_TYPE:
+              return sResources.imsCall;
+         case AppCompatConstants.INCOMING_WIFI_TYPE:
+         case AppCompatConstants.OUTGOING_WIFI_TYPE:
+         case AppCompatConstants.MISSED_WIFI_TYPE:
+              return sResources.wifiCall;
+         default:
+              return null;
+       }
+    }
+
     /**
      * Determines whether the video call icon will be shown.
      *
@@ -81,6 +120,12 @@
      */
     public void setShowVideo(boolean showVideo) {
         mShowVideo = showVideo;
+        if (mIsCarrierOneSupported) {
+            //  Don't show video icon in call log item. For CarrierOne, show more precise icon
+            //  based on call type in call detail history.
+            return;
+        }
+
         if (showVideo) {
             mWidth += sResources.videoCall.getIntrinsicWidth();
             mHeight = Math.max(mHeight, sResources.videoCall.getIntrinsicHeight());
@@ -111,12 +156,15 @@
         switch (callType) {
             case AppCompatConstants.CALLS_INCOMING_TYPE:
             case AppCompatConstants.INCOMING_IMS_TYPE:
+            case AppCompatConstants.INCOMING_WIFI_TYPE:
                 return sResources.incoming;
             case AppCompatConstants.CALLS_OUTGOING_TYPE:
             case AppCompatConstants.OUTGOING_IMS_TYPE:
+            case AppCompatConstants.OUTGOING_WIFI_TYPE:
                 return sResources.outgoing;
             case AppCompatConstants.CALLS_MISSED_TYPE:
             case AppCompatConstants.MISSED_IMS_TYPE:
+            case AppCompatConstants.MISSED_WIFI_TYPE:
                 return sResources.missed;
             case AppCompatConstants.CALLS_VOICEMAIL_TYPE:
                 return sResources.voicemail;
@@ -150,9 +198,19 @@
         // If showing the video call icon, draw it scaled appropriately.
         if (mShowVideo) {
             final Drawable drawable = sResources.videoCall;
-            final int right = left + sResources.videoCall.getIntrinsicWidth();
-            drawable.setBounds(left, 0, right, sResources.videoCall.getIntrinsicHeight());
+            final int right = left + drawable.getIntrinsicWidth();
+            drawable.setBounds(left, 0, right, drawable.getIntrinsicHeight());
             drawable.draw(canvas);
+            left = right + sResources.iconMargin;
+        }
+
+        for (Integer callType : mCallTypes) {
+            final Drawable drawableIms = getImsOrWifiDrawable(callType);
+            if (drawableIms != null) {
+                final int right = left + drawableIms.getIntrinsicWidth();
+                drawableIms.setBounds(left, 0, right, drawableIms.getIntrinsicHeight());
+                drawableIms.draw(canvas);
+            }
         }
     }
 
@@ -182,6 +240,15 @@
         public final int iconMargin;
 
         /**
+         * Drawable repesenting a wifi call.
+         */
+        public final Drawable wifiCall;
+
+        /**
+         * Drawable repesenting a IMS call.
+         */
+        public final Drawable imsCall;
+        /**
          * Configures the call icon drawables.
          * A single white call arrow which points down and left is used as a basis for all of the
          * call arrow icons, applying rotation and colors as needed.
@@ -208,11 +275,26 @@
             blocked = getScaledBitmap(context, R.drawable.ic_block_24dp);
             blocked.setColorFilter(r.getColor(R.color.blocked_call), PorterDuff.Mode.MULTIPLY);
 
-            videoCall = getScaledBitmap(context, R.drawable.ic_videocam_24dp);
+            if (mIsCarrierOneSupported) {
+                videoCall = r.getDrawable(R.drawable.volte_video).mutate();
+            } else {
+            // Get the video call icon, scaled to match the height of the call arrows.
+            // We want the video call icon to be the same height as the call arrows, while keeping
+            // the same width aspect ratio.
+                videoCall = getScaledBitmap(context, R.drawable.ic_videocam_24dp);
+            }
             videoCall.setColorFilter(r.getColor(R.color.dialtacts_secondary_text_color),
                     PorterDuff.Mode.MULTIPLY);
 
             iconMargin = r.getDimensionPixelSize(R.dimen.call_log_icon_margin);
+
+            wifiCall = r.getDrawable(R.drawable.wifi_calling).mutate();
+            wifiCall.setColorFilter(r.getColor(R.color.dialtacts_secondary_text_color),
+                    PorterDuff.Mode.MULTIPLY);
+
+            imsCall = r.getDrawable(R.drawable.volte_voice).mutate();
+            imsCall.setColorFilter(r.getColor(R.color.dialtacts_secondary_text_color),
+                    PorterDuff.Mode.MULTIPLY);
         }
 
         // Gets the icon, scaled to the height of the call type icons. This helps display all the
diff --git a/src/com/android/dialer/calllog/MSimCallLogFragment.java b/src/com/android/dialer/calllog/MSimCallLogFragment.java
index 666368f..8f484d8 100644
--- a/src/com/android/dialer/calllog/MSimCallLogFragment.java
+++ b/src/com/android/dialer/calllog/MSimCallLogFragment.java
@@ -464,7 +464,7 @@
                 messageId = R.string.call_log_voicemail_empty;
                 break;
             case CallLogQueryHandler.CALL_TYPE_ALL:
-                messageId = R.string.call_log_all_empty_action;
+                messageId = R.string.recentCalls_empty;
                 break;
             default:
                 throw new IllegalArgumentException("Unexpected filter type in CallLogFragment: "
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index ea77722..d5f0035 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -29,18 +29,22 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.media.AudioManager;
 import android.media.ToneGenerator;
+import android.Manifest;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Trace;
+import android.os.SystemProperties;
 import android.provider.Contacts.People;
 import android.provider.Contacts.Phones;
 import android.provider.Contacts.PhonesColumns;
 import android.provider.Settings;
+import android.support.v4.app.ActivityCompat;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.PhoneNumberUtils;
@@ -89,6 +93,7 @@
 import com.android.dialer.util.IntentUtil.CallIntentBuilder;
 import com.android.dialer.util.TelecomUtil;
 import com.android.incallui.Call.LogState;
+import com.android.dialer.util.WifiCallUtils;
 import com.android.phone.common.CallLogAsync;
 import com.android.phone.common.animation.AnimUtils;
 import com.android.phone.common.dialpad.DialpadKeyButton;
@@ -108,6 +113,8 @@
         DialpadKeyButton.OnPressedListener {
     private static final String TAG = "DialpadFragment";
 
+    /* define for Activity permission request for Android6.0 */
+    private static final int PERMISSION_REQUEST_CODE_LOCATION = 2;
     /**
      * LinearLayout with getter and setter methods for the translationY property using floats,
      * for animation purposes.
@@ -305,6 +312,15 @@
 
     private static final String PREF_DIGITS_FILLED_BY_INTENT = "pref_digits_filled_by_intent";
 
+    private static final String ACTION_WIFI_CALL_READY_STATUS_CHANGE
+        = "com.android.wificall.READY";
+    private static final String ACTION_WIFI_CALL_READY_EXTRA
+        = "com.android.wificall.ready.extra";
+    private static final String SYSTEM_PROPERTY_WIFI_CALL_READY
+        = "persist.sys.wificall.ready";
+    private BroadcastReceiver mWifiCallReadyReceiver;
+    private boolean isConfigAvailableNetwork = false;
+
     private TelephonyManager getTelephonyManager() {
         return (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
     }
@@ -356,6 +372,20 @@
         updateDeleteButtonEnabledState();
     }
 
+    private void changeDialpadButton(boolean ready) {
+        Log.d(TAG, "changeDialpadButton, ready = " + ready);
+        ImageView floatingActionButton =
+                (ImageButton) getView().findViewById(R.id.dialpad_floating_action_button);
+        if (floatingActionButton == null) {
+            return;
+        }
+        if (ready) {
+            floatingActionButton.setImageResource(R.drawable.fab_ic_wificall);
+        } else {
+            floatingActionButton.setImageResource(R.drawable.fab_ic_call);
+        }
+    }
+
     @Override
     public void onCreate(Bundle state) {
         Trace.beginSection(TAG + " onCreate");
@@ -380,6 +410,8 @@
             mCallStateReceiver = new CallStateReceiver();
             ((Context) getActivity()).registerReceiver(mCallStateReceiver, callStateIntentFilter);
         }
+        isConfigAvailableNetwork = getActivity().getResources().getBoolean(
+                R.bool.config_regional_pup_no_available_network);
         Trace.endSection();
     }
 
@@ -773,6 +805,20 @@
             mOperator.setVisibility(View.GONE);
         }
 
+        if (isConfigAvailableNetwork) {
+            Context context = getActivity();
+            mWifiCallReadyReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    changeDialpadButton(
+                            intent.getBooleanExtra(ACTION_WIFI_CALL_READY_EXTRA, false));
+                }
+            };
+            IntentFilter filter = new IntentFilter(ACTION_WIFI_CALL_READY_STATUS_CHANGE);
+            context.registerReceiver(mWifiCallReadyReceiver, filter);
+            changeDialpadButton(
+                    SystemProperties.getBoolean(SYSTEM_PROPERTY_WIFI_CALL_READY, false));
+         }
         Trace.endSection();
     }
 
@@ -789,6 +835,10 @@
         mLastNumberDialed = EMPTY_NUMBER;  // Since we are going to query again, free stale number.
 
         SpecialCharSequenceMgr.cleanup();
+
+        if (isConfigAvailableNetwork) {
+            (getActivity()).unregisterReceiver(mWifiCallReadyReceiver);
+        }
     }
 
     @Override
@@ -1047,8 +1097,12 @@
     public void onClick(View view) {
         int resId = view.getId();
         if (resId == R.id.dialpad_floating_action_button) {
-            view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-            handleDialButtonPressed();
+            if (isConfigAvailableNetwork) {
+                dialAfterNetworkCheck();
+            } else {
+                view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+                handleDialButtonPressed();
+            }
         } else if (resId == R.id.deleteButton) {
             keyPressed(KeyEvent.KEYCODE_DEL);
         } else if (resId == R.id.digits) {
@@ -1932,4 +1986,42 @@
                 .show();
     }
 
+    private void dialAfterNetworkCheck() {
+        if (ActivityCompat.checkSelfPermission(getContext(),
+                Manifest.permission.ACCESS_COARSE_LOCATION) !=
+            PackageManager.PERMISSION_GRANTED) {
+            requestPermissions(new String[] {Manifest.permission.ACCESS_COARSE_LOCATION},
+                    PERMISSION_REQUEST_CODE_LOCATION);
+        } else {
+            if(WifiCallUtils.shallShowWifiCallDialog(getActivity())) {
+                 WifiCallUtils.showWifiCallDialog(getActivity());
+             } else {
+                 getView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+                 handleDialButtonPressed();
+             }
+        }
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions,
+            int[] grantResults) {
+        switch (requestCode) {
+            case PERMISSION_REQUEST_CODE_LOCATION:
+                if ( grantResults.length > 0 && grantResults[0] ==
+                        PackageManager.PERMISSION_GRANTED) {
+                    if(WifiCallUtils.shallShowWifiCallDialog(getActivity())) {
+                        WifiCallUtils.showWifiCallDialog(getActivity());
+                    } else {
+                        getView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+                        handleDialButtonPressed();
+                    }
+                } else {
+                    getView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+                    handleDialButtonPressed();
+                }
+                break;
+            default:
+                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        }
+    }
 }
diff --git a/src/com/android/dialer/settings/DialerSettingsActivity.java b/src/com/android/dialer/settings/DialerSettingsActivity.java
index 322ecd4..1c81455 100644
--- a/src/com/android/dialer/settings/DialerSettingsActivity.java
+++ b/src/com/android/dialer/settings/DialerSettingsActivity.java
@@ -31,6 +31,7 @@
 import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.compat.TelephonyManagerCompat;
 import com.android.dialer.SpeedDialListActivity;
+import com.android.contacts.common.CallUtil;
 import com.android.dialer.R;
 import com.android.dialer.compat.FilteredNumberCompat;
 import com.android.dialer.compat.SettingsCompat;
@@ -134,6 +135,27 @@
             accessibilitySettingsHeader.intent = accessibilitySettingsIntent;
             target.add(accessibilitySettingsHeader);
         }
+        //video calling
+        boolean enablePresence = this.getResources().getBoolean(
+                R.bool.config_regional_presence_enable);
+        if(enablePresence){
+            Header videocallingHeader = new Header();
+            videocallingHeader.titleRes = R.string.video_call;
+            videocallingHeader.fragment = VideoCallingSettingsFragment.class.getName();
+            target.add(videocallingHeader);
+        }
+
+        boolean usageEnable = getResources().getBoolean(
+                R.bool.config_regional_call_data_usage_enable);
+        if (usageEnable) {
+            final Header historyInfoHeader = new Header();
+            historyInfoHeader.titleRes = R.string.call_data_info_label;
+            historyInfoHeader.summaryRes = R.string.call_data_info_description;
+            historyInfoHeader.intent = new Intent(Intent.ACTION_MAIN);
+            historyInfoHeader.intent
+                    .setAction("android.intent.action.SHOW_TIMERINFO");
+            target.add(historyInfoHeader);
+        }
     }
 
     @Override
diff --git a/src/com/android/dialer/settings/VideoCallingSettingsFragment.java b/src/com/android/dialer/settings/VideoCallingSettingsFragment.java
new file mode 100644
index 0000000..fa73ab7
--- /dev/null
+++ b/src/com/android/dialer/settings/VideoCallingSettingsFragment.java
@@ -0,0 +1,83 @@
+/**
+ * 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.dialer.settings;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.SwitchPreference;
+
+import java.lang.Object;
+import java.lang.Override;
+import java.lang.String;
+
+import com.android.contacts.common.CallUtil;
+import com.android.dialer.R;
+
+public class VideoCallingSettingsFragment extends PreferenceFragment implements
+        Preference.OnPreferenceChangeListener {
+
+    private final static String KEY_VIDEO_CALL = "video_calling_preference";
+    private SwitchPreference mVideoCallingPreference;
+    private Context mContext;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        addPreferencesFromResource(R.xml.video_calling_settings);
+
+        mContext = getActivity();
+        mVideoCallingPreference = (SwitchPreference)findPreference(KEY_VIDEO_CALL);
+        mVideoCallingPreference.setOnPreferenceChangeListener(this);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        int enable = Settings.System.getInt(mContext.getContentResolver(),
+                CallUtil.DIALOG_VIDEO_CALLING,CallUtil.DISABLE_VIDEO_CALLING);
+        if(mVideoCallingPreference != null)
+            mVideoCallingPreference.setChecked(enable == CallUtil.ENABLE_VIDEO_CALLING);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        if (preference == mVideoCallingPreference) {
+            boolean isCheck = mVideoCallingPreference.isChecked();
+            CallUtil.createVideoCallingDialog(isCheck , mContext);
+            Settings.System.putInt(mContext.getContentResolver(), CallUtil.CONFIG_VIDEO_CALLING,
+                    isCheck ? CallUtil.ENABLE_VIDEO_CALLING : CallUtil.DISABLE_VIDEO_CALLING);
+        }
+        return true;
+    }
+
+}
diff --git a/src/com/android/dialer/util/AppCompatConstants.java b/src/com/android/dialer/util/AppCompatConstants.java
index 15c1460..dd6c024 100644
--- a/src/com/android/dialer/util/AppCompatConstants.java
+++ b/src/com/android/dialer/util/AppCompatConstants.java
@@ -30,4 +30,7 @@
     public static final int INCOMING_IMS_TYPE = 8;
     public static final int OUTGOING_IMS_TYPE = 9;
     public static final int MISSED_IMS_TYPE = 10;
+    public static final int INCOMING_WIFI_TYPE = Calls.INCOMING_WIFI_TYPE;
+    public static final int OUTGOING_WIFI_TYPE = Calls.OUTGOING_WIFI_TYPE;
+    public static final int MISSED_WIFI_TYPE = Calls.MISSED_WIFI_TYPE;
 }
diff --git a/src/com/android/dialer/util/IntentUtil.java b/src/com/android/dialer/util/IntentUtil.java
index cff261c..8d47075 100644
--- a/src/com/android/dialer/util/IntentUtil.java
+++ b/src/com/android/dialer/util/IntentUtil.java
@@ -17,6 +17,7 @@
 package com.android.dialer.util;
 
 import android.content.Intent;
+import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract;
@@ -25,9 +26,12 @@
 import android.telecom.VideoProfile;
 import android.content.Context;
 import com.android.dialer.R;
+import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 
 import com.android.contacts.common.CallUtil;
+import java.util.List;
 
 /**
  * Utilities for creation of intents in Dialer, such as {@link Intent#ACTION_CALL}.
@@ -162,12 +166,26 @@
      * if true, conference dialer  is enabled.
      */
     public static boolean isConferDialerEnabled(Context context) {
-        if (context.getResources().getBoolean(R.bool.config_enable_conference_dialer)) {
-            TelephonyManager telephonyMgr = (TelephonyManager)
-                    context.getSystemService(Context.TELEPHONY_SERVICE);
-            return telephonyMgr.isImsRegistered();
+        boolean isEnabled = false;
+        List<SubscriptionInfo> subInfos = SubscriptionManager.from(context)
+                .getActiveSubscriptionInfoList();
+        if (subInfos != null) {
+            for (SubscriptionInfo subInfo : subInfos ) {
+                if (SubscriptionManager.isValidSubscriptionId(subInfo.getSubscriptionId())) {
+                    Resources subRes = SubscriptionManager.getResourcesForSubId(context,
+                            subInfo.getSubscriptionId());
+                    if (subRes.getBoolean(R.bool.config_enable_conference_dialer)) {
+                        TelephonyManager telephonyMgr = (TelephonyManager) context.
+                                getSystemService(Context.TELEPHONY_SERVICE);
+                        isEnabled = telephonyMgr.isImsRegistered();
+                        if (isEnabled) {
+                            break;
+                        }
+                    }
+                }
+            }
         }
-        return false;
+        return isEnabled;
     }
 
     /**
diff --git a/src/com/android/dialer/util/PresenceHelper.java b/src/com/android/dialer/util/PresenceHelper.java
new file mode 100644
index 0000000..cf94df0
--- /dev/null
+++ b/src/com/android/dialer/util/PresenceHelper.java
@@ -0,0 +1,134 @@
+/**
+ * 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.dialer.util;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.android.incallui.Log;
+
+import org.codeaurora.presenceserv.IPresenceService;
+import org.codeaurora.presenceserv.IPresenceServiceCB;
+
+/**
+ * General presnece service utility methods for the Dialer.
+ */
+public class PresenceHelper {
+
+    private static final String TAG = "PresenceHelper";
+    private static volatile IPresenceService mService;
+    private static boolean mIsBound;
+
+    private static ServiceConnection mConnection = new ServiceConnection() {
+
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            Log.d(TAG, "PresenceService connected");
+            mService = IPresenceService.Stub.asInterface(service);
+            try {
+                mService.registerCallback(mCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG, "PresenceService registerCallback error " + e);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            Log.d(TAG, "PresenceService disconnected");
+            mService = null;
+        }
+    };
+
+    private static IPresenceServiceCB mCallback = new IPresenceServiceCB.Stub() {
+
+        public void setIMSEnabledCB() {
+            Log.d(TAG, "PresenceService setIMSEnabled callback");
+        }
+
+    };
+
+    public static void bindService(Context context) {
+        Log.d(TAG, "PresenceService BindService ");
+        Intent intent = new Intent(IPresenceService.class.getName());
+        intent.setClassName("com.qualcomm.qti.presenceserv",
+                "com.qualcomm.qti.presenceserv.PresenceService");
+        mIsBound = context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+    }
+
+    public static void unbindService(Context context) {
+        Log.d(TAG, "PresenceService unbindService");
+        if (mService == null) {
+            Log.d(TAG, "PresenceService unbindService: mService is null");
+            return;
+        }
+        try {
+            mService.unregisterCallback(mCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "PresenceService unregister error " + e);
+        }
+        if (mIsBound) {
+            Log.d(TAG, "PresenceService unbind");
+            context.unbindService(mConnection);
+            mIsBound = false;
+        }
+    }
+
+    public static boolean isBound() {
+        return mIsBound;
+    }
+
+    public static boolean startAvailabilityFetch(String number){
+        Log.d(TAG, "startAvailabilityFetch   number " + number);
+        if (mService == null) {
+             Log.d(TAG, "startAvailabilityFetch mService is null");
+             return false;
+        }
+        try {
+            return mService.invokeAvailabilityFetch(number);
+        } catch (Exception e) {
+            Log.d(TAG, "getVTCapOfContact ERROR " + e);
+        }
+        return false;
+    }
+
+    public static boolean getVTCapability(String number) {
+        Log.d(TAG, "getVTCapability   number " + number);
+        if (null == mService) {
+            Log.d(TAG, "getVTCapability mService is null");
+            return false;
+        }
+        try {
+            return mService.hasVTCapability(number);
+        } catch (Exception e) {
+            Log.d(TAG, "getVTCapability ERROR " + e);
+        }
+        return false;
+    }
+}
diff --git a/src/com/android/dialer/util/WifiCallUtils.java b/src/com/android/dialer/util/WifiCallUtils.java
new file mode 100644
index 0000000..fb143c8
--- /dev/null
+++ b/src/com/android/dialer/util/WifiCallUtils.java
@@ -0,0 +1,215 @@
+/*
+* Copyright (c) 2015, 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.dialer.util;
+
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Handler;
+import android.os.SystemProperties;
+import android.telephony.CellInfo;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import com.android.dialer.R;
+
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class WifiCallUtils {
+
+    private static final String TAG = WifiCallUtils.class.getSimpleName();
+    private static final int DELAYED_TIME = 5 * 1000;
+    private static final int NOTIFICATION_WIFI_CALL_ID = 1;
+    private WindowManager mWindowManager;
+    private TextView mTextView;
+    private boolean mViewRemoved = true;
+
+    private static final String SYSTEM_PROPERTY_WIFI_CALL_READY = "persist.sys.wificall.ready";
+    private static final String SYSTEM_PROPERTY_WIFI_CALL_TURNON = "persist.sys.wificall.turnon";
+
+    public void addWifiCallReadyMarqueeMessage(Context context) {
+        if (mViewRemoved && SystemProperties.getBoolean(SYSTEM_PROPERTY_WIFI_CALL_READY, false)) {
+            if (mWindowManager == null) mWindowManager =
+                (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+            if(mTextView == null){
+                mTextView = new TextView(context);
+                Log.d(TAG, "mTextView is null, new mTextView = " + mTextView);
+                mTextView.setText(
+                        com.android.dialer.R.string.alert_call_over_wifi);
+                mTextView.setSingleLine(true);
+                mTextView.setEllipsize(android.text.TextUtils.TruncateAt.MARQUEE);
+                mTextView.setMarqueeRepeatLimit(-1);
+                mTextView.setFocusableInTouchMode(true);
+            } else {
+                Log.d(TAG, "mTextView is not null, mTextView = " + mTextView);
+            }
+
+            WindowManager.LayoutParams windowParam = new WindowManager.LayoutParams();
+            windowParam.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+            windowParam.format= 1;
+            windowParam.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+            windowParam.alpha = 1.0f;
+            windowParam.x = 0;
+            windowParam.y = -500;
+            windowParam.height = WindowManager.LayoutParams.WRAP_CONTENT;
+            windowParam.width = (mWindowManager.getDefaultDisplay().getWidth()
+                    < mWindowManager.getDefaultDisplay().getHeight()
+                    ? mWindowManager.getDefaultDisplay().getWidth()
+                    : mWindowManager.getDefaultDisplay().getHeight()) - 64;
+            mWindowManager.addView(mTextView, windowParam);
+            mViewRemoved = false;
+            Log.d(TAG, "addWifiCallReadyMarqueeMessage, mWindowManager:" + mWindowManager
+                    + " addView, mTextView:" + mTextView
+                    + " addWifiCallReadyMarqueeMessage, mViewRemoved = " + mViewRemoved);
+
+            scheduleRemoveWifiCallReadyMarqueeMessageTimer();
+        }
+    }
+
+    public void removeWifiCallReadyMarqueeMessage() {
+        if (!mViewRemoved) {
+            mWindowManager.removeView(mTextView);
+            mViewRemoved = true;
+            Log.d(TAG, "removeWifiCallReadyMarqueeMessage, mWindowManager:" + mWindowManager
+                    + " removeView, mTextView:" + mTextView
+                    + " removeWifiCallReadyMarqueeMessage, mViewRemoved = " + mViewRemoved);
+        }
+    }
+
+    private void scheduleRemoveWifiCallReadyMarqueeMessageTimer() {
+        // Schedule a timer, 5s later, remove the message
+        new Handler().postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    Log.d(TAG, "Handler is running");
+                    removeWifiCallReadyMarqueeMessage();
+                }
+        }, DELAYED_TIME);
+        Log.d(TAG, "schedule timerTask");
+    }
+
+    private static boolean isCellularNetworkAvailable(Context context) {
+        boolean available = false;
+
+        TelephonyManager tm = (TelephonyManager) context.
+                getSystemService(Context.TELEPHONY_SERVICE);
+        List<CellInfo> cellInfoList = tm.getAllCellInfo();
+
+        if (cellInfoList != null) {
+            for (CellInfo cellinfo : cellInfoList) {
+                if (cellinfo.isRegistered()) {
+                    available = true;
+                }
+            }
+        }
+
+        return available;
+    }
+
+    public static void showWifiCallDialog(final Context context) {
+        String promptMessage = context.getString(com.android.dialer.R.string
+                .alert_call_no_cellular_coverage) +"\n"+ context.getString(com.android.dialer.R
+                        .string.alert_user_connect_to_wifi_for_call);
+        AlertDialog.Builder diaBuilder = new AlertDialog.Builder(context);
+        diaBuilder.setMessage(promptMessage);
+        diaBuilder.setPositiveButton(com.android.internal.R.string.ok, new OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                Intent intent = new Intent(Intent.ACTION_MAIN);
+                intent.setClassName("com.qualcomm.qti.extsettings",
+                        "com.qualcomm.qti.extsettings.wificall.WifiCallingEnhancedSettings");
+                context.startActivity(intent);
+            }
+        });
+        diaBuilder.setOnCancelListener(new OnCancelListener() {
+            @Override
+            public void onCancel(DialogInterface dialog) {
+            }
+        });
+        diaBuilder.create().show();
+    }
+
+    public static boolean shallShowWifiCallDialog(final Context context) {
+        boolean wifiCallTurnOn = SystemProperties.getBoolean(
+                SYSTEM_PROPERTY_WIFI_CALL_TURNON, false);
+
+        ConnectivityManager conManager = (ConnectivityManager) context
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo wifiNetworkInfo = conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        boolean wifiAvailableNotConnected =
+                wifiNetworkInfo.isAvailable() && !wifiNetworkInfo.isConnected();
+
+        return wifiCallTurnOn && wifiAvailableNotConnected && !isCellularNetworkAvailable(context);
+    }
+
+    public static void showWifiCallNotification(final Context context) {
+        if (shallShowWifiCallDialog(context)) {
+            final NotificationManager notiManager =
+                    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+            Intent intent = new Intent();
+            intent.setAction(android.provider.Settings.ACTION_WIFI_SETTINGS);
+            PendingIntent pendingIntent =
+                    PendingIntent.getActivity(
+                            context, NOTIFICATION_WIFI_CALL_ID,
+                            intent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+            Notification.Builder builder = new Notification.Builder(context);
+            builder.setOngoing(false);
+            builder.setWhen(0);
+            builder.setContentIntent(pendingIntent);
+            builder.setAutoCancel(true);
+            builder.setSmallIcon(R.drawable.wifi_calling_on_notification);
+            builder.setContentTitle(
+                    context.getResources().getString(R.string.alert_user_connect_to_wifi_for_call));
+            builder.setContentText(
+                    context.getResources().getString(R.string.alert_user_connect_to_wifi_for_call));
+            notiManager.notify(NOTIFICATION_WIFI_CALL_ID, builder.build());
+            new Handler().postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        notiManager.cancel(NOTIFICATION_WIFI_CALL_ID);
+                    }
+           }, 2000);
+        }
+    }
+}
diff --git a/src/org/codeaurora/presenceserv/IPresenceService.aidl b/src/org/codeaurora/presenceserv/IPresenceService.aidl
new file mode 100644
index 0000000..edd0ac1
--- /dev/null
+++ b/src/org/codeaurora/presenceserv/IPresenceService.aidl
@@ -0,0 +1,50 @@
+/**
+ * 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 org.codeaurora.presenceserv;
+
+import org.codeaurora.presenceserv.IPresenceServiceCB;
+
+/**
+ * Presence service interface.
+ */
+interface IPresenceService {
+
+    String getImsEnablerState();
+    boolean hasVTCapability(String number);
+    void invokPublish();
+    boolean invokeAvailabilityFetch(String number);
+    void invokeCapabilityPolling(String number);
+    void invokeListAvailabilityFetch();
+    void invokeListCapabilityPolling();
+    void registerCallback(IPresenceServiceCB cb);
+    void unregisterCallback(IPresenceServiceCB cb);
+
+}
+
diff --git a/src/org/codeaurora/presenceserv/IPresenceServiceCB.aidl b/src/org/codeaurora/presenceserv/IPresenceServiceCB.aidl
new file mode 100644
index 0000000..05ad7d7
--- /dev/null
+++ b/src/org/codeaurora/presenceserv/IPresenceServiceCB.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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 org.codeaurora.presenceserv;
+
+/**
+ * Presence service callback interface.
+ */
+interface IPresenceServiceCB {
+
+    void setIMSEnabledCB();
+}
+