From 1716548685e2a14b9d847b8b2f7b3b069164a790 Mon Sep 17 00:00:00 2001 From: Bonian Chen Date: Sun, 9 Feb 2020 23:16:29 +0800 Subject: [PATCH] [Settings] Replace isVolteEnabledByPlatform Replace ImsManager#isVolteEnabledByPlatform() by ImsMmTelManager#isSupport(). Bug: 140542283 Test: m RunSettingsRoboTests -j ROBOTEST_FILTER=Enhanced4gBasePreferenceControllerTest Test: m RunSettingsRoboTests -j ROBOTEST_FILTER=Enhanced4gLteSliceHelperTest Change-Id: I656a00ad2c6120255e53d0b836945462258e01bb --- .../settings/network/ims/BooleanConsumer.java | 58 +++++++++++++++++++ .../network/ims/ImsQueryController.java | 26 +++++++++ .../network/ims/VolteQueryImsState.java | 16 +++-- .../network/ims/MockVolteQueryImsState.java | 15 +++++ ...nhanced4gBasePreferenceControllerTest.java | 8 ++- .../Enhanced4gLteSliceHelperTest.java | 17 +++--- 6 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 src/com/android/settings/network/ims/BooleanConsumer.java diff --git a/src/com/android/settings/network/ims/BooleanConsumer.java b/src/com/android/settings/network/ims/BooleanConsumer.java new file mode 100644 index 00000000000..a5dfe6fc867 --- /dev/null +++ b/src/com/android/settings/network/ims/BooleanConsumer.java @@ -0,0 +1,58 @@ +/* + * 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 java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +class BooleanConsumer extends Semaphore implements Consumer { + + private static final String TAG = "BooleanConsumer"; + + BooleanConsumer() { + super(0); + mValue = new AtomicBoolean(); + } + + private volatile AtomicBoolean mValue; + + /** + * Get boolean value reported from callback + * + * @param timeout callback waiting time in milliseconds + * @return boolean value reported + * @throws InterruptedException when thread get interrupted + */ + boolean get(long timeout) throws InterruptedException { + tryAcquire(timeout, TimeUnit.MILLISECONDS); + return mValue.get(); + } + + /** + * Implementation of {@link Consumer#accept(Boolean)} + * + * @param value boolean reported from {@link Consumer#accept(Boolean)} + */ + public void accept(Boolean value) { + if (value != null) { + mValue.set(value.booleanValue()); + } + release(); + } +} diff --git a/src/com/android/settings/network/ims/ImsQueryController.java b/src/com/android/settings/network/ims/ImsQueryController.java index fec862b383e..8fdad4004fe 100644 --- a/src/com/android/settings/network/ims/ImsQueryController.java +++ b/src/com/android/settings/network/ims/ImsQueryController.java @@ -17,16 +17,24 @@ package com.android.settings.network.ims; import android.telephony.AccessNetworkConstants; +import android.telephony.SubscriptionManager; +import android.telephony.ims.ImsException; +import android.telephony.ims.ImsMmTelManager; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import androidx.annotation.VisibleForTesting; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + /** * Controller class for querying IMS status */ abstract class ImsQueryController { + private static final long TIMEOUT_MILLIS = 2000; + private volatile int mCapability; private volatile int mTech; private volatile int mTransportType; @@ -54,6 +62,24 @@ abstract class ImsQueryController { return (new ImsQueryTtyOnVolteStat(subId)).query(); } + @VisibleForTesting + boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (!SubscriptionManager.isValidSubscriptionId(subId)) { + return false; + } + + final ImsMmTelManager imsMmTelManager = ImsMmTelManager.createForSubscriptionId(subId); + // TODO: have a shared thread pool instead of create ExecutorService + // everytime to improve performance. + final ExecutorService executor = Executors.newSingleThreadExecutor(); + final BooleanConsumer booleanResult = new BooleanConsumer(); + imsMmTelManager.isSupported(mCapability, mTransportType, executor, booleanResult); + // get() will be blocked until end of execution(isSupported()) within thread(executor) + // or timeout after TIMEOUT_MILLIS milliseconds + return booleanResult.get(TIMEOUT_MILLIS); + } + @VisibleForTesting boolean isProvisionedOnDevice(int subId) { return (new ImsQueryProvisioningStat(subId, mCapability, mTech)).query(); diff --git a/src/com/android/settings/network/ims/VolteQueryImsState.java b/src/com/android/settings/network/ims/VolteQueryImsState.java index 23f8bab081b..22fb529ef80 100644 --- a/src/com/android/settings/network/ims/VolteQueryImsState.java +++ b/src/com/android/settings/network/ims/VolteQueryImsState.java @@ -20,8 +20,10 @@ import android.content.Context; import android.telecom.TelecomManager; import android.telephony.AccessNetworkConstants; import android.telephony.SubscriptionManager; +import android.telephony.ims.ImsException; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; +import android.util.Log; import androidx.annotation.VisibleForTesting; @@ -34,6 +36,8 @@ import com.android.settings.network.telephony.MobileNetworkUtils; */ public class VolteQueryImsState extends ImsQueryController { + private static final String LOG_TAG = "VolteQueryImsState"; + private Context mContext; private int mSubId; @@ -71,13 +75,15 @@ public class VolteQueryImsState extends ImsQueryController { * @return true when VoLTE has been enabled, otherwise false */ public boolean isVoLteProvisioned() { - final ImsManager imsManager = getImsManager(mSubId); - if (imsManager == null) { + if (!isProvisionedOnDevice(mSubId)) { return false; } - - return imsManager.isVolteEnabledByPlatform() - && isProvisionedOnDevice(mSubId); + try { + return isEnabledByPlatform(mSubId); + } catch (InterruptedException | IllegalArgumentException | ImsException exception) { + Log.w(LOG_TAG, "fail to get VoLte supporting status. subId=" + mSubId, exception); + } + return false; } /** diff --git a/tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java index 84399a2db48..97d76ca7beb 100644 --- a/tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java +++ b/tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java @@ -17,6 +17,7 @@ package com.android.settings.network.ims; import android.content.Context; +import android.telephony.ims.ImsException; import com.android.ims.ImsManager; @@ -28,6 +29,7 @@ import com.android.ims.ImsManager; public class MockVolteQueryImsState extends VolteQueryImsState { private Boolean mIsTtyOnVolteEnabled; + private Boolean mIsSupported; private Boolean mIsProvisionedOnDevice; private Boolean mIsEnabledByUser; @@ -57,6 +59,19 @@ public class MockVolteQueryImsState extends VolteQueryImsState { return super.isTtyOnVolteEnabled(subId); } + public void setEnabledByPlatform(boolean isSupported) { + mIsSupported = isSupported; + } + + @Override + boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (mIsSupported != null) { + return mIsSupported; + } + return super.isEnabledByPlatform(subId); + } + public void setIsProvisionedOnDevice(boolean isProvisioned) { mIsProvisionedOnDevice = isProvisioned; } diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java index d7db984c67e..ba71a7952fe 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java @@ -87,7 +87,9 @@ public class Enhanced4gBasePreferenceControllerTest { mQueryImsState = spy(new MockVolteQueryImsState(mContext, SUB_ID)); doReturn(mImsManager).when(mQueryImsState).getImsManager(anyInt()); + mQueryImsState.setEnabledByPlatform(true); mQueryImsState.setIsProvisionedOnDevice(true); + mQueryImsState.setIsEnabledByUser(true); mPreference = new RestrictedSwitchPreference(mContext); mController = spy(new Enhanced4gLtePreferenceController(mContext, "VoLTE")); @@ -106,7 +108,7 @@ public class Enhanced4gBasePreferenceControllerTest { @Test public void getAvailabilityStatus_volteDisabled_returnUnavailable() { - doReturn(false).when(mImsManager).isVolteEnabledByPlatform(); + mQueryImsState.setEnabledByPlatform(false); doReturn(true).when(mProvisioningManager).getProvisioningStatusForCapability( MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, ImsRegistrationImplBase.REGISTRATION_TECH_LTE); @@ -117,7 +119,7 @@ public class Enhanced4gBasePreferenceControllerTest { @Test public void updateState_configEnabled_prefEnabled() { - doReturn(true).when(mQueryImsState).isEnabledByUser(); + mQueryImsState.setIsEnabledByUser(true); mPreference.setEnabled(false); mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1); mController.mCallState = TelephonyManager.CALL_STATE_IDLE; @@ -131,7 +133,7 @@ public class Enhanced4gBasePreferenceControllerTest { @Test public void updateState_configOn_prefChecked() { - doReturn(true).when(mQueryImsState).isEnabledByUser(); + mQueryImsState.setIsEnabledByUser(true); mPreference.setChecked(false); doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser(); doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled(); diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelperTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelperTest.java index a89a7aac1c1..944d8e623b2 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelperTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLteSliceHelperTest.java @@ -110,7 +110,9 @@ public class Enhanced4gLteSliceHelperTest { mQueryImsState = spy(new MockVolteQueryImsState(mContext, SUB_ID)); doReturn(mMockImsManager).when(mQueryImsState).getImsManager(anyInt()); + mQueryImsState.setEnabledByPlatform(true); mQueryImsState.setIsProvisionedOnDevice(true); + mQueryImsState.setIsEnabledByUser(true); mEnhanced4gLteSliceHelper = spy(new FakeEnhanced4gLteSliceHelper(mContext)); doReturn(mQueryImsState).when(mEnhanced4gLteSliceHelper).queryImsState(anyInt()); @@ -121,6 +123,9 @@ public class Enhanced4gLteSliceHelperTest { @Test public void test_CreateEnhanced4gLteSlice_invalidSubId() { + mQueryImsState.setEnabledByPlatform(false); + mQueryImsState.setIsProvisionedOnDevice(false); + mQueryImsState.setIsEnabledByUser(false); mShadowSubscriptionManager.setDefaultVoiceSubscriptionId(-1); final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice( @@ -131,7 +136,7 @@ public class Enhanced4gLteSliceHelperTest { @Test public void test_CreateEnhanced4gLteSlice_enhanced4gLteNotSupported() { - when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(false); + mQueryImsState.setEnabledByPlatform(false); final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice( CustomSliceRegistry.ENHANCED_4G_SLICE_URI); @@ -142,9 +147,8 @@ public class Enhanced4gLteSliceHelperTest { @Test public void test_CreateEnhanced4gLteSlice_success() { - when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(true); + mQueryImsState.setEnabledByPlatform(true); mQueryImsState.setIsProvisionedOnDevice(true); - doReturn(true).when(mQueryImsState).isEnabledByUser(); when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true); when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null); @@ -157,9 +161,8 @@ public class Enhanced4gLteSliceHelperTest { @Test public void test_SettingSliceProvider_getsRightSliceEnhanced4gLte() { - when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(true); + mQueryImsState.setEnabledByPlatform(true); mQueryImsState.setIsProvisionedOnDevice(true); - doReturn(true).when(mQueryImsState).isEnabledByUser(); when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true); when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null); when(mSlicesFeatureProvider.getNewEnhanced4gLteSliceHelper(mContext)) @@ -174,9 +177,9 @@ public class Enhanced4gLteSliceHelperTest { @Test @Ignore public void test_SliceBroadcastReceiver_toggleOffEnhanced4gLte() { - when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(true); + mQueryImsState.setEnabledByPlatform(true); mQueryImsState.setIsProvisionedOnDevice(true); - doReturn(false).when(mQueryImsState).isEnabledByUser(); + mQueryImsState.setIsEnabledByUser(false); when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true); when(mSlicesFeatureProvider.getNewEnhanced4gLteSliceHelper(mContext)) .thenReturn(mEnhanced4gLteSliceHelper);