From 74f45a446c333951b783f8d0924a93fbf41ded75 Mon Sep 17 00:00:00 2001 From: Bonian Chen Date: Mon, 10 Feb 2020 01:52:14 +0800 Subject: [PATCH] [Settings] Replace ImsManager#getImsServiceState() Replacing ImsManager#getImsServiceState() into ImsMmTelManager#getFeatureState(). Bug: 140542283 Test: m RunSettingsRoboTests -j ROBOTEST_FILTER=VideoCallingPreferenceControllerTest Change-Id: Id0832bf523409ae9d02ee49d809f62701e33b15e --- .../network/ims/ImsQueryController.java | 17 ++++++ .../settings/network/ims/IntegerConsumer.java | 58 +++++++++++++++++++ .../settings/network/ims/VtQueryImsState.java | 22 +++++-- .../network/ims/MockVtQueryImsState.java | 15 +++++ .../VideoCallingPreferenceControllerTest.java | 3 +- 5 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 src/com/android/settings/network/ims/IntegerConsumer.java diff --git a/src/com/android/settings/network/ims/ImsQueryController.java b/src/com/android/settings/network/ims/ImsQueryController.java index 8fdad4004fe..068a80537b9 100644 --- a/src/com/android/settings/network/ims/ImsQueryController.java +++ b/src/com/android/settings/network/ims/ImsQueryController.java @@ -20,6 +20,7 @@ import android.telephony.AccessNetworkConstants; import android.telephony.SubscriptionManager; import android.telephony.ims.ImsException; import android.telephony.ims.ImsMmTelManager; +import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; @@ -84,4 +85,20 @@ abstract class ImsQueryController { boolean isProvisionedOnDevice(int subId) { return (new ImsQueryProvisioningStat(subId, mCapability, mTech)).query(); } + + @VisibleForTesting + boolean isServiceStateReady(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 IntegerConsumer intResult = new IntegerConsumer(); + imsMmTelManager.getFeatureState(executor, intResult); + return (intResult.get(TIMEOUT_MILLIS) == ImsFeature.STATE_READY); + } } diff --git a/src/com/android/settings/network/ims/IntegerConsumer.java b/src/com/android/settings/network/ims/IntegerConsumer.java new file mode 100644 index 00000000000..02c82275a86 --- /dev/null +++ b/src/com/android/settings/network/ims/IntegerConsumer.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.AtomicInteger; +import java.util.function.Consumer; + +class IntegerConsumer extends Semaphore implements Consumer { + + private static final String TAG = "IntegerConsumer"; + + IntegerConsumer() { + super(0); + mValue = new AtomicInteger(); + } + + private volatile AtomicInteger mValue; + + /** + * Get boolean value reported from callback + * + * @param timeout callback waiting time in milliseconds + * @return int value reported + * @throws InterruptedException when thread get interrupted + */ + int get(long timeout) throws InterruptedException { + tryAcquire(timeout, TimeUnit.MILLISECONDS); + return mValue.get(); + } + + /** + * Implementation of {@link Consumer#accept(Integer)} + * + * @param value int reported from {@link Consumer#accept(Integer)} + */ + public void accept(Integer value) { + if (value != null) { + mValue.set(value.intValue()); + } + release(); + } +} diff --git a/src/com/android/settings/network/ims/VtQueryImsState.java b/src/com/android/settings/network/ims/VtQueryImsState.java index 60bd72988e3..c0776036bf1 100644 --- a/src/com/android/settings/network/ims/VtQueryImsState.java +++ b/src/com/android/settings/network/ims/VtQueryImsState.java @@ -20,20 +20,23 @@ 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; import com.android.ims.ImsManager; import com.android.settings.network.SubscriptionUtil; -import com.android.settings.network.telephony.MobileNetworkUtils; /** * Controller class for querying VT status */ public class VtQueryImsState extends ImsQueryController { + private static final String LOG_TAG = "VtQueryImsState"; + private Context mContext; private int mSubId; @@ -71,14 +74,25 @@ public class VtQueryImsState extends ImsQueryController { * @return true when Video Call can be performed, otherwise false */ public boolean isReadyToVideoCall() { + if (!isProvisionedOnDevice(mSubId)) { + return false; + } + final ImsManager imsManager = getImsManager(mSubId); if (imsManager == null) { return false; } - return imsManager.isVtEnabledByPlatform() - && isProvisionedOnDevice(mSubId) - && MobileNetworkUtils.isImsServiceStateReady(imsManager); + if (!imsManager.isVtEnabledByPlatform()) { + return false; + } + + try { + return isServiceStateReady(mSubId); + } catch (InterruptedException | IllegalArgumentException | ImsException exception) { + Log.w(LOG_TAG, "fail to get Vt service status. subId=" + mSubId, exception); + } + return false; } /** diff --git a/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java index 4fd7d0c6dfb..3daf6cb0f1e 100644 --- a/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java +++ b/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.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; @@ -29,6 +30,7 @@ public class MockVtQueryImsState extends VtQueryImsState { private Boolean mIsTtyOnVolteEnabled; private Boolean mIsProvisionedOnDevice; private Boolean mIsEnabledByUser; + private Boolean mIsServiceStateReady; /** * Constructor @@ -68,6 +70,19 @@ public class MockVtQueryImsState extends VtQueryImsState { return super.isProvisionedOnDevice(subId); } + public void setServiceStateReady(boolean isReady) { + mIsServiceStateReady = isReady; + } + + @Override + boolean isServiceStateReady(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (mIsServiceStateReady != null) { + return mIsServiceStateReady; + } + return super.isServiceStateReady(subId); + } + public void setIsEnabledByUser(boolean enabled) { mIsEnabledByUser = enabled; } diff --git a/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java index c766289c2b6..04fc4b94889 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java @@ -27,7 +27,6 @@ import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.TelephonyManager; import android.telephony.ims.ProvisioningManager; -import android.telephony.ims.feature.ImsFeature; import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; @@ -98,7 +97,7 @@ public class VideoCallingPreferenceControllerTest { doReturn(true).when(mImsManager).isVtEnabledByPlatform(); mQueryImsState.setIsProvisionedOnDevice(true); - doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceState(); + mQueryImsState.setServiceStateReady(true); doReturn(true).when(mTelephonyManager).isDataEnabled(); mController.mCallState = TelephonyManager.CALL_STATE_IDLE;