diff --git a/src/com/android/settings/network/ims/ImsQueryController.java b/src/com/android/settings/network/ims/ImsQueryController.java index 5519ddd378d..f48fc6afee3 100644 --- a/src/com/android/settings/network/ims/ImsQueryController.java +++ b/src/com/android/settings/network/ims/ImsQueryController.java @@ -31,11 +31,6 @@ abstract class ImsQueryController { private volatile int mTech; private volatile int mTransportType; - /** - * Constructor for query IMS status - */ - ImsQueryController() {} - /** * Constructor for query IMS status * diff --git a/src/com/android/settings/network/ims/ImsQueryProvisioningStat.java b/src/com/android/settings/network/ims/ImsQueryProvisioningStat.java index 34f232d2e79..5c050b520ac 100644 --- a/src/com/android/settings/network/ims/ImsQueryProvisioningStat.java +++ b/src/com/android/settings/network/ims/ImsQueryProvisioningStat.java @@ -45,7 +45,7 @@ public class ImsQueryProvisioningStat implements ImsQuery { } /** - * Implementation of interface {@link ImsQuery} + * Implementation of interface {@link ImsQuery#query()} * * @return result of query */ diff --git a/src/com/android/settings/network/ims/WifiCallingQueryImsState.java b/src/com/android/settings/network/ims/WifiCallingQueryImsState.java index d6703d1d843..ab0bc8c885d 100644 --- a/src/com/android/settings/network/ims/WifiCallingQueryImsState.java +++ b/src/com/android/settings/network/ims/WifiCallingQueryImsState.java @@ -18,10 +18,17 @@ package com.android.settings.network.ims; import android.content.Context; import android.telecom.TelecomManager; +import android.telephony.AccessNetworkConstants; import android.telephony.SubscriptionManager; +import android.telephony.ims.feature.MmTelFeature; +import android.telephony.ims.stub.ImsRegistrationImplBase; import androidx.annotation.VisibleForTesting; +import com.android.ims.ImsManager; +import com.android.settings.network.SubscriptionUtil; +import com.android.settings.network.telephony.MobileNetworkUtils; + /** * Controller class for querying Wifi calling status */ @@ -37,7 +44,9 @@ public class WifiCallingQueryImsState extends ImsQueryController { * @param subId subscription's id */ public WifiCallingQueryImsState(Context context, int subId) { - super(); + super(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, + ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, + AccessNetworkConstants.TRANSPORT_TYPE_WLAN); mContext = context; mSubId = subId; } @@ -50,6 +59,37 @@ public class WifiCallingQueryImsState extends ImsQueryController { return new ImsQueryWfcUserSetting(subId); } + @VisibleForTesting + ImsManager getImsManager(int subId) { + return ImsManager.getInstance(mContext, + SubscriptionUtil.getPhoneId(mContext, subId)); + } + + /** + * Check whether Wifi Calling has been provisioned or not on this subscription + * + * @return true when Wifi Calling has been enabled, otherwise false + */ + public boolean isWifiCallingProvisioned() { + final ImsManager imsManager = getImsManager(mSubId); + if (imsManager == null) { + return false; + } + + return imsManager.isWfcEnabledByPlatform() + && isProvisionedOnDevice(mSubId).query(); + } + + /** + * Check whether Wifi Calling can be perform or not on this subscription + * + * @return true when Wifi Calling can be performed, otherwise false + */ + public boolean isReadyToWifiCalling() { + return isWifiCallingProvisioned() + && MobileNetworkUtils.isImsServiceStateReady(getImsManager(mSubId)); + } + /** * Get allowance status for user to alter configuration * diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java index ec23465012d..e928dba734c 100644 --- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java +++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java @@ -34,9 +34,7 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; -import com.android.ims.ImsManager; import com.android.settings.R; -import com.android.settings.network.SubscriptionUtil; import com.android.settings.network.ims.WifiCallingQueryImsState; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; @@ -56,8 +54,6 @@ public class WifiCallingPreferenceController extends TelephonyBasePreferenceCont Integer mCallState; @VisibleForTesting CarrierConfigManager mCarrierConfigManager; - @VisibleForTesting - ImsManager mImsManager; private ImsMmTelManager mImsMmTelManager; @VisibleForTesting PhoneAccountHandle mSimCallManager; @@ -73,7 +69,7 @@ public class WifiCallingPreferenceController extends TelephonyBasePreferenceCont @Override public int getAvailabilityStatus(int subId) { return SubscriptionManager.isValidSubscriptionId(subId) - && MobileNetworkUtils.isWifiCallingEnabled(mContext, subId) + && isWifiCallingEnabled(mContext, subId) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } @@ -164,8 +160,6 @@ public class WifiCallingPreferenceController extends TelephonyBasePreferenceCont public WifiCallingPreferenceController init(int subId) { mSubId = subId; - mImsManager = ImsManager.getInstance(mContext, - SubscriptionUtil.getPhoneId(mContext, mSubId)); mImsMmTelManager = getImsMmTelManager(mSubId); mSimCallManager = mContext.getSystemService(TelecomManager.class) .getSimCallManagerForSubscription(mSubId); @@ -221,4 +215,23 @@ public class WifiCallingPreferenceController extends TelephonyBasePreferenceCont mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE); } } + + private boolean isWifiCallingEnabled(Context context, int subId) { + final PhoneAccountHandle simCallManager = + context.getSystemService(TelecomManager.class) + .getSimCallManagerForSubscription(subId); + final int phoneId = SubscriptionManager.getSlotIndex(subId); + + boolean isWifiCallingEnabled; + if (simCallManager != null) { + final Intent intent = MobileNetworkUtils.buildPhoneAccountConfigureIntent( + context, simCallManager); + + isWifiCallingEnabled = intent != null; + } else { + isWifiCallingEnabled = queryImsState(subId).isReadyToWifiCalling(); + } + + return isWifiCallingEnabled; + } } diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettings.java b/src/com/android/settings/wifi/calling/WifiCallingSettings.java index 72e1df204f8..5c0ee9bd04c 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingSettings.java +++ b/src/com/android/settings/wifi/calling/WifiCallingSettings.java @@ -22,9 +22,6 @@ import android.os.Bundle; import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; -import android.telephony.ims.ProvisioningManager; -import android.telephony.ims.feature.MmTelFeature; -import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -35,11 +32,11 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; -import com.android.ims.ImsManager; import com.android.internal.util.CollectionUtils; import com.android.settings.R; import com.android.settings.core.InstrumentedFragment; import com.android.settings.network.SubscriptionUtil; +import com.android.settings.network.ims.WifiCallingQueryImsState; import com.android.settings.search.actionbar.SearchMenuController; import com.android.settings.support.actionbar.HelpMenuController; import com.android.settings.support.actionbar.HelpResourceProvider; @@ -196,25 +193,6 @@ public class WifiCallingSettings extends InstrumentedFragment implements HelpRes } } - @VisibleForTesting - boolean isWfcEnabledByPlatform(SubscriptionInfo info) { - final ImsManager imsManager = ImsManager.getInstance(getActivity(), - info.getSimSlotIndex()); - return imsManager.isWfcEnabledByPlatform(); - } - - @VisibleForTesting - boolean isWfcProvisionedOnDevice(SubscriptionInfo info) { - final ProvisioningManager provisioningMgr = - ProvisioningManager.createForSubscriptionId(info.getSubscriptionId()); - if (provisioningMgr == null) { - return true; - } - return provisioningMgr.getProvisioningStatusForCapability( - MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, - ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN); - } - private void updateSubList() { mSil = SubscriptionUtil.getActiveSubscriptions( getContext().getSystemService(SubscriptionManager.class)); @@ -225,7 +203,7 @@ public class WifiCallingSettings extends InstrumentedFragment implements HelpRes } for (int i = 0; i < mSil.size(); ) { final SubscriptionInfo info = mSil.get(i); - if (!isWfcEnabledByPlatform(info) || !isWfcProvisionedOnDevice(info)) { + if (!queryImsState(info.getSubscriptionId()).isWifiCallingProvisioned()) { mSil.remove(i); } else { i++; @@ -241,4 +219,9 @@ public class WifiCallingSettings extends InstrumentedFragment implements HelpRes getActivity().getActionBar().setTitle(title); } } + + @VisibleForTesting + WifiCallingQueryImsState queryImsState(int subId) { + return new WifiCallingQueryImsState(getContext(), subId); + } } diff --git a/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java new file mode 100644 index 00000000000..aa30aa0444a --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 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.network.ims; + +import android.content.Context; + +import com.android.ims.ImsManager; + + +/** + * Controller class for mock Wifi calling status + */ +public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState { + + private ImsQuery mIsTtyOnVolteEnabled; + private ImsQuery mIsProvisionedOnDevice; + private ImsQuery mIsEnabledByUser; + + /** + * Constructor + * + * @param context {@code Context} + * @param subId subscription's id + */ + public MockWifiCallingQueryImsState(Context context, int subId) { + super(context, subId); + } + + public ImsManager getImsManager(int subId) { + return super.getImsManager(subId); + } + + public void setIsTtyOnVolteEnabled(boolean enabled) { + mIsTtyOnVolteEnabled = new MockImsQueryResult.BooleanResult(enabled); + } + + @Override + ImsQuery isTtyOnVolteEnabled(int subId) { + if (mIsTtyOnVolteEnabled != null) { + return mIsTtyOnVolteEnabled; + } + return super.isTtyOnVolteEnabled(subId); + } + + public void setIsProvisionedOnDevice(boolean isProvisioned) { + mIsProvisionedOnDevice = new MockImsQueryResult.BooleanResult(isProvisioned); + } + + @Override + ImsQuery isProvisionedOnDevice(int subId) { + if (mIsProvisionedOnDevice != null) { + return mIsProvisionedOnDevice; + } + return super.isProvisionedOnDevice(subId); + } + + public void setIsEnabledByUser(boolean enabled) { + mIsEnabledByUser = new MockImsQueryResult.BooleanResult(enabled); + } + + @Override + ImsQuery isEnabledByUser(int subId) { + if (mIsEnabledByUser != null) { + return mIsEnabledByUser; + } + return super.isEnabledByUser(subId); + } + +} 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 961f8cb9e33..b91f7188aef 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java @@ -40,7 +40,7 @@ import androidx.preference.PreferenceScreen; import com.android.ims.ImsManager; import com.android.internal.R; import com.android.settings.core.BasePreferenceController; -import com.android.settings.network.ims.WifiCallingQueryImsState; +import com.android.settings.network.ims.MockWifiCallingQueryImsState; import org.junit.Before; import org.junit.Ignore; @@ -66,7 +66,7 @@ public class WifiCallingPreferenceControllerTest { @Mock private PreferenceScreen mPreferenceScreen; - private WifiCallingQueryImsState mQueryImsState; + private MockWifiCallingQueryImsState mQueryImsState; private WifiCallingPreferenceController mController; private Preference mPreference; @@ -79,8 +79,10 @@ public class WifiCallingPreferenceControllerTest { mContext = spy(RuntimeEnvironment.application); - mQueryImsState = spy(new WifiCallingQueryImsState(mContext, SUB_ID)); + mQueryImsState = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID)); doReturn(true).when(mQueryImsState).isEnabledByUser(); + doReturn(mImsManager).when(mQueryImsState).getImsManager(anyInt()); + mQueryImsState.setIsProvisionedOnDevice(true); mPreference = new Preference(mContext); mController = spy(new WifiCallingPreferenceController(mContext, "wifi_calling") { @@ -91,7 +93,6 @@ public class WifiCallingPreferenceControllerTest { }); mController.mCarrierConfigManager = mCarrierConfigManager; mController.init(SUB_ID); - mController.mImsManager = mImsManager; mController.mCallState = TelephonyManager.CALL_STATE_IDLE; doReturn(mQueryImsState).when(mController).queryImsState(anyInt()); mPreference.setKey(mController.getPreferenceKey()); @@ -143,7 +144,6 @@ public class WifiCallingPreferenceControllerTest { mCarrierConfig.putBoolean( CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, true); mController.init(SUB_ID); - mController.mImsManager = mImsManager; when(mImsMmTelManager.getVoWiFiRoamingModeSetting()).thenReturn( ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED); diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java index 7957ae0d9b8..dc3b2b0a714 100644 --- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java @@ -18,13 +18,13 @@ package com.android.settings.wifi.calling; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +import android.content.Context; import android.content.Intent; import android.provider.Settings; import android.telephony.SubscriptionInfo; @@ -32,14 +32,19 @@ import android.view.View; import androidx.fragment.app.FragmentActivity; +import com.android.ims.ImsManager; import com.android.settings.R; import com.android.settings.network.SubscriptionUtil; +import com.android.settings.network.ims.MockWifiCallingQueryImsState; import com.android.settings.widget.RtlCompatibleViewPager; 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.shadows.androidx.fragment.FragmentController; import java.util.ArrayList; @@ -48,12 +53,38 @@ import java.util.Collections; @RunWith(RobolectricTestRunner.class) public class WifiCallingSettingsTest { + private static final int SUB_ID1 = 111; + private static final int SUB_ID2 = 222; + + private Context mContext; + + @Mock + private ImsManager mImsManager; private WifiCallingSettings mFragment; + private MockWifiCallingQueryImsState mQueryImsState1; + private MockWifiCallingQueryImsState mQueryImsState2; + @Before public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = spy(RuntimeEnvironment.application); + + mQueryImsState1 = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID1)); + mQueryImsState2 = spy(new MockWifiCallingQueryImsState(mContext, SUB_ID2)); + doReturn(true).when(mQueryImsState1).isEnabledByUser(); + doReturn(true).when(mQueryImsState2).isEnabledByUser(); + doReturn(mImsManager).when(mQueryImsState1).getImsManager(anyInt()); + doReturn(mImsManager).when(mQueryImsState2).getImsManager(anyInt()); + doReturn(true).when(mImsManager).isWfcEnabledByPlatform(); + mQueryImsState1.setIsProvisionedOnDevice(true); + mQueryImsState2.setIsProvisionedOnDevice(true); + mFragment = spy(new WifiCallingSettings()); + doReturn(mQueryImsState1).when(mFragment).queryImsState(SUB_ID1); + doReturn(mQueryImsState2).when(mFragment).queryImsState(SUB_ID2); } @Test @@ -65,12 +96,12 @@ public class WifiCallingSettingsTest { @Test public void setupFragment_oneSubscription_noCrash() { final SubscriptionInfo info = mock(SubscriptionInfo.class); - when(info.getSubscriptionId()).thenReturn(111); + when(info.getSubscriptionId()).thenReturn(SUB_ID1); SubscriptionUtil.setActiveSubscriptionsForTesting(new ArrayList<>( Collections.singletonList(info))); - doReturn(true).when(mFragment).isWfcEnabledByPlatform(any(SubscriptionInfo.class)); - doReturn(true).when(mFragment).isWfcProvisionedOnDevice(any(SubscriptionInfo.class)); + doReturn(true).when(mImsManager).isWfcEnabledByPlatform(); + mQueryImsState1.setIsProvisionedOnDevice(true); final Intent intent = new Intent(); intent.putExtra(Settings.EXTRA_SUB_ID, info.getSubscriptionId()); @@ -88,13 +119,11 @@ public class WifiCallingSettingsTest { public void setupFragment_twoSubscriptions_correctSelection() { final SubscriptionInfo info1 = mock(SubscriptionInfo.class); final SubscriptionInfo info2 = mock(SubscriptionInfo.class); - when(info1.getSubscriptionId()).thenReturn(111); - when(info2.getSubscriptionId()).thenReturn(222); + when(info1.getSubscriptionId()).thenReturn(SUB_ID1); + when(info2.getSubscriptionId()).thenReturn(SUB_ID2); SubscriptionUtil.setActiveSubscriptionsForTesting(new ArrayList<>( Arrays.asList(info1, info2))); - doReturn(true).when(mFragment).isWfcEnabledByPlatform(any(SubscriptionInfo.class)); - doReturn(true).when(mFragment).isWfcProvisionedOnDevice(any(SubscriptionInfo.class)); final Intent intent = new Intent(); intent.putExtra(Settings.EXTRA_SUB_ID, info2.getSubscriptionId()); @@ -114,14 +143,12 @@ public class WifiCallingSettingsTest { public void setupFragment_twoSubscriptionsOneNotProvisionedOnDevice_oneResult() { final SubscriptionInfo info1 = mock(SubscriptionInfo.class); final SubscriptionInfo info2 = mock(SubscriptionInfo.class); - when(info1.getSubscriptionId()).thenReturn(111); - when(info2.getSubscriptionId()).thenReturn(222); + when(info1.getSubscriptionId()).thenReturn(SUB_ID1); + when(info2.getSubscriptionId()).thenReturn(SUB_ID2); SubscriptionUtil.setActiveSubscriptionsForTesting(new ArrayList<>( Arrays.asList(info1, info2))); - doReturn(true).when(mFragment).isWfcEnabledByPlatform(any(SubscriptionInfo.class)); - doReturn(true).when(mFragment).isWfcProvisionedOnDevice(eq(info1)); - doReturn(false).when(mFragment).isWfcProvisionedOnDevice(eq(info2)); + mQueryImsState2.setIsProvisionedOnDevice(false); final Intent intent = new Intent(); intent.putExtra(Settings.EXTRA_SUB_ID, info1.getSubscriptionId());