From 69dbf4bf844696f5d48ec0d270a8ffbc6136fd33 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 Change-Id: I2af91c3734274f0aea942a8bb894d6f4ce295354 --- .../wifi/calling/WifiCallingSettingsForSub.java | 48 +++++++- .../calling/WifiCallingSettingsForSubTest.java | 127 ++++++++++++++++++++- 2 files changed, 172 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java index 40cc0dcdf7..9ed2035366 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java +++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java @@ -29,6 +29,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; @@ -44,7 +45,9 @@ import androidx.preference.Preference.OnPreferenceClickListener; import androidx.preference.PreferenceScreen; 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.telephony.Phone; import com.android.settings.R; import com.android.settings.SettingsActivity; @@ -152,6 +155,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); @@ -221,6 +237,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); @@ -236,8 +257,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment FRAGMENT_BUNDLE_SUBID, SubscriptionManager.INVALID_SUBSCRIPTION_ID); } - mImsManager = ImsManager.getInstance( - getActivity(), SubscriptionManager.getPhoneId(mSubId)); + mImsManager = getImsManager(); mTelephonyManager = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE)) .createForSubscriptionId(mSubId); @@ -277,6 +297,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; @@ -336,6 +363,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 @@ -354,6 +389,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 b194d73e0c..98795a7ad4 100644 --- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java +++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java @@ -18,15 +18,140 @@ package com.android.settings.wifi.calling; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertNotNull; +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.preference.PreferenceManager; +import android.telephony.TelephonyManager; +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.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.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) public class WifiCallingSettingsForSubTest { + private TestFragment mFragment; + private Context mContext; + private TextView mEmptyView; + + @Mock private ImsManager mImsManager; + @Mock private TelephonyManager mTelephonyManager; + @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); + + mContext = RuntimeEnvironment.application; + doReturn(mContext.getTheme()).when(mActivity).getTheme(); + + mFragment = spy(new TestFragment()); + doReturn(mActivity).when(mFragment).getActivity(); + doReturn(mContext).when(mFragment).getContext(); + doReturn(mock(Intent.class)).when(mActivity).getIntent(); + doReturn(mContext.getResources()).when(mFragment).getResources(); + doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen(); + doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt()); + 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 class TestFragment extends WifiCallingSettingsForSub { + @Override + protected Object getSystemService(final String name) { + if (Context.TELEPHONY_SERVICE.equals(name)) { + return mTelephonyManager; + } + return null; + } } } -- 2.11.0