Merge 68a594cb4507e341e5ba526929c64f22e3a67f71 on remote branch

Change-Id: I611b6bc5eab4d3b8193119b0468cc2d6fd603a95
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4930315..715722b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -169,6 +169,7 @@
         </activity>
 
         <activity android:name="com.android.dialer.calllog.CallLogActivity"
+            android:configChanges="orientation|screenSize|keyboardHidden"
             android:label="@string/call_log_activity_title"
             android:theme="@style/DialtactsThemeWithoutActionBarOverlay"
             android:icon="@mipmap/ic_launcher_phone">
diff --git a/InCallUI/res/drawable-hdpi/ic_hd2_24dp.png b/InCallUI/res/drawable-hdpi/ic_hd2_24dp.png
new file mode 100644
index 0000000..b4cbe6d
--- /dev/null
+++ b/InCallUI/res/drawable-hdpi/ic_hd2_24dp.png
Binary files differ
diff --git a/InCallUI/res/drawable-mdpi/ic_hd2_24dp.png b/InCallUI/res/drawable-mdpi/ic_hd2_24dp.png
new file mode 100644
index 0000000..f4bc997
--- /dev/null
+++ b/InCallUI/res/drawable-mdpi/ic_hd2_24dp.png
Binary files differ
diff --git a/InCallUI/res/drawable-xhdpi/ic_hd2_24dp.png b/InCallUI/res/drawable-xhdpi/ic_hd2_24dp.png
new file mode 100644
index 0000000..4ac0961
--- /dev/null
+++ b/InCallUI/res/drawable-xhdpi/ic_hd2_24dp.png
Binary files differ
diff --git a/InCallUI/res/drawable-xxhdpi/ic_hd2_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_hd2_24dp.png
new file mode 100644
index 0000000..f1e6f1f
--- /dev/null
+++ b/InCallUI/res/drawable-xxhdpi/ic_hd2_24dp.png
Binary files differ
diff --git a/InCallUI/res/layout-h400dp/call_card_fragment.xml b/InCallUI/res/layout-h400dp/call_card_fragment.xml
index 54b9e36..ccff385 100644
--- a/InCallUI/res/layout-h400dp/call_card_fragment.xml
+++ b/InCallUI/res/layout-h400dp/call_card_fragment.xml
@@ -116,7 +116,7 @@
                 <ProgressBar
                     android:id="@+id/progress_bar"
                     style="@android:style/Widget.Material.ProgressBar"
-                    android:layout_gravity="center"
+                    android:layout_gravity="left|center_vertical"
                     android:layout_width="48dp"
                     android:layout_height="48dp"
                     android:indeterminate="true" />
diff --git a/InCallUI/res/layout-w500dp-land/call_card_fragment.xml b/InCallUI/res/layout-w500dp-land/call_card_fragment.xml
index bdd1e27..1efe527 100644
--- a/InCallUI/res/layout-w500dp-land/call_card_fragment.xml
+++ b/InCallUI/res/layout-w500dp-land/call_card_fragment.xml
@@ -109,7 +109,7 @@
             <ProgressBar
                 android:id="@+id/progress_bar"
                 style="@android:style/Widget.Material.ProgressBar"
-                android:layout_gravity="center"
+                android:layout_gravity="left|center_vertical"
                 android:layout_width="48dp"
                 android:layout_height="48dp"
                 android:indeterminate="true" />
diff --git a/InCallUI/res/layout/call_card_fragment.xml b/InCallUI/res/layout/call_card_fragment.xml
index f865944..2a4c3e2 100644
--- a/InCallUI/res/layout/call_card_fragment.xml
+++ b/InCallUI/res/layout/call_card_fragment.xml
@@ -91,7 +91,7 @@
         <ProgressBar
             android:id="@+id/progress_bar"
             style="@android:style/Widget.Material.ProgressBar"
-            android:layout_gravity="center"
+            android:layout_gravity="left|center_vertical"
             android:layout_width="48dp"
             android:layout_height="48dp"
             android:indeterminate="true" />
diff --git a/InCallUI/res/values-mcc460-mnc01/qticonfig.xml b/InCallUI/res/values-mcc460-mnc01/qticonfig.xml
new file mode 100644
index 0000000..5f789c5
--- /dev/null
+++ b/InCallUI/res/values-mcc460-mnc01/qticonfig.xml
@@ -0,0 +1,32 @@
+<!--
+  ~ 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.
+  -->
+<resources>
+    <!-- Config to show/hide HD Icon2 -->
+    <bool name="config_show_hd2">true</bool>
+</resources>
diff --git a/InCallUI/res/values-mcc460-mnc06/qticonfig.xml b/InCallUI/res/values-mcc460-mnc06/qticonfig.xml
new file mode 100644
index 0000000..5f789c5
--- /dev/null
+++ b/InCallUI/res/values-mcc460-mnc06/qticonfig.xml
@@ -0,0 +1,32 @@
+<!--
+  ~ 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.
+  -->
+<resources>
+    <!-- Config to show/hide HD Icon2 -->
+    <bool name="config_show_hd2">true</bool>
+</resources>
diff --git a/InCallUI/res/values-mcc460-mnc09/qticonfig.xml b/InCallUI/res/values-mcc460-mnc09/qticonfig.xml
new file mode 100644
index 0000000..5f789c5
--- /dev/null
+++ b/InCallUI/res/values-mcc460-mnc09/qticonfig.xml
@@ -0,0 +1,32 @@
+<!--
+  ~ 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.
+  -->
+<resources>
+    <!-- Config to show/hide HD Icon2 -->
+    <bool name="config_show_hd2">true</bool>
+</resources>
diff --git a/InCallUI/res/values/qticonfig.xml b/InCallUI/res/values/qticonfig.xml
index 8483d84..0e65f94 100644
--- a/InCallUI/res/values/qticonfig.xml
+++ b/InCallUI/res/values/qticonfig.xml
@@ -27,8 +27,6 @@
   ~ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   -->
 <resources>
-    <!-- Determines UI extensions for video calls should be used. -->
-    <bool name="video_call_use_ext">true</bool>
     <!-- Config to show/hide Video quality toast -->
     <bool name="config_display_video_quality_toast">true</bool>
     <!-- Config to show/hide call session event toast like player start/stop -->
@@ -54,4 +52,8 @@
     <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>
+    <!-- Config to show/hide HD Icon2 -->
+    <bool name="config_show_hd2">false</bool>
+    <!-- Config to enalbe call record -->
+    <bool name="enable_call_record">false</bool>
 </resources>
diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java
index db597b2..5c1319f 100644
--- a/InCallUI/src/com/android/incallui/CallButtonFragment.java
+++ b/InCallUI/src/com/android/incallui/CallButtonFragment.java
@@ -36,6 +36,7 @@
 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 static com.android.incallui.CallButtonFragment.Buttons.BUTTON_ADD_PARTICIPANT;
 
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -95,8 +96,8 @@
         public static final int BUTTON_HOLD = 3;
         public static final int BUTTON_SWAP = 4;
         public static final int BUTTON_UPGRADE_TO_VIDEO = 5;
-        public static final int BUTTON_SWITCH_CAMERA = 6;
-        public static final int BUTTON_DOWNGRADE_TO_AUDIO = 7;
+        public static final int BUTTON_DOWNGRADE_TO_AUDIO = 6;
+        public static final int BUTTON_SWITCH_CAMERA = 7;
         public static final int BUTTON_ADD_CALL = 8;
         public static final int BUTTON_MERGE = 9;
         public static final int BUTTON_PAUSE_VIDEO = 10;
@@ -108,7 +109,8 @@
         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;
+        public static final int BUTTON_ADD_PARTICIPANT = 19;
+        public static final int BUTTON_COUNT = 20;
     }
 
     private SparseIntArray mButtonVisibilityMap = new SparseIntArray(BUTTON_COUNT);
@@ -492,6 +494,8 @@
             return mSwitchCameraButton;
         } else if (id == BUTTON_ADD_CALL) {
             return mAddCallButton;
+        } else if (id == BUTTON_ADD_PARTICIPANT) {
+            return mAddParticipantButton;
         } else if (id == BUTTON_MERGE) {
             return mMergeButton;
         } else if (id == BUTTON_PAUSE_VIDEO) {
@@ -538,10 +542,6 @@
         mPauseVideoButton.setSelected(isPaused);
     }
 
-    public void enableAddParticipant(boolean show) {
-        mAddParticipantButton.setVisibility(show ? View.VISIBLE : View.GONE);
-    }
-
     @Override
     public void setMute(boolean value) {
         if (mMuteButton.isSelected() != value) {
diff --git a/InCallUI/src/com/android/incallui/CallButtonPresenter.java b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
index 7ea2f7f..ceae8c0 100644
--- a/InCallUI/src/com/android/incallui/CallButtonPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
@@ -34,6 +34,7 @@
 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 static com.android.incallui.CallButtonFragment.Buttons.BUTTON_ADD_PARTICIPANT;
 
 import android.content.Context;
 import android.os.Build;
@@ -315,6 +316,11 @@
 
         VideoProfile videoProfile = new VideoProfile(VideoProfile.STATE_AUDIO_ONLY);
         videoCall.sendSessionModifyRequest(videoProfile);
+
+        if (QtiCallUtils.useCustomVideoUi(getUi().getContext())) {
+            InCallAudioManager.getInstance().onModifyCallClicked(mCall,
+                    VideoProfile.STATE_AUDIO_ONLY);
+        }
     }
 
     public void showDialpadClicked(boolean checked) {
@@ -340,6 +346,11 @@
         VideoProfile videoProfile = new VideoProfile(currUnpausedVideoState);
         videoCall.sendSessionModifyRequest(videoProfile);
         mCall.setSessionModificationState(Call.SessionModificationState.WAITING_FOR_RESPONSE);
+
+        if (QtiCallUtils.useCustomVideoUi(context)) {
+            InCallAudioManager.getInstance().onModifyCallClicked(mCall,
+                    currUnpausedVideoState);
+        }
     }
 
     public void changeToVideo(int videoState) {
@@ -480,17 +491,27 @@
         final boolean showMerge = call.can(
                 android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE);
         final boolean useExt = QtiCallUtils.useExt(ui.getContext());
-
+        final boolean useCustomVideoUi =
+                QtiCallUtils.useCustomVideoUi(ui.getContext());
         final boolean isCallActive = call.getState() == Call.State.ACTIVE;
-        final boolean showUpgradeToVideo = (!isVideo  && !useExt && hasVideoCallCapabilities(call))
-                || (useExt && QtiCallUtils.hasVoiceOrVideoCapabilities(call)
-                && (isCallActive || isCallOnHold));
+
+        final boolean showUpgradeToVideo =
+                /* When useExt is true, show upgrade button for an active/held
+                   call if the call has either voice or video capabilities */
+                ((useExt && QtiCallUtils.hasVoiceOrVideoCapabilities(call)) ||
+                /* When useCustomVideoUi is true, show upgrade button for an active/held
+                   voice call only if the current call has video capabilities */
+                (useCustomVideoUi && !isVideo && hasVideoCallCapabilities(call))
+                && (isCallActive || isCallOnHold)) ||
+                /* When useExt and custom UI are false, default to Google behaviour */
+                (!isVideo && !useExt && !useCustomVideoUi && hasVideoCallCapabilities(call));
 
         final boolean showDowngradeToAudio = isVideo && isDowngradeToAudioSupported(call);
         final int callState = call.getState();
 
-        final boolean showRecord = (callState == Call.State.ACTIVE
-                || callState == Call.State.ONHOLD);
+        final boolean showRecord = ((callState == Call.State.ACTIVE
+                || callState == Call.State.ONHOLD)
+                && (ui.getContext().getResources().getBoolean(R.bool.enable_call_record)));
 
         final boolean showMute = call.can(android.telecom.Call.Details.CAPABILITY_MUTE);
         int callTransferCapabilities = call.isEmergencyCall()? 0 : call.getTransferCapabilities();
@@ -523,12 +544,12 @@
         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_PAUSE_VIDEO, isVideo && !useExt && !useCustomVideoUi);
         ui.showButton(BUTTON_DIALPAD, true);
         ui.showButton(BUTTON_MERGE, showMerge);
-        ui.enableAddParticipant(showAddParticipant && !mEnhanceEnable);
-
+        ui.showButton(BUTTON_ADD_PARTICIPANT, showAddParticipant && !mEnhanceEnable);
         ui.showButton(BUTTON_RECORD, showRecord);
+
         /* Depending on the transfer capabilities, display the corresponding buttons */
         if ((callTransferCapabilities & QtiImsExtUtils.QTI_IMS_CONSULTATIVE_TRANSFER) != 0) {
             ui.showButton(BUTTON_TRANSFER_BLIND, true);
@@ -551,6 +572,7 @@
         }
 
         ui.updateButtonStates();
+        ui.updateColors();
     }
 
     private boolean hasVideoCallCapabilities(Call call) {
@@ -609,7 +631,6 @@
         void setHold(boolean on);
         void setCameraSwitched(boolean isBackFacingCamera);
         void setVideoPaused(boolean isPaused);
-        void enableAddParticipant(boolean show);
         void setAudio(int mode);
         void setSupportedAudio(int mask);
         void displayDialpad(boolean on, boolean animate);
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index c64f8c6..69446a9 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -45,6 +45,7 @@
 import android.provider.Settings;
 import android.telecom.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
+import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.view.Gravity;
@@ -930,6 +931,7 @@
             mCallStateIcon.setAlpha(0.0f);
             mCallStateIcon.setVisibility(View.GONE);
         }
+        mCallStateIcon.requestLayout();
 
         if (VideoUtils.isVideoCall(videoState)
                 || (state == Call.State.ACTIVE && sessionModificationState
@@ -1357,6 +1359,11 @@
      */
     @Override
     public void showHdAudioIndicator(boolean visible) {
+        int subId = CallList.getInstance().getActiveSubId();
+        if (SubscriptionManager.getResourcesForSubId(getContext(), subId)
+                .getBoolean(R.bool.config_show_hd2)) {
+            mHdAudioIcon.setImageResource(R.drawable.ic_hd2_24dp);
+        }
         mHdAudioIcon.setVisibility(visible ? View.VISIBLE : View.GONE);
     }
 
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 259de79..af5a7d9 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -445,7 +445,7 @@
         return null;
     }
 
-    private void updatePrimaryCallState() {
+    public void updatePrimaryCallState() {
         if (getUi() != null && mPrimary != null) {
             boolean isWorkCall = mPrimary.hasProperty(PROPERTY_ENTERPRISE_CALL)
                     || (mPrimaryContactInfo == null ? false
diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java
index 5db5eeb..56817d1 100644
--- a/InCallUI/src/com/android/incallui/InCallActivity.java
+++ b/InCallUI/src/com/android/incallui/InCallActivity.java
@@ -335,6 +335,7 @@
         if (mShowPostCharWaitDialogOnResume) {
             showPostCharWaitDialog(mShowPostCharWaitDialogCallId, mShowPostCharWaitDialogChars);
         }
+        InCallPresenter.getInstance().updatePrimaryCallState();
     }
 
     // onPause is guaranteed to be called when the InCallActivity goes
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index 68a03b9..729bd33 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -1348,6 +1348,18 @@
     }
 
     /**
+     * Update  color of sim card icon
+     */
+    public void updatePrimaryCallState() {
+        for (InCallEventListener listener : mInCallEventListeners) {
+            if (listener instanceof CallCardPresenter) {
+                listener.updatePrimaryCallState();
+                break;
+            }
+        }
+    }
+
+    /**
      * Called by the {@link CallCardPresenter} to inform of a change in visibility of the secondary
      * caller info bar.
      *
@@ -1811,16 +1823,18 @@
      * orientation event listener if allowOrientationChange is true, disables it if false.
      *
      * @param orientation {@link ActivityInfo#screenOrientation} Actual orientation value to set
+     * @return returns whether the new orientation mode was set successfully or not.
      */
-    public void setInCallAllowsOrientationChange(int orientation) {
+    public boolean setInCallAllowsOrientationChange(int orientation) {
         if (mInCallActivity == null) {
             Log.e(this, "InCallActivity is null. Can't set requested orientation.");
-            return;
+            return false;
         }
 
         mInCallActivity.setRequestedOrientation(orientation);
         mInCallActivity.enableInCallOrientationEventListener(
                 orientation == InCallOrientationEventListener.FULL_SENSOR_SCREEN_ORIENTATION);
+        return true;
     }
 
     /* returns TRUE if screen is turned ON else false */
@@ -2083,6 +2097,7 @@
     public interface InCallEventListener {
         public void onFullscreenModeChanged(boolean isFullscreenMode);
         public void onSecondaryCallerInfoVisibilityChanged(boolean isVisible, int height);
+        public void updatePrimaryCallState();
     }
 
     public interface InCallUiListener {
diff --git a/InCallUI/src/com/android/incallui/QtiCallUtils.java b/InCallUI/src/com/android/incallui/QtiCallUtils.java
index 234fa4d..6a4383a 100644
--- a/InCallUI/src/com/android/incallui/QtiCallUtils.java
+++ b/InCallUI/src/com/android/incallui/QtiCallUtils.java
@@ -51,6 +51,7 @@
 
 import org.codeaurora.internal.IExtTelephony;
 import org.codeaurora.ims.QtiCallConstants;
+import org.codeaurora.ims.utils.QtiImsExtUtils;
 
 /**
  * This class contains Qti specific utiltity functions.
@@ -239,7 +240,18 @@
         if (context == null) {
             Log.w(context, "Context is null...");
         }
-        return context != null && context.getResources().getBoolean(R.bool.video_call_use_ext);
+        return context != null && QtiImsExtUtils.useExt(context);
+    }
+
+    /**
+     * Checks the boolean flag in config file to figure out if custom video ui is required or
+     * not
+     */
+    public static boolean useCustomVideoUi(Context context) {
+        if (context == null) {
+            Log.w(context, "Context is null...");
+        }
+        return context != null && QtiImsExtUtils.useCustomVideoUi(context);
     }
 
     /**
@@ -515,7 +527,7 @@
 
     /**
      * Returns true if local has the VT Receive and if remote capability has VT Transmit set i.e.
-     * Local can transmit and remote can receive
+     * Remote can transmit and local can receive
      */
     public static boolean hasReceiveVideoCapabilities(Call call) {
         return call != null &&
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index 8c09ff3..d088594 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -339,9 +339,12 @@
 
         final boolean isVideoUpgradeRequest = call.getSessionModificationState()
                 == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST;
+        final Call pendingAccountSelectionCall = CallList.getInstance()
+                .getWaitingForAccountCall();
         final int notificationType;
-        if (callState == Call.State.INCOMING || callState == Call.State.CALL_WAITING
-                || isVideoUpgradeRequest) {
+        if ((callState == Call.State.INCOMING || callState == Call.State.CALL_WAITING
+                || isVideoUpgradeRequest) && (!InCallPresenter.getInstance().isShowingInCallUi()
+                || pendingAccountSelectionCall != null)) {
             notificationType = NOTIFICATION_INCOMING_CALL;
         } else {
             notificationType = NOTIFICATION_IN_CALL;
@@ -388,8 +391,6 @@
         // Set up the main intent to send the user to the in-call screen
         final PendingIntent inCallPendingIntent = createLaunchPendingIntent();
         builder.setContentIntent(inCallPendingIntent);
-        final Call pendingAccountSelectionCall = CallList.getInstance()
-                .getWaitingForAccountCall();
 
         // Set the intent as a full screen intent as well if a call is incoming
         if (notificationType == NOTIFICATION_INCOMING_CALL
diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
index eab6ca2..5b7adcd 100644
--- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/VideoCallPresenter.java
@@ -514,6 +514,10 @@
         cancelAutoFullScreen();
     }
 
+    @Override
+    public void updatePrimaryCallState() {
+    }
+
     /**
      * Handles changes to the visibility of the secondary caller info bar.
      *
@@ -670,11 +674,11 @@
 
     private void checkForOrientationAllowedChange(Call call) {
         final int newMode = OrientationModeHandler.getInstance().getOrientation(call);
-        if (newMode != mActivityOrientationMode) {
+        if (newMode != mActivityOrientationMode && InCallPresenter.
+                getInstance().setInCallAllowsOrientationChange(newMode)) {
             Log.d(this, "checkForOrientationAllowedChange: currMode = " +
                     mActivityOrientationMode + " newMode = " + newMode);
             mActivityOrientationMode = newMode;
-            InCallPresenter.getInstance().setInCallAllowsOrientationChange(newMode);
         }
     }
 
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 382f20b..ca28569 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -300,4 +300,63 @@
     <string name="no_call_log">没有通话记录</string>
     <string name="clear">清除</string>
     <string name="description_clear_search">清除搜索记录</string>
+    <string name="recentCalls_empty">"您没有任何通话记录"</string>
+    <!-- The description text for the call log tab.
+    Note: AccessibilityServices use this attribute to announce what the view represents.
+    This is especially valuable for views without textual representation like ImageView.
+    [CHAR LIMIT=NONE] -->
+    <string name="recentCallsIconLabel">"通话记录"</string>
+    <!-- Menu item used to call a contact from the call log -->
+    <string name="recentCalls_callNumber">"呼叫<xliff:g id="NAME">%s</xliff:g>"</string>
+    <!-- Text for a menu item to report a call as having been incorrectly identified.
+         [CHAR LIMIT=30] -->
+    <string name="call_detail_menu_report">"报告错误的号码"</string>
+    <!-- Menu item used to copy a number from the call log to the dialer so it can be edited before calling it -->
+    <string name="recentCalls_editNumberBeforeCall">"呼叫之前编辑号码"</string>
+    <!-- Menu item used to add a number from the call log to contacts -->
+    <string name="recentCalls_addToContact">"添加到联系人"</string>
+    <!-- Menu item used to remove a single call from the call log -->
+    <string name="recentCalls_removeFromRecentList">"从通话记录中删除"</string>
+    <!-- Menu item used to remove all calls from the call log -->
+    <string name="recentCalls_deleteAll">"清除通话记录"</string>
+    <!-- Menu item used to delete a voicemail. [CHAR LIMIT=30] -->
+    <string name="recentCalls_trashVoicemail">"删除语音邮件"</string>
+    <!-- Menu item used to share a voicemail. [CHAR LIMIT=30] -->
+    <string name="recentCalls_shareVoicemail">"分享语音邮件"</string>
+    <!-- Label of the button displayed when the call log is empty. Allows the user to make a call. -->
+    <string name="recentCalls_empty_action">"拨打电话"</string>
+    <!-- String resource for the font-family to use for the call log activity's title
+         Do not translate. -->
+    <string name="call_log_activity_title_font_family">sans-serif-light</string>
+    <!-- String resource for the font-family to use for the full call history footer
+         Do not translate. -->
+    <string name="view_full_call_history_font_family">sans-serif</string>
+    <!-- Text displayed when the list of incoming calls is empty -->
+    <string name="recentIncoming_empty">"您没有任何来电。"</string>
+    <!-- Text displayed when the list of outgoing calls is empty -->
+    <string name="recentOutgoing_empty">"您没有任何外拨电话。"</string>
+    <!-- Text displayed when the list of missed calls is empty -->
+    <string name="recentMissed_empty">"您没有任何未接电话。"</string>
+    <!-- Text displayed when the list of voicemails is empty -->
+    <string name="recentVoicemails_empty">"您未收到任何语音邮件。"</string>
+
+    <string name="add_to_white_list">"加入白名单"</string>
+    <string name="add_to_black_list">"加入黑名单"</string>
+    <string name="remove_from_black_list">"从黑名单中移除"</string>
+    <string name="remove_from_white_list">"从白名单中移除"</string>
+    <string name="firewall_remove_success">"已成功移除"</string>
+    <string name="yes">"是"</string>
+    <string name="no">"否"</string>
+    <string name="input_number">"输入号码"</string>
+    <string name="speed_dial_cancel">"取消"</string>
+    <string name="speed_dial_ok">"确定"</string>
+    <string name="call_data_info_label">"通话/流量计时器"</string>
+    <string name="call_data_info_description">"语音通话时长和流量使用时间"</string>
+    <string name="alert_call_over_wifi">"将通过 Wi-Fi 拨打电话。"</string>
+    <string name="alert_call_no_cellular_coverage">"移动网络不可用。请连接至可用的 Wi-Fi 拨打电话。"</string>
+    <string name="alert_user_connect_to_wifi_for_call">"请连接至 Wi-Fi 拨打电话。"</string>
+    <string name="video_call">"视频通话"</string>
+    <string name="video_call_welcome_title"><b>"欢迎使用全新的视频通话拨号器"</b></string>
+    <string name="video_call_welcome_message">"我们都希望在电话的另一端传来熟悉的声音,但打电话显然比不上面对面交流!下面介绍了如何获取实时(或 FaceTime?)连接: 需要 4G LTE 或 Wi-Fi 连接;被叫方设备必须也支持视频通话;视频通话使用高速数据;您也可以将语音通话升级到视频通话;访问 "<a>"https://support.t-mobile.com/docs/DOC-23574"</a>" 了解详细信息。"</string>
+    <string name="video_call_welcome_message_repeat">"每次都显示这条信息"</string>
 </resources>
diff --git a/src/com/android/dialer/calllog/MSimCallLogFragment.java b/src/com/android/dialer/calllog/MSimCallLogFragment.java
index 8f484d8..1eefe53 100644
--- a/src/com/android/dialer/calllog/MSimCallLogFragment.java
+++ b/src/com/android/dialer/calllog/MSimCallLogFragment.java
@@ -71,7 +71,6 @@
 import android.util.Log;
 import android.preference.PreferenceManager;
 import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
 
 import java.util.List;
 
@@ -612,9 +611,8 @@
         }
 
         // Update the sub filter's content.
-        final TelephonyManager telephony = (TelephonyManager) getActivity().getSystemService(
-                Context.TELEPHONY_SERVICE);
-        if (!telephony.isMultiSimEnabled()) {
+        final SubscriptionManager subscriptionManager = SubscriptionManager.from(getActivity());
+        if (subscriptionManager.getActiveSubscriptionInfoCount() < 2) {
             mFilterSubSpinnerView.setVisibility(View.GONE);
         }else{
             ArrayAdapter<SpinnerContent> filterSubAdapter = new ArrayAdapter<SpinnerContent>(
diff --git a/src/com/android/dialer/database/DialerDatabaseHelper.java b/src/com/android/dialer/database/DialerDatabaseHelper.java
old mode 100755
new mode 100644
index 05f94a5..1d3de31
--- a/src/com/android/dialer/database/DialerDatabaseHelper.java
+++ b/src/com/android/dialer/database/DialerDatabaseHelper.java
@@ -19,6 +19,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDatabase;
@@ -50,6 +51,7 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 
+import java.io.File;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -84,6 +86,8 @@
      * </pre>
      */
     public static final int DATABASE_VERSION = 9;
+    public static final int DATABASE_SHAREPREF_VERSION = 1;
+    public static final String DATABASE_SHAREPREF_KEY = "database_sharepref_key";
     public static final String DATABASE_NAME = "dialer.db";
 
     /**
@@ -459,6 +463,11 @@
         setupTables(db);
     }
 
+    @Override
+    public void onOpen(SQLiteDatabase db) {
+        upgradeSmartSearchDatabase(db);
+    }
+
     private void setupTables(SQLiteDatabase db) {
         dropTables(db);
         db.execSQL("CREATE TABLE " + Tables.SMARTDIAL_TABLE + " ("
@@ -514,6 +523,49 @@
         }
     }
 
+    private boolean isNeedUpgradeForSmartSearch() {
+        String FILENAME = "upgradeSmartSearchTable";
+
+        Log.d(TAG, "Shared Preference Created with name:  " + FILENAME);
+        SharedPreferences pref = mContext.getSharedPreferences(FILENAME,
+                mContext.MODE_PRIVATE);
+        if (pref != null) {
+            int mSharePrefVersion = pref.getInt(DATABASE_SHAREPREF_KEY,0);
+            if(mSharePrefVersion < DATABASE_SHAREPREF_VERSION) {
+                Editor editor;
+                editor = pref.edit();
+                editor.putInt(DATABASE_SHAREPREF_KEY, DATABASE_SHAREPREF_VERSION);
+                editor.commit();
+                return true;
+            }
+            return false;
+        } else {
+            Log.d(TAG, "fail to get SharedPreferences !");
+            return false;
+        }
+    }
+
+    private void upgradeSmartSearchDatabase(SQLiteDatabase db) {
+        if (isNeedUpgradeForSmartSearch()) {
+            db.beginTransaction();
+            try {
+                upgradeDatabaseSmartSearch(db);
+                db.setTransactionSuccessful();
+            } catch (Throwable ex) {
+                Log.e(TAG, ex.getMessage(), ex);
+            } finally {
+                db.endTransaction();
+            }
+        }
+    }
+
+    private void upgradeDatabaseSmartSearch(SQLiteDatabase db) {
+        db.execSQL("ALTER TABLE " +  Tables.SMARTDIAL_TABLE + " ADD COLUMN " +
+                SmartDialDbColumns.ACCOUNT_TYPE + " TEXT;");
+        db.execSQL("ALTER TABLE " +  Tables.SMARTDIAL_TABLE + " ADD COLUMN " +
+                SmartDialDbColumns.ACCOUNT_NAME + " TEXT;");
+    }
+
     public void dropTables(SQLiteDatabase db) {
         db.execSQL("DROP TABLE IF EXISTS " + Tables.PREFIX_TABLE);
         db.execSQL("DROP TABLE IF EXISTS " + Tables.SMARTDIAL_TABLE);
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index d5f0035..8dab294 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -316,8 +316,6 @@
         = "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;
 
@@ -709,6 +707,14 @@
         // Long-pressing zero button will enter '+' instead.
         final DialpadKeyButton zero = (DialpadKeyButton) fragmentView.findViewById(R.id.zero);
         zero.setOnLongClickListener(this);
+
+        // Long-pressing star button will enter ','(pause) instead.
+        final DialpadKeyButton star = (DialpadKeyButton) fragmentView.findViewById(R.id.star);
+        star.setOnLongClickListener(this);
+
+        // Long-pressing pound button will enter ';'(wait) instead.
+        final DialpadKeyButton pound = (DialpadKeyButton) fragmentView.findViewById(R.id.pound);
+        pound.setOnLongClickListener(this);
     }
 
     @Override
@@ -816,8 +822,7 @@
             };
             IntentFilter filter = new IntentFilter(ACTION_WIFI_CALL_READY_STATUS_CHANGE);
             context.registerReceiver(mWifiCallReadyReceiver, filter);
-            changeDialpadButton(
-                    SystemProperties.getBoolean(SYSTEM_PROPERTY_WIFI_CALL_READY, false));
+            changeDialpadButton(WifiCallUtils.isWifiCallReadyEnabled(context));
          }
         Trace.endSection();
     }
@@ -1181,6 +1186,28 @@
                 mDigits.setCursorVisible(true);
                 return false;
             }
+            case R.id.star: {
+                if (mDigits.length() > 1) {
+                    // Remove tentative input ('*') done by onTouch().
+                    removePreviousDigitIfPossible('*');
+                    keyPressed(KeyEvent.KEYCODE_COMMA);
+                    stopTone();
+                    mPressedDialpadKeys.remove(view);
+                    return true;
+                }
+                return false;
+            }
+            case R.id.pound: {
+                if (mDigits.length() > 1) {
+                    // Remove tentative input ('#') done by onTouch().
+                    removePreviousDigitIfPossible('#');
+                    keyPressed(KeyEvent.KEYCODE_SEMICOLON);
+                    stopTone();
+                    mPressedDialpadKeys.remove(view);
+                    return true;
+                }
+                return false;
+            }
             case R.id.two:
             case R.id.three:
             case R.id.four:
@@ -1511,8 +1538,6 @@
             mFloatingActionButtonController.setVisible(true);
             mDialpadChooser.setVisibility(View.GONE);
         }
-
-        onHiddenChanged(false);
     }
 
     /**
diff --git a/src/com/android/dialer/util/WifiCallUtils.java b/src/com/android/dialer/util/WifiCallUtils.java
index fb143c8..0aa9a43 100644
--- a/src/com/android/dialer/util/WifiCallUtils.java
+++ b/src/com/android/dialer/util/WifiCallUtils.java
@@ -41,7 +41,7 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.os.Handler;
-import android.os.SystemProperties;
+import android.provider.Settings;
 import android.telephony.CellInfo;
 import android.telephony.TelephonyManager;
 import android.util.Log;
@@ -63,11 +63,13 @@
     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";
+    private static final String WIFI_CALL_READY = "wifi_call_ready";
+    private static final String WIFI_CALL_TURNON = "wifi_call_turnon";
+    private static final int WIFI_CALLING_DISABLED = 0;
+    private static final int WIFI_CALLING_ENABLED = 1;
 
     public void addWifiCallReadyMarqueeMessage(Context context) {
-        if (mViewRemoved && SystemProperties.getBoolean(SYSTEM_PROPERTY_WIFI_CALL_READY, false)) {
+        if (mViewRemoved && isWifiCallReadyEnabled(context)) {
             if (mWindowManager == null) mWindowManager =
                 (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
             if(mTextView == null){
@@ -168,9 +170,18 @@
         diaBuilder.create().show();
     }
 
+    public static boolean isWifiCallReadyEnabled(final Context context) {
+        return (Settings.Global.getInt(context.getContentResolver(),
+                WIFI_CALL_READY, WIFI_CALLING_DISABLED) == WIFI_CALLING_ENABLED);
+    }
+
+    public static boolean isWifiCallTurnOnEnabled(final Context context){
+        return (Settings.Global.getInt(context.getContentResolver(),
+                WIFI_CALL_TURNON, WIFI_CALLING_DISABLED) == WIFI_CALLING_ENABLED);
+    }
+
     public static boolean shallShowWifiCallDialog(final Context context) {
-        boolean wifiCallTurnOn = SystemProperties.getBoolean(
-                SYSTEM_PROPERTY_WIFI_CALL_TURNON, false);
+        boolean wifiCallTurnOn = isWifiCallTurnOnEnabled(context);
 
         ConnectivityManager conManager = (ConnectivityManager) context
                 .getSystemService(Context.CONNECTIVITY_SERVICE);