Merge "Support VPN Proxy(2/2)"
diff --git a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
index 6af0911..d7fcb2f 100644
--- a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
+++ b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java
@@ -27,9 +27,19 @@
  */
 public class FilteredCountryTimeZones {
 
-    // New timezone list and the meta data of time zone, notUsedAfter, is introduced in Android P
-    // in 2018. Only show time zone used in or after 2018.
-    private static final long MIN_USE_DATE_OF_TIMEZONE = 1514764800000L; // 1/1/2018 00:00 UTC
+    /**
+     * The timestamp used to determine which time zones to show to users by using the notUsedAfter
+     * metadata Android holds for each time zone.
+     *
+     * notUsedAfter exists because some time zones effectively "merge" with other time zones after
+     * a given point in time (i.e. they have identical transitions, offsets, etc.). After that
+     * point we only need to show one of the functionally identical ones.
+     *
+     * Rather than using System.currentTimeMillis(), UX folks asked for consistent behavior and so
+     * a timestamp known to be in the recent past is used. This should be updated occasionally but
+     * it doesn't have to be very often.
+     */
+    private static final long MIN_USE_DATE_OF_TIMEZONE = 1546300800000L; // 1/1/2019 00:00 UTC
 
     private final CountryTimeZones mCountryTimeZones;
     private final List<String> mTimeZoneIds;
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
index 33e8d85..e50cb95 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
@@ -89,6 +89,7 @@
     private boolean mValidListener = false;
     private boolean mEditableWfcMode = true;
     private boolean mEditableWfcRoamingMode = true;
+    private boolean mUseWfcHomeModeForRoaming = false;
 
     private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private ImsManager mImsManager;
@@ -312,6 +313,9 @@
                         CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL);
                 mEditableWfcRoamingMode = b.getBoolean(
                         CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL);
+                mUseWfcHomeModeForRoaming = b.getBoolean(
+                        CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL,
+                        false);
                 isWifiOnlySupported = b.getBoolean(
                         CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, true);
             }
@@ -496,7 +500,7 @@
                 // Don't show WFC (home) preference if it's not editable.
                 preferenceScreen.removePreference(mButtonWfcMode);
             }
-            if (mEditableWfcRoamingMode) {
+            if (mEditableWfcRoamingMode && !mUseWfcHomeModeForRoaming) {
                 preferenceScreen.addPreference(mButtonWfcRoamingMode);
             } else {
                 // Don't show WFC roaming preference if it's not editable.
@@ -525,10 +529,8 @@
                 mImsManager.setWfcMode(buttonMode, false);
                 mButtonWfcMode.setSummary(getWfcModeSummary(buttonMode));
                 mMetricsFeatureProvider.action(getActivity(), getMetricsCategory(), buttonMode);
-            }
-            if (!mEditableWfcRoamingMode) {
-                int currentWfcRoamingMode = mImsManager.getWfcMode(true);
-                if (buttonMode != currentWfcRoamingMode) {
+
+                if (mUseWfcHomeModeForRoaming) {
                     mImsManager.setWfcMode(buttonMode, true);
                     // mButtonWfcRoamingMode.setSummary is not needed; summary is selected value
                 }
diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
index a5e80c6..2f2fa62 100644
--- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
@@ -19,18 +19,23 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+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.Intent;
 import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
 import android.telephony.ims.ProvisioningManager;
 import android.view.View;
 import android.widget.TextView;
@@ -54,17 +59,23 @@
 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;
 import org.robolectric.util.ReflectionHelpers;
 
-@RunWith(SettingsRobolectricTestRunner.class)
+@RunWith(RobolectricTestRunner.class)
 @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
 public class WifiCallingSettingsForSubTest {
+    private static final String BUTTON_WFC_MODE = "wifi_calling_mode";
+    private static final String BUTTON_WFC_ROAMING_MODE = "wifi_calling_roaming_mode";
+
     private TestFragment mFragment;
     private Context mContext;
     private TextView mEmptyView;
+    private final PersistableBundle mBundle = new PersistableBundle();
 
+    @Mock private static CarrierConfigManager sCarrierConfigManager;
     @Mock private ImsManager mImsManager;
     @Mock private PreferenceScreen mPreferenceScreen;
     @Mock private SettingsActivity mActivity;
@@ -72,6 +83,8 @@
     @Mock private ToggleSwitch mToggleSwitch;
     @Mock private View mView;
     @Mock private ImsConfig mImsConfig;
+    @Mock private ListPreference mButtonWfcMode;
+    @Mock private ListPreference mButtonWfcRoamingMode;
 
     @Before
     public void setUp() throws NoSuchFieldException, ImsException {
@@ -90,6 +103,8 @@
         when(mFragment.getArguments()).thenReturn(bundle);
         doNothing().when(mFragment).addPreferencesFromResource(anyInt());
         doReturn(mock(ListPreference.class)).when(mFragment).findPreference(any());
+        doReturn(mButtonWfcMode).when(mFragment).findPreference(BUTTON_WFC_MODE);
+        doReturn(mButtonWfcRoamingMode).when(mFragment).findPreference(BUTTON_WFC_ROAMING_MODE);
         doNothing().when(mFragment).finish();
         doReturn(mView).when(mFragment).getView();
 
@@ -102,12 +117,26 @@
         doReturn(mImsManager).when(mFragment).getImsManager();
         doReturn(mImsConfig).when(mImsManager).getConfigInterface();
         doReturn(true).when(mImsManager).isWfcProvisionedOnDevice();
+        doReturn(true).when(mImsManager).isWfcEnabledByUser();
+        doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
+        doReturn(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)
+                .when(mImsManager).getWfcMode(anyBoolean());
+
+        doReturn(mBundle).when(sCarrierConfigManager).getConfigForSubId(anyInt());
+        setDefaultCarrierConfigValues();
 
         mFragment.onAttach(mContext);
         mFragment.onCreate(null);
         mFragment.onActivityCreated(null);
     }
 
+    private void setDefaultCarrierConfigValues() {
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false);
+        mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, true);
+        mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, true);
+    }
+
     @Test
     public void getHelpResource_shouldReturn0() {
         assertThat(mFragment.getHelpResource()).isEqualTo(0);
@@ -143,10 +172,106 @@
         verify(mImsConfig).removeConfigCallback(any());
     }
 
+    @Test
+    public void onResume_useWfcHomeModeConfigFalseAndEditable_shouldShowWfcRoaming() {
+        // Call onResume to update the WFC roaming preference.
+        mFragment.onResume();
+
+        // Check that WFC roaming preference is shown.
+        verify(mPreferenceScreen, times(1)).addPreference(mButtonWfcRoamingMode);
+        verify(mPreferenceScreen, never()).removePreference(mButtonWfcRoamingMode);
+    }
+
+    @Test
+    public void onResume_useWfcHomeModeConfigTrueAndEditable_shouldHideWfcRoaming() {
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, true);
+        mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, true);
+
+        // Call onResume to update the WFC roaming preference.
+        mFragment.onResume();
+
+        // Check that WFC roaming preference is hidden.
+        verify(mPreferenceScreen, never()).addPreference(mButtonWfcRoamingMode);
+        verify(mPreferenceScreen, times(1)).removePreference(mButtonWfcRoamingMode);
+    }
+
+    @Test
+    public void onResume_useWfcHomeModeConfigFalseAndNotEditable_shouldHideWfcRoaming() {
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false);
+        mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
+
+        // Call onResume to update the WFC roaming preference.
+        mFragment.onResume();
+
+        // Check that WFC roaming preference is hidden.
+        verify(mPreferenceScreen, never()).addPreference(mButtonWfcRoamingMode);
+        verify(mPreferenceScreen, times(1)).removePreference(mButtonWfcRoamingMode);
+    }
+
+    @Test
+    public void onResume_useWfcHomeModeConfigTrueAndNotEditable_shouldHideWfcRoaming() {
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, true);
+        mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
+
+        // Call onResume to update the WFC roaming preference.
+        mFragment.onResume();
+
+        // Check that WFC roaming preference is hidden.
+        verify(mPreferenceScreen, never()).addPreference(mButtonWfcRoamingMode);
+        verify(mPreferenceScreen, times(1)).removePreference(mButtonWfcRoamingMode);
+    }
+
+    @Test
+    public void onPreferenceChange_useWfcHomeModeConfigFalse_shouldNotSetWfcRoaming() {
+        // Call onResume to update carrier config values.
+        mFragment.onResume();
+
+        // Set the WFC home mode.
+        mFragment.onPreferenceChange(mButtonWfcMode,
+                String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED));
+
+        // Check that only WFC home mode is set.
+        verify(mImsManager, times(1)).setWfcMode(
+                eq(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED),
+                eq(false));
+        verify(mImsManager, never()).setWfcMode(
+                eq(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED),
+                eq(true));
+    }
+
+    @Test
+    public void onPreferenceChange_useWfcHomeModeConfigTrue_shouldSetWfcRoaming() {
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, true);
+
+        // Call onResume to update carrier config values.
+        mFragment.onResume();
+
+        // Set the WFC home mode.
+        mFragment.onPreferenceChange(mButtonWfcMode,
+                String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED));
+
+        // Check that both WFC home mode and roaming mode are set.
+        verify(mImsManager, times(1)).setWfcMode(
+                eq(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED),
+                eq(false));
+        verify(mImsManager, times(1)).setWfcMode(
+                eq(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED),
+                eq(true));
+    }
+
     protected static class TestFragment extends WifiCallingSettingsForSub {
         @Override
         protected Object getSystemService(final String name) {
-            return null;
+            switch (name) {
+                case Context.CARRIER_CONFIG_SERVICE:
+                    return sCarrierConfigManager;
+                default:
+                    return null;
+            }
         }
     }
 }