Merge "Add "Your work policy info" entry in Privacy settings" into qt-dev
diff --git a/res/layout/dialog_back_gesture_sensitivity.xml b/res/layout/dialog_back_gesture_sensitivity.xml
new file mode 100644
index 0000000..37ef771
--- /dev/null
+++ b/res/layout/dialog_back_gesture_sensitivity.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:padding="12dp">
+
+    <SeekBar
+        android:id="@+id/back_sensitivity_seekbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:min="0"
+        android:max="3"
+        style="@android:style/Widget.Material.SeekBar.Discrete"
+        android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginTop="2dp"
+        android:layout_marginBottom="8dp">
+
+        <TextView android:id="@+id/low_tick"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:layout_weight="1"
+                  android:layout_marginBottom="2dp"
+                  android:layout_marginStart="12dp"
+                  android:gravity="start"
+                  android:text="@string/low_label"
+                  android:textAppearance="?android:attr/textAppearance"
+                  android:singleLine="true"
+                  android:ellipsize="marquee" />
+
+        <TextView android:id="@+id/high_tick"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content"
+                  android:layout_weight="1"
+                  android:layout_marginBottom="2dp"
+                  android:layout_marginEnd="12dp"
+                  android:gravity="end"
+                  android:text="@string/high_label"
+                  android:textAppearance="?android:attr/textAppearance"
+                  android:singleLine="true"
+                  android:ellipsize="marquee" />
+
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index fbf1a24..f31a266 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -411,4 +411,7 @@
 
     <!-- Maximum height for SliceView, override on slices/view/src/main/res/values/dimens.xml -->
     <dimen name="abc_slice_large_height">480dp</dimen>
+
+    <!-- System navigation settings illustration height -->
+    <dimen name="system_navigation_illustration_height">320dp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0994be4..1acb5f1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10225,6 +10225,17 @@
     <!-- Content description for the Information icon [CHAR LIMIT=30] -->
     <string name="information_label">Information</string>
 
+    <!-- Label on the left side of sensitivity adjustment slider [CHAR LIMIT=30] -->
+    <string name="low_label">Low</string>
+    <!-- Label on the right side of sensitivity adjustment slider [CHAR LIMIT=30] -->
+    <string name="high_label">High</string>
+
+    <!-- Message for the dialog that explains how increasing sensitivity can affect gestures along the edges. [CHAR LIMIT=NONE] -->
+    <string name="back_sensitivity_dialog_message">\nHigher sensitivity may conflict with any app gestures along the edges of the screen.</string>
+
+    <!-- Title for the dialog that is shown to adjust the back sensitivity [CHAR LIMIT=60] -->
+    <string name="back_sensitivity_dialog_title">Back Sensitivity</string>
+
     <!-- Preference and settings suggestion title text for ambient display double tap (phone) [CHAR LIMIT=60]-->
     <string name="ambient_display_title" product="default">Double-tap to check phone</string>
     <!-- Preference and settings suggestion title text for ambient display double tap (tablet) [CHAR LIMIT=60]-->
diff --git a/src/com/android/settings/gestures/GestureNavigationBackSensitivityDialog.java b/src/com/android/settings/gestures/GestureNavigationBackSensitivityDialog.java
new file mode 100644
index 0000000..164705b
--- /dev/null
+++ b/src/com/android/settings/gestures/GestureNavigationBackSensitivityDialog.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.gestures;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.os.Bundle;
+import android.os.ServiceManager;
+import android.view.View;
+import android.widget.SeekBar;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+/**
+ * Dialog to set the back gesture's sensitivity in Gesture navigation mode.
+ */
+public class GestureNavigationBackSensitivityDialog extends InstrumentedDialogFragment {
+    private static final String TAG = "GestureNavigationBackSensitivityDialog";
+    private static final String KEY_BACK_SENSITIVITY = "back_sensitivity";
+
+    public static void show(SystemNavigationGestureSettings parent, int sensitivity) {
+        if (!parent.isAdded()) {
+            return;
+        }
+
+        final GestureNavigationBackSensitivityDialog dialog =
+                new GestureNavigationBackSensitivityDialog();
+        final Bundle bundle = new Bundle();
+        bundle.putInt(KEY_BACK_SENSITIVITY, sensitivity);
+        dialog.setArguments(bundle);
+        dialog.setTargetFragment(parent, 0);
+        dialog.show(parent.getFragmentManager(), TAG);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(135211145): Use a separate metrics category for this dialog.
+        return SettingsEnums.SETTINGS_GESTURE_SWIPE_UP;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final View view = getActivity().getLayoutInflater().inflate(
+                R.layout.dialog_back_gesture_sensitivity, null);
+        final SeekBar seekBar = view.findViewById(R.id.back_sensitivity_seekbar);
+        seekBar.setProgress(getArguments().getInt(KEY_BACK_SENSITIVITY));
+        return new AlertDialog.Builder(getContext())
+                .setTitle(R.string.back_sensitivity_dialog_title)
+                .setMessage(R.string.back_sensitivity_dialog_message)
+                .setView(view)
+                .setPositiveButton(R.string.okay, (dialog, which) -> {
+                    int sensitivity = seekBar.getProgress();
+                    getArguments().putInt(KEY_BACK_SENSITIVITY, sensitivity);
+                    SystemNavigationGestureSettings.setBackSensitivity(getActivity(),
+                            getOverlayManager(), sensitivity);
+                })
+                .create();
+    }
+
+    private IOverlayManager getOverlayManager() {
+        return IOverlayManager.Stub.asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE));
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/gestures/GestureNavigationNotAvailableDialog.java b/src/com/android/settings/gestures/GestureNavigationNotAvailableDialog.java
new file mode 100644
index 0000000..e69db27
--- /dev/null
+++ b/src/com/android/settings/gestures/GestureNavigationNotAvailableDialog.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.gestures;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+/**
+ * Dialog to notify user that gesture navigation is not available because of unsupported launcher.
+ */
+public class GestureNavigationNotAvailableDialog extends InstrumentedDialogFragment {
+    private static final String TAG = "GestureNavigationNotAvailableDialog";
+
+    public static void show(SystemNavigationGestureSettings parent) {
+        if (!parent.isAdded()) {
+            return;
+        }
+
+        final GestureNavigationNotAvailableDialog dialog =
+                new GestureNavigationNotAvailableDialog();
+        dialog.setTargetFragment(parent, 0);
+        dialog.show(parent.getFragmentManager(), TAG);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(135211145): Use a separate metrics category for this dialog.
+        return SettingsEnums.SETTINGS_GESTURE_SWIPE_UP;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final Context context = getActivity();
+        final String defaultHomeAppName = SystemNavigationPreferenceController
+                .getDefaultHomeAppName(context);
+        final String message = getString(R.string.gesture_not_supported_dialog_message,
+                defaultHomeAppName);
+        return new AlertDialog.Builder(context)
+                .setMessage(message)
+                .setPositiveButton(R.string.okay, null)
+                .create();
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index 28b76b2..b3d090d 100644
--- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
+++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
@@ -23,14 +23,15 @@
 
 import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
 import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_INFO;
+import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
 
-import android.app.AlertDialog;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
 import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -65,6 +66,11 @@
     private static final String TAG = "SystemNavigationGesture";
 
     @VisibleForTesting
+    static final String SHARED_PREFERENCES_NAME = "system_navigation_settings_preferences";
+    @VisibleForTesting
+    static final String PREFS_BACK_SENSITIVITY_KEY = "system_navigation_back_sensitivity";
+
+    @VisibleForTesting
     static final String KEY_SYSTEM_NAV_3BUTTONS = "system_nav_3buttons";
     @VisibleForTesting
     static final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons";
@@ -74,6 +80,25 @@
     public static final String PREF_KEY_SUGGESTION_COMPLETE =
             "pref_system_navigation_suggestion_complete";
 
+    @VisibleForTesting
+    static final String NAV_BAR_MODE_GESTURAL_OVERLAY_NARROW_BACK
+            = "com.android.internal.systemui.navbar.gestural_narrow_back";
+    @VisibleForTesting
+    static final String NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK
+            = "com.android.internal.systemui.navbar.gestural_wide_back";
+    @VisibleForTesting
+    static final String NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK
+            = "com.android.internal.systemui.navbar.gestural_extra_wide_back";
+    @VisibleForTesting
+    static final String[] BACK_GESTURE_INSET_OVERLAYS = {
+            NAV_BAR_MODE_GESTURAL_OVERLAY_NARROW_BACK,
+            NAV_BAR_MODE_GESTURAL_OVERLAY,
+            NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK,
+            NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK
+    };
+    @VisibleForTesting
+    static int BACK_GESTURE_INSET_DEFAULT_OVERLAY = 1;
+
     private IOverlayManager mOverlayManager;
 
     private VideoPreference mVideoPreference;
@@ -91,6 +116,9 @@
 
         mVideoPreference = new VideoPreference(context);
         setIllustrationVideo(mVideoPreference, getDefaultKey());
+        mVideoPreference.setHeight( /* Illustration height in dp */
+                getResources().getDimension(R.dimen.system_navigation_illustration_height)
+                        / getResources().getDisplayMetrics().density);
     }
 
     @Override
@@ -99,11 +127,6 @@
     }
 
     @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.system_navigation_gesture_settings;
-    }
-
-    @Override
     public void updateCandidates() {
         final String defaultKey = getDefaultKey();
         final String systemDefaultKey = getSystemDefaultKey();
@@ -126,6 +149,39 @@
     }
 
     @Override
+    public void bindPreferenceExtra(RadioButtonPreference pref,
+            String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
+        if (!(info instanceof NavModeCandidateInfo)
+                || !(pref instanceof RadioButtonPreferenceWithExtraWidget)) {
+            return;
+        }
+
+        pref.setSummary(((NavModeCandidateInfo) info).loadSummary());
+
+        RadioButtonPreferenceWithExtraWidget p = (RadioButtonPreferenceWithExtraWidget) pref;
+        if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL) {
+            if (SystemNavigationPreferenceController.isGestureNavSupportedByDefaultLauncher(
+                    getContext())) {
+                p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
+                p.setExtraWidgetOnClickListener((v) -> GestureNavigationBackSensitivityDialog
+                        .show(this, getBackSensitivity(getContext(), mOverlayManager)));
+            } else {
+                p.setEnabled(false);
+                p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_INFO);
+                p.setExtraWidgetOnClickListener((v) ->
+                        GestureNavigationNotAvailableDialog.show(this));
+            }
+        } else {
+            p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
+        }
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.system_navigation_gesture_settings;
+    }
+
+    @Override
     protected List<? extends CandidateInfo> getCandidates() {
         final Context c = getContext();
         List<NavModeCandidateInfo> candidates = new ArrayList<>();
@@ -169,7 +225,7 @@
             return false;
         }
 
-        setCurrentSystemNavigationMode(mOverlayManager, key);
+        setCurrentSystemNavigationMode(c, mOverlayManager, key);
         setIllustrationVideo(mVideoPreference, key);
         if (TextUtils.equals(KEY_SYSTEM_NAV_GESTURAL, key) && (
                 isAnyServiceSupportAccessibilityButton() || isNavBarMagnificationEnabled())) {
@@ -181,6 +237,37 @@
     }
 
     @VisibleForTesting
+    static void setBackSensitivity(Context context, IOverlayManager overlayManager,
+            int sensitivity) {
+        if (sensitivity < 0 || sensitivity >= BACK_GESTURE_INSET_OVERLAYS.length) {
+            throw new IllegalArgumentException("Sensitivity out of range.");
+        }
+
+        // Store the sensitivity level, to be able to restore when user returns to Gesture Nav mode
+        context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).edit()
+                .putInt(PREFS_BACK_SENSITIVITY_KEY, sensitivity).apply();
+        if (getCurrentSystemNavigationMode(context) == KEY_SYSTEM_NAV_GESTURAL) {
+            setNavBarInteractionMode(overlayManager, BACK_GESTURE_INSET_OVERLAYS[sensitivity]);
+        }
+    }
+
+    @VisibleForTesting
+    static int getBackSensitivity(Context context, IOverlayManager overlayManager) {
+        for (int i = 0; i < BACK_GESTURE_INSET_OVERLAYS.length; i++) {
+            OverlayInfo info = null;
+            try {
+                info = overlayManager.getOverlayInfo(BACK_GESTURE_INSET_OVERLAYS[i], USER_CURRENT);
+            } catch (RemoteException e) { /* Do nothing */ }
+            if (info != null && info.isEnabled()) {
+                return i;
+            }
+        }
+        // If Gesture nav is not selected, read the value from shared preferences.
+        return context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .getInt(PREFS_BACK_SENSITIVITY_KEY, BACK_GESTURE_INSET_DEFAULT_OVERLAY);
+    }
+
+    @VisibleForTesting
     static String getCurrentSystemNavigationMode(Context context) {
         if (SystemNavigationPreferenceController.isEdgeToEdgeEnabled(context)) {
             return KEY_SYSTEM_NAV_GESTURAL;
@@ -192,10 +279,12 @@
     }
 
     @VisibleForTesting
-    static void setCurrentSystemNavigationMode(IOverlayManager overlayManager, String key) {
+    static void setCurrentSystemNavigationMode(Context context, IOverlayManager overlayManager,
+            String key) {
         switch (key) {
             case KEY_SYSTEM_NAV_GESTURAL:
-                setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_GESTURAL_OVERLAY);
+                int sensitivity = getBackSensitivity(context, overlayManager);
+                setNavBarInteractionMode(overlayManager, BACK_GESTURE_INSET_OVERLAYS[sensitivity]);
                 break;
             case KEY_SYSTEM_NAV_2BUTTONS:
                 setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY);
@@ -206,10 +295,8 @@
         }
     }
 
-    /**
-     * Enables the specified overlay package.
-     */
-    static void setNavBarInteractionMode(IOverlayManager overlayManager, String overlayPackage) {
+    private static void setNavBarInteractionMode(IOverlayManager overlayManager,
+            String overlayPackage) {
         try {
             overlayManager.setEnabledExclusiveInCategory(overlayPackage, USER_CURRENT);
         } catch (RemoteException e) {
@@ -217,7 +304,7 @@
         }
     }
 
-    static void setIllustrationVideo(VideoPreference videoPref, String systemNavKey) {
+    private static void setIllustrationVideo(VideoPreference videoPref, String systemNavKey) {
         videoPref.setVideo(0, 0);
         switch (systemNavKey) {
             case KEY_SYSTEM_NAV_GESTURAL:
@@ -233,41 +320,6 @@
         }
     }
 
-    @Override
-    public void bindPreferenceExtra(RadioButtonPreference pref,
-            String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
-        if (!(info instanceof NavModeCandidateInfo)
-                || !(pref instanceof RadioButtonPreferenceWithExtraWidget)) {
-            return;
-        }
-
-        pref.setSummary(((NavModeCandidateInfo) info).loadSummary());
-
-        RadioButtonPreferenceWithExtraWidget p = (RadioButtonPreferenceWithExtraWidget) pref;
-        if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL
-                && !SystemNavigationPreferenceController.isGestureNavSupportedByDefaultLauncher(
-                        getContext())) {
-            p.setEnabled(false);
-            p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_INFO);
-            p.setExtraWidgetOnClickListener((v) -> {
-                showGestureNavDisabledDialog();
-            });
-        } else {
-            p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE);
-        }
-    }
-
-    private void showGestureNavDisabledDialog() {
-        final String defaultHomeAppName = SystemNavigationPreferenceController
-                .getDefaultHomeAppName(getContext());
-        final String message = getString(R.string.gesture_not_supported_dialog_message,
-                defaultHomeAppName);
-        AlertDialog d = new AlertDialog.Builder(getContext())
-                .setMessage(message)
-                .setPositiveButton(R.string.okay, null)
-                .show();
-    }
-
     private boolean isAnyServiceSupportAccessibilityButton() {
         final AccessibilityManager ams = (AccessibilityManager) getContext().getSystemService(
                 Context.ACCESSIBILITY_SERVICE);
diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
index c71ee35..4d4d3ef 100644
--- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
@@ -114,6 +114,10 @@
         if (mSimCallManager != null) {
             Intent intent = MobileNetworkUtils.buildPhoneAccountConfigureIntent(mContext,
                     mSimCallManager);
+            if (intent == null) {
+                // Do nothing in this case since preference is invisible
+                return;
+            }
             final PackageManager pm = mContext.getPackageManager();
             List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
             preference.setTitle(resolutions.get(0).loadLabel(pm));
diff --git a/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java b/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java
index 6a47ce5..19fd923 100644
--- a/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java
+++ b/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java
@@ -27,6 +27,7 @@
 public class RadioButtonPreferenceWithExtraWidget extends RadioButtonPreference {
     public static final int EXTRA_WIDGET_VISIBILITY_GONE = 0;
     public static final int EXTRA_WIDGET_VISIBILITY_INFO = 1;
+    public static final int EXTRA_WIDGET_VISIBILITY_SETTING = 2;
 
     private View mExtraWidgetDivider;
     private ImageView mExtraWidget;
@@ -66,6 +67,15 @@
             mExtraWidget.setClickable(true);
             mExtraWidget.setVisibility(View.VISIBLE);
             mExtraWidgetDivider.setVisibility(View.VISIBLE);
+            if (mExtraWidgetVisibility == EXTRA_WIDGET_VISIBILITY_INFO) {
+                mExtraWidget.setImageResource(R.drawable.ic_settings_about);
+                mExtraWidget.setContentDescription(
+                        getContext().getResources().getText(R.string.information_label));
+            } else if (mExtraWidgetVisibility == EXTRA_WIDGET_VISIBILITY_SETTING) {
+                mExtraWidget.setImageResource(R.drawable.ic_settings_accent);
+                mExtraWidget.setContentDescription(
+                        getContext().getResources().getText(R.string.settings_label));
+            }
         }
     }
 
diff --git a/tests/robotests/src/com/android/settings/gestures/SystemNavigationGestureSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/SystemNavigationGestureSettingsTest.java
index 1f3a758..24cb9ed 100644
--- a/tests/robotests/src/com/android/settings/gestures/SystemNavigationGestureSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SystemNavigationGestureSettingsTest.java
@@ -24,21 +24,30 @@
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
 
+import static com.android.settings.gestures.SystemNavigationGestureSettings.BACK_GESTURE_INSET_DEFAULT_OVERLAY;
+import static com.android.settings.gestures.SystemNavigationGestureSettings.BACK_GESTURE_INSET_OVERLAYS;
 import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_2BUTTONS;
 import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_3BUTTONS;
 import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_GESTURAL;
+import static com.android.settings.gestures.SystemNavigationGestureSettings.NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK;
+import static com.android.settings.gestures.SystemNavigationGestureSettings.NAV_BAR_MODE_GESTURAL_OVERLAY_NARROW_BACK;
+import static com.android.settings.gestures.SystemNavigationGestureSettings.NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.mock;
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.om.IOverlayManager;
-import android.os.ServiceManager;
+import android.content.om.OverlayInfo;
 import android.provider.SearchIndexableResource;
-import android.text.TextUtils;
 
 import com.android.internal.R;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
@@ -46,6 +55,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
@@ -57,17 +68,25 @@
 public class SystemNavigationGestureSettingsTest {
 
     private Context mContext;
-
-    private IOverlayManager mOverlayManager;
-
     private SystemNavigationGestureSettings mSettings;
 
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mOverlayManager = mock(IOverlayManager.class);
+    @Mock
+    private IOverlayManager mOverlayManager;
+    @Mock
+    private OverlayInfo mOverlayInfoEnabled;
+    @Mock
+    private OverlayInfo mOverlayInfoDisabled;
 
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application;
         mSettings = new SystemNavigationGestureSettings();
+
+        when(mOverlayInfoDisabled.isEnabled()).thenReturn(false);
+        when(mOverlayInfoEnabled.isEnabled()).thenReturn(true);
+        when(mOverlayManager.getOverlayInfo(any(), anyInt())).thenReturn(mOverlayInfoDisabled);
     }
 
     @Test
@@ -82,34 +101,111 @@
 
     @Test
     public void testGetCurrentSystemNavigationMode() {
-        SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
-                NAV_BAR_MODE_GESTURAL);
-        assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext),
-                KEY_SYSTEM_NAV_GESTURAL)).isTrue();
+        SettingsShadowResources.overrideResource(
+                R.integer.config_navBarInteractionMode, NAV_BAR_MODE_GESTURAL);
+        assertEquals(KEY_SYSTEM_NAV_GESTURAL, mSettings.getCurrentSystemNavigationMode(mContext));
 
-        SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
-                NAV_BAR_MODE_3BUTTON);
-        assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext),
-                KEY_SYSTEM_NAV_3BUTTONS)).isTrue();
+        SettingsShadowResources.overrideResource(
+                R.integer.config_navBarInteractionMode, NAV_BAR_MODE_3BUTTON);
+        assertEquals(KEY_SYSTEM_NAV_3BUTTONS, mSettings.getCurrentSystemNavigationMode(mContext));
 
-        SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode,
-                NAV_BAR_MODE_2BUTTON);
-        assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext),
-                KEY_SYSTEM_NAV_2BUTTONS)).isTrue();
+        SettingsShadowResources.overrideResource(
+                R.integer.config_navBarInteractionMode, NAV_BAR_MODE_2BUTTON);
+        assertEquals(KEY_SYSTEM_NAV_2BUTTONS, mSettings.getCurrentSystemNavigationMode(mContext));
     }
 
     @Test
     public void testSetCurrentSystemNavigationMode() throws Exception {
-        mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_GESTURAL);
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 0);
+        mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager,
+                KEY_SYSTEM_NAV_GESTURAL);
+        verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
+                NAV_BAR_MODE_GESTURAL_OVERLAY_NARROW_BACK, USER_CURRENT);
+
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 1);
+        mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager,
+                KEY_SYSTEM_NAV_GESTURAL);
         verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
                 NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT);
 
-        mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_2BUTTONS);
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 2);
+        mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager,
+                KEY_SYSTEM_NAV_GESTURAL);
+        verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
+                NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK, USER_CURRENT);
+
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 3);
+        mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager,
+                KEY_SYSTEM_NAV_GESTURAL);
+        verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
+                NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK, USER_CURRENT);
+
+        mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager,
+                KEY_SYSTEM_NAV_2BUTTONS);
         verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
                 NAV_BAR_MODE_2BUTTON_OVERLAY, USER_CURRENT);
 
-        mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_3BUTTONS);
+        mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager,
+                KEY_SYSTEM_NAV_3BUTTONS);
         verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
                 NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
     }
+
+    @Test
+    public void testSetCurrentSystemNavigationMode_backSensitivityValuePersists() throws Exception {
+        SettingsShadowResources.overrideResource(
+                R.integer.config_navBarInteractionMode, NAV_BAR_MODE_3BUTTON);
+
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 2);
+        mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager,
+                KEY_SYSTEM_NAV_3BUTTONS);
+        verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
+                NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
+
+        // Return to Gesture navigation, without setting the sensitivity value.
+        mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager,
+                KEY_SYSTEM_NAV_GESTURAL);
+        verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
+                NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK, USER_CURRENT);
+    }
+
+    @Test
+    public void testGetBackSensitivity_default() {
+        assertEquals(BACK_GESTURE_INSET_DEFAULT_OVERLAY,
+                mSettings.getBackSensitivity(mContext, mOverlayManager));
+    }
+
+    @Test
+    public void testBackSensitivitySetterAndGetter_currentNavModeNotGestural() throws Exception {
+        SettingsShadowResources.overrideResource(
+                R.integer.config_navBarInteractionMode, NAV_BAR_MODE_3BUTTON);
+
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 3);
+        assertEquals(3, mSettings.getBackSensitivity(mContext, mOverlayManager));
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 2);
+        assertEquals(2, mSettings.getBackSensitivity(mContext, mOverlayManager));
+
+        verify(mOverlayManager, never()).setEnabledExclusiveInCategory(any(), anyInt());
+    }
+
+    @Test
+    public void testBackSensitivitySetterAndGetter_currentNavModeIsGestural() throws Exception {
+        SettingsShadowResources.overrideResource(
+                R.integer.config_navBarInteractionMode, NAV_BAR_MODE_GESTURAL);
+
+        when(mOverlayManager.getOverlayInfo(BACK_GESTURE_INSET_OVERLAYS[3], USER_CURRENT))
+                .thenReturn(mOverlayInfoEnabled);
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 3);
+        assertEquals(3, mSettings.getBackSensitivity(mContext, mOverlayManager));
+
+        when(mOverlayManager.getOverlayInfo(BACK_GESTURE_INSET_OVERLAYS[2], USER_CURRENT))
+                .thenReturn(mOverlayInfoEnabled);
+        mSettings.setBackSensitivity(mContext, mOverlayManager, 2);
+        assertEquals(2, mSettings.getBackSensitivity(mContext, mOverlayManager));
+
+        verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
+                NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK, USER_CURRENT);
+        verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory(
+                NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK, USER_CURRENT);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
index 1a0126e..42422f9 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
@@ -27,6 +27,7 @@
 import android.content.Intent;
 import android.os.PersistableBundle;
 import android.provider.Settings;
+import android.telecom.PhoneAccountHandle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -118,6 +119,14 @@
     }
 
     @Test
+    public void updateState_invalidPhoneAccountHandle_shouldNotCrash() {
+        mController.mSimCallManager = new PhoneAccountHandle(null /* invalid */, "");
+
+        //Should not crash
+        mController.updateState(mPreference);
+    }
+
+    @Test
     public void updateState_wfcNonRoaming() {
         assertNull(mController.mSimCallManager);
         mCarrierConfig.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
diff --git a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java
index b84b3bb..2e2d786 100644
--- a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java
+++ b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java
@@ -18,6 +18,7 @@
 
 import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE;
 import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_INFO;
+import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -104,6 +105,18 @@
         assertEquals(View.VISIBLE, mExtraWidget.getVisibility());
         assertEquals(View.VISIBLE, mExtraWidgetDivider.getVisibility());
         assertThat(mExtraWidget.isClickable()).isTrue();
+        assertEquals(mContext.getResources().getText(R.string.information_label),
+                mExtraWidget.getContentDescription());
+    }
+
+    @Test
+    public void testSetExtraWidgetVisibility_setting() {
+        mPreference.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING);
+        assertEquals(View.VISIBLE, mExtraWidget.getVisibility());
+        assertEquals(View.VISIBLE, mExtraWidgetDivider.getVisibility());
+        assertThat(mExtraWidget.isClickable()).isTrue();
+        assertEquals(mContext.getResources().getText(R.string.settings_label),
+                mExtraWidget.getContentDescription());
     }
 
     @Test