From 73ffcf49990ab3134b139607c0225f6ae1646c18 Mon Sep 17 00:00:00 2001 From: Torbjorn Eklund Date: Wed, 9 Jan 2019 11:09:18 +0100 Subject: [PATCH] Close Wi-Fi Calling screen if provisioning status changes to disallow Starts to listen for provisioning changes in Wi-Fi Calling screen and closes the screen if the Wi-Fi Calling provisioning status changes to disallow. This prevents the Wi-Fi Calling screen from being kept open if the Wi-Fi Calling provisioning status is changed to disallow while the Wi-Fi Calling screen is open. Bug: 119389855 Test: make RunSettingsRoboTests \ ROBOTEST_FILTER=WifiCallingSettingsForSubTest Merged-In: I2af91c3734274f0aea942a8bb894d6f4ce295354 Change-Id: I2af91c3734274f0aea942a8bb894d6f4ce295354 --- .../calling/WifiCallingSettingsForSub.java | 48 ++++++- .../WifiCallingSettingsForSubTest.java | 124 +++++++++++++++++- 2 files changed, 167 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java index 00f4758fe34..c0cb4fce690 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java +++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java @@ -33,6 +33,7 @@ import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.telephony.ims.ProvisioningManager; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; @@ -42,7 +43,9 @@ import android.widget.Switch; import android.widget.TextView; import com.android.ims.ImsConfig; +import com.android.ims.ImsException; import com.android.ims.ImsManager; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.Phone; import com.android.settings.R; @@ -150,6 +153,19 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment } }; + private final ProvisioningManager.Callback mProvisioningCallback = + new ProvisioningManager.Callback() { + @Override + public void onProvisioningIntChanged(int item, int value) { + if (item == ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED + || item == ImsConfig.ConfigConstants.VLT_SETTING_ENABLED) { + // The provisioning policy might have changed. Update the body to make sure + // this change takes effect if needed. + updateBody(); + } + } + }; + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -219,6 +235,11 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment return 0; } + @VisibleForTesting + ImsManager getImsManager() { + return ImsManager.getInstance(getActivity(), SubscriptionManager.getPhoneId(mSubId)); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -234,8 +255,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment FRAGMENT_BUNDLE_SUBID, SubscriptionManager.INVALID_SUBSCRIPTION_ID); } - mImsManager = ImsManager.getInstance( - getActivity(), SubscriptionManager.getPhoneId(mSubId)); + mImsManager = getImsManager(); mButtonWfcMode = (ListPreference) findPreference(BUTTON_WFC_MODE); mButtonWfcMode.setOnPreferenceChangeListener(this); @@ -272,6 +292,13 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment } private void updateBody() { + if (!mImsManager.isWfcProvisionedOnDevice()) { + // This screen is not allowed to be shown due to provisioning policy and should + // therefore be closed. + finish(); + return; + } + CarrierConfigManager configManager = (CarrierConfigManager) getSystemService(Context.CARRIER_CONFIG_SERVICE); boolean isWifiOnlySupported = true; @@ -333,6 +360,14 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) { showAlert(intent); } + + // Register callback for provisioning changes. + try { + mImsManager.getConfigInterface().addConfigCallback(mProvisioningCallback); + } catch (ImsException e) { + Log.w(TAG, "onResume: Unable to register callback for provisioning changes."); + } + } @Override @@ -351,6 +386,15 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment } context.unregisterReceiver(mIntentReceiver); + + // Remove callback for provisioning changes. + try { + mImsManager.getConfigInterface().removeConfigCallback( + mProvisioningCallback.getBinder()); + } catch (ImsException e) { + Log.w(TAG, "onPause: Unable to remove callback for provisioning changes"); + } + } /** 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 d60f8cfa0a1..a5e80c67814 100644 --- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java +++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java @@ -18,17 +18,135 @@ package com.android.settings.wifi.calling; import static com.google.common.truth.Truth.assertThat; -import com.android.settings.testutils.SettingsRobolectricTestRunner; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +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.telephony.ims.ProvisioningManager; +import android.view.View; +import android.widget.TextView; + +import androidx.preference.ListPreference; +import androidx.preference.PreferenceScreen; + +import com.android.ims.ImsConfig; +import com.android.ims.ImsException; +import com.android.ims.ImsManager; +import com.android.settings.R; +import com.android.settings.SettingsActivity; +import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.widget.SwitchBar; +import com.android.settings.widget.ToggleSwitch; + +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = SettingsShadowResources.SettingsShadowTheme.class) public class WifiCallingSettingsForSubTest { + private TestFragment mFragment; + private Context mContext; + private TextView mEmptyView; + + @Mock private ImsManager mImsManager; + @Mock private PreferenceScreen mPreferenceScreen; + @Mock private SettingsActivity mActivity; + @Mock private SwitchBar mSwitchBar; + @Mock private ToggleSwitch mToggleSwitch; + @Mock private View mView; + @Mock private ImsConfig mImsConfig; + + @Before + public void setUp() throws NoSuchFieldException, ImsException { + MockitoAnnotations.initMocks(this); + FakeFeatureFactory.setupForTest(); + + mContext = RuntimeEnvironment.application; + doReturn(mContext.getTheme()).when(mActivity).getTheme(); + + mFragment = spy(new TestFragment()); + doReturn(mActivity).when(mFragment).getActivity(); + doReturn(mock(Intent.class)).when(mActivity).getIntent(); + doReturn(mContext.getResources()).when(mFragment).getResources(); + doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen(); + final Bundle bundle = new Bundle(); + when(mFragment.getArguments()).thenReturn(bundle); + doNothing().when(mFragment).addPreferencesFromResource(anyInt()); + doReturn(mock(ListPreference.class)).when(mFragment).findPreference(any()); + doNothing().when(mFragment).finish(); + doReturn(mView).when(mFragment).getView(); + + mEmptyView = new TextView(mContext); + doReturn(mEmptyView).when(mView).findViewById(android.R.id.empty); + + ReflectionHelpers.setField(mSwitchBar, "mSwitch", mToggleSwitch); + doReturn(mSwitchBar).when(mView).findViewById(R.id.switch_bar); + + doReturn(mImsManager).when(mFragment).getImsManager(); + doReturn(mImsConfig).when(mImsManager).getConfigInterface(); + doReturn(true).when(mImsManager).isWfcProvisionedOnDevice(); + + mFragment.onAttach(mContext); + mFragment.onCreate(null); + mFragment.onActivityCreated(null); + } @Test public void getHelpResource_shouldReturn0() { - assertThat(new WifiCallingSettingsForSub().getHelpResource()) - .isEqualTo(0); + assertThat(mFragment.getHelpResource()).isEqualTo(0); + } + + @Test + public void onResume_provisioningAllowed_shouldNotFinish() throws ImsException { + // Call onResume while provisioning is allowed. + mFragment.onResume(); + + // Verify that finish() is not called. + verify(mFragment, never()).finish(); + } + + @Test + public void onResume_provisioningDisallowed_shouldFinish() { + // Call onResume while provisioning is disallowed. + doReturn(false).when(mImsManager).isWfcProvisionedOnDevice(); + mFragment.onResume(); + + // Verify that finish() is called + verify(mFragment).finish(); + } + + @Test + public void onResumeOnPause_provisioningCallbackRegistration() throws ImsException { + // Verify that provisioning callback is registered after call to onResume(). + mFragment.onResume(); + verify(mImsConfig).addConfigCallback(any(ProvisioningManager.Callback.class)); + + // Verify that provisioning callback is unregistered after call to onPause. + mFragment.onPause(); + verify(mImsConfig).removeConfigCallback(any()); + } + + protected static class TestFragment extends WifiCallingSettingsForSub { + @Override + protected Object getSystemService(final String name) { + return null; + } } }