Loading src/com/android/settings/network/ims/BooleanConsumer.java 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * 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<Boolean> { 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(); } } src/com/android/settings/network/ims/ImsQueryController.java +26 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading src/com/android/settings/network/ims/VolteQueryImsState.java +11 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } /** Loading tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java +15 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settings.network.ims; import android.content.Context; import android.telephony.ims.ImsException; import com.android.ims.ImsManager; Loading @@ -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; Loading Loading @@ -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; } Loading tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java +5 −3 Original line number Diff line number Diff line Loading @@ -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")); Loading @@ -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); Loading @@ -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; Loading @@ -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(); Loading Loading
src/com/android/settings/network/ims/BooleanConsumer.java 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * 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<Boolean> { 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(); } }
src/com/android/settings/network/ims/ImsQueryController.java +26 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading
src/com/android/settings/network/ims/VolteQueryImsState.java +11 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } /** Loading
tests/robotests/src/com/android/settings/network/ims/MockVolteQueryImsState.java +15 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settings.network.ims; import android.content.Context; import android.telephony.ims.ImsException; import com.android.ims.ImsManager; Loading @@ -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; Loading Loading @@ -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; } Loading
tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java +5 −3 Original line number Diff line number Diff line Loading @@ -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")); Loading @@ -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); Loading @@ -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; Loading @@ -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(); Loading