aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2018-06-08 11:07:40 -0700
committerXin Li <delphij@google.com>2018-06-08 11:07:40 -0700
commit2f9b484f9e7393ec87d56ed1b08dd176ea8110db (patch)
tree85e7015e236862b3747058678d1b781c0b038e95
parent61e71d322bb831d8841c3c3822e2cf7f60f4f2ab (diff)
parente21cb833095cf25031a633cf338dd3222b4f8762 (diff)
downloadims-2f9b484f9e7393ec87d56ed1b08dd176ea8110db.tar.gz
Merge pi-dev-plus-aosp-without-vendor into stage-aosp-master
Bug: 79597307 Change-Id: Idddad9f3c510d51ea4a77c0a439ac00846af7cb9
-rw-r--r--src/java/com/android/ims/ImsConnectionStateListener.java2
-rw-r--r--src/java/com/android/ims/ImsManager.java93
-rw-r--r--src/java/com/android/ims/MmTelFeatureConnection.java111
-rw-r--r--tests/Android.mk4
-rw-r--r--tests/src/com/android/ims/ImsConfigTest.java6
5 files changed, 122 insertions, 94 deletions
diff --git a/src/java/com/android/ims/ImsConnectionStateListener.java b/src/java/com/android/ims/ImsConnectionStateListener.java
index d5fb633c..8ac473a5 100644
--- a/src/java/com/android/ims/ImsConnectionStateListener.java
+++ b/src/java/com/android/ims/ImsConnectionStateListener.java
@@ -102,7 +102,7 @@ public class ImsConnectionStateListener extends ImsRegistrationImplBase.Callback
}
if (c.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO)) {
enabledCapabilities[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI] =
- ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI;
+ ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI;
}
if (c.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT)) {
enabledCapabilities[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI] =
diff --git a/src/java/com/android/ims/ImsManager.java b/src/java/com/android/ims/ImsManager.java
index 52d523b9..31dd86f4 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -368,18 +368,16 @@ public class ImsManager {
private int mPhoneId;
private final boolean mConfigDynamicBind;
private @Nullable MmTelFeatureConnection mMmTelFeatureConnection = null;
- private ImsServiceDeathRecipient mDeathRecipient = new ImsServiceDeathRecipient();
- // Ut interface for the supplementary service configuration
- private ImsUt mUt = null;
- // Interface to get/set ims config items
- private ImsConfig mConfig = null;
private boolean mConfigUpdated = false;
private ImsConfigListener mImsConfigListener;
+ //TODO: Move these caches into the MmTelFeature Connection and restrict their lifetimes to the
+ // lifetime of the MmTelFeature.
+ // Ut interface for the supplementary service configuration
+ private ImsUt mUt = null;
// ECBM interface
private ImsEcbm mEcbm = null;
-
private ImsMultiEndpoint mMultiEndpoint = null;
private Set<MmTelFeatureConnection.IFeatureUpdate> mStatusCallbacks =
@@ -436,9 +434,12 @@ public class ImsManager {
/**
* Returns the user configuration of Enhanced 4G LTE Mode setting for slot. If the option is
- * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false),
- * this method will return default value specified by
+ * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), or
+ * the setting is not initialized, this method will return default value specified by
* {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
+ *
+ * Note that even if the setting was set, it may no longer be editable. If this is the case we
+ * return the default value.
*/
public boolean isEnhanced4gLteModeSettingEnabledByUser() {
int setting = SubscriptionManager.getIntegerSubscriptionProperty(
@@ -737,7 +738,8 @@ public class ImsManager {
SUB_PROPERTY_NOT_INITIALIZED, mContext);
// If it's never set, by default we return true.
- return (setting == SUB_PROPERTY_NOT_INITIALIZED || setting == 1);
+ return (setting == SUB_PROPERTY_NOT_INITIALIZED
+ || setting == ImsConfig.FeatureValueConstants.ON);
}
/**
@@ -774,7 +776,7 @@ public class ImsManager {
log("setVtSetting(b) : imsServiceAllowTurnOff -> turnOffIms");
turnOffIms();
}
- } catch (ImsException | RemoteException e) {
+ } catch (ImsException e) {
// The ImsService is down. Since the SubscriptionManager already recorded the user's
// preference, it will be resent in updateImsServiceConfig when the ImsPhoneCallTracker
// reconnects.
@@ -847,7 +849,7 @@ public class ImsManager {
return getBooleanCarrierConfig(
CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
} else {
- return setting == 1;
+ return setting == ImsConfig.FeatureValueConstants.ON;
}
}
@@ -902,7 +904,7 @@ public class ImsManager {
}
setWfcModeInternal(imsWfcModeFeatureValue);
- } catch (ImsException | RemoteException e) {
+ } catch (ImsException e) {
loge("setWfcSetting(): ", e);
}
}
@@ -1112,7 +1114,7 @@ public class ImsManager {
return getBooleanCarrierConfig(
CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
} else {
- return (setting == 1);
+ return setting == ImsConfig.FeatureValueConstants.ON;
}
}
@@ -1301,7 +1303,7 @@ public class ImsManager {
}
mConfigUpdated = true;
- } catch (ImsException | RemoteException e) {
+ } catch (ImsException e) {
loge("updateImsServiceConfig: ", e);
mConfigUpdated = false;
}
@@ -1313,7 +1315,7 @@ public class ImsManager {
* @return whether feature is On
* @throws ImsException
*/
- private boolean updateVolteFeatureValue() throws RemoteException {
+ private boolean updateVolteFeatureValue() throws ImsException {
boolean available = isVolteEnabledByPlatform();
boolean enabled = isEnhanced4gLteModeSettingEnabledByUser();
boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
@@ -1334,7 +1336,7 @@ public class ImsManager {
* @return whether feature is On
* @throws ImsException
*/
- private boolean updateVideoCallFeatureValue() throws RemoteException {
+ private boolean updateVideoCallFeatureValue() throws ImsException {
boolean available = isVtEnabledByPlatform();
boolean enabled = isVtEnabledByUser();
boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
@@ -1361,7 +1363,7 @@ public class ImsManager {
* @return whether feature is On
* @throws ImsException
*/
- private boolean updateWfcFeatureAndProvisionedValues() throws RemoteException {
+ private boolean updateWfcFeatureAndProvisionedValues() throws ImsException {
TelephonyManager tm = new TelephonyManager(mContext, getSubId());
boolean isNetworkRoaming = tm.isNetworkRoaming();
boolean available = isWfcEnabledByPlatform();
@@ -1652,7 +1654,6 @@ public class ImsManager {
mMmTelFeatureConnection.closeConnection();
}
mUt = null;
- mConfig = null;
mEcbm = null;
mMultiEndpoint = null;
}
@@ -1801,41 +1802,44 @@ public class ImsManager {
* @throws ImsException if getting the setting interface results in an error.
*/
public ImsConfig getConfigInterface() throws ImsException {
- if (mConfig != null && mConfig.isBinderAlive()) {
- return mConfig;
- }
-
checkAndThrowExceptionIfServiceUnavailable();
+
try {
IImsConfig config = mMmTelFeatureConnection.getConfigInterface();
if (config == null) {
throw new ImsException("getConfigInterface()",
ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
}
- mConfig = new ImsConfig(config, mContext);
+ return new ImsConfig(config);
} catch (RemoteException e) {
throw new ImsException("getConfigInterface()", e,
ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
}
- return mConfig;
}
public void changeMmTelCapability(
@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech,
- boolean isEnabled) throws RemoteException {
+ boolean isEnabled) throws ImsException {
+ checkAndThrowExceptionIfServiceUnavailable();
+
CapabilityChangeRequest request = new CapabilityChangeRequest();
if (isEnabled) {
request.addCapabilitiesToEnableForTech(capability, radioTech);
} else {
request.addCapabilitiesToDisableForTech(capability, radioTech);
}
- mMmTelFeatureConnection.changeEnabledCapabilities(request, null);
- if (mImsConfigListener != null) {
- mImsConfigListener.onSetFeatureResponse(capability,
- mMmTelFeatureConnection.getRegistrationTech(),
- isEnabled ? ImsConfig.FeatureValueConstants.ON
- : ImsConfig.FeatureValueConstants.OFF, -1);
+ try {
+ mMmTelFeatureConnection.changeEnabledCapabilities(request, null);
+ if (mImsConfigListener != null) {
+ mImsConfigListener.onSetFeatureResponse(capability,
+ mMmTelFeatureConnection.getRegistrationTech(),
+ isEnabled ? ImsConfig.FeatureValueConstants.ON
+ : ImsConfig.FeatureValueConstants.OFF, -1);
+ }
+ } catch (RemoteException e) {
+ throw new ImsException("changeMmTelCapability()", e,
+ ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
}
}
@@ -1875,6 +1879,15 @@ public class ImsManager {
/**
* Sets the UI TTY mode. This is the preferred TTY mode that the user sets in the call
* settings screen.
+ * @param uiTtyMode TTY Mode, valid options are:
+ * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
+ * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
+ * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
+ * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
+ * @param onComplete A Message that will be called by the ImsService when it has completed this
+ * operation or null if not waiting for an async response. The Message must contain a
+ * valid {@link Message#replyTo} {@link android.os.Messenger}, since it will be passed
+ * through Binder to another process.
*/
public void setUiTTYMode(Context context, int uiTtyMode, Message onComplete)
throws ImsException {
@@ -2141,20 +2154,6 @@ public class ImsManager {
}
/**
- * Death recipient class for monitoring IMS service.
- */
- private class ImsServiceDeathRecipient implements IBinder.DeathRecipient {
- @Override
- public void binderDied() {
- mMmTelFeatureConnection = null;
- mUt = null;
- mConfig = null;
- mEcbm = null;
- mMultiEndpoint = null;
- }
- }
-
- /**
* Gets the ECBM interface to request ECBM exit.
*
* @return the ECBM interface instance
@@ -2309,7 +2308,9 @@ public class ImsManager {
public void factoryReset() {
// Set VoLTE to default
SubscriptionManager.setSubscriptionProperty(getSubId(),
- SubscriptionManager.ENHANCED_4G_MODE_ENABLED, booleanToPropertyString(true));
+ SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
+ booleanToPropertyString(getBooleanCarrierConfig(
+ CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL)));
// Set VoWiFi to default
SubscriptionManager.setSubscriptionProperty(getSubId(),
diff --git a/src/java/com/android/ims/MmTelFeatureConnection.java b/src/java/com/android/ims/MmTelFeatureConnection.java
index b2472c8a..d6954f3f 100644
--- a/src/java/com/android/ims/MmTelFeatureConnection.java
+++ b/src/java/com/android/ims/MmTelFeatureConnection.java
@@ -44,8 +44,10 @@ import com.android.ims.internal.IImsMultiEndpoint;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.ims.internal.IImsUt;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
* A container of the IImsServiceController binder, which implements all of the ImsFeatures that
@@ -73,35 +75,41 @@ public class MmTelFeatureConnection {
private IImsRegistration mRegistrationBinder;
private IImsConfig mConfigBinder;
+ private IBinder.DeathRecipient mDeathRecipient = () -> {
+ Log.w(TAG, "DeathRecipient triggered, binder died.");
+ onRemovedOrDied();
+ };
+
private abstract class CallbackAdapterManager<T> {
private static final String TAG = "CallbackAdapterManager";
- protected final Set<T> mLocalCallbacks = new HashSet<>();
+ protected final Set<T> mLocalCallbacks =
+ Collections.newSetFromMap(new ConcurrentHashMap<>());
private boolean mHasConnected = false;
public void addCallback(T localCallback) throws RemoteException {
// We only one one binding to the ImsService per process.
// Store any more locally.
synchronized (mLock) {
- if(!mHasConnected) {
+ if (!mHasConnected) {
// throws a RemoteException if a connection can not be established.
- if(createConnection()) {
+ if (createConnection()) {
mHasConnected = true;
} else {
throw new RemoteException("Can not create connection!");
}
}
- Log.i(TAG, "Local callback added: " + localCallback);
- mLocalCallbacks.add(localCallback);
}
+ Log.i(TAG, "Local callback added: " + localCallback);
+ mLocalCallbacks.add(localCallback);
}
public void removeCallback(T localCallback) {
// We only maintain one binding to the ImsService per process.
+ Log.i(TAG, "Local callback removed: " + localCallback);
+ mLocalCallbacks.remove(localCallback);
synchronized (mLock) {
- Log.i(TAG, "Local callback removed: " + localCallback);
- mLocalCallbacks.remove(localCallback);
- // If we have removed all local callbacks, remove callback to ImsService.
+ // If we have removed all local callbacks, remove callback to ImsService.
if(mHasConnected) {
if (mLocalCallbacks.isEmpty()) {
removeConnection();
@@ -118,9 +126,9 @@ public class MmTelFeatureConnection {
// Still mark the connection as disconnected, even if this fails.
mHasConnected = false;
}
- Log.i(TAG, "Closing connection and clearing callbacks");
- mLocalCallbacks.clear();
}
+ Log.i(TAG, "Closing connection and clearing callbacks");
+ mLocalCallbacks.clear();
}
abstract boolean createConnection() throws RemoteException;
@@ -140,27 +148,21 @@ public class MmTelFeatureConnection {
public void onRegistered(int imsRadioTech) {
Log.i(TAG, "onRegistered ::");
- synchronized (mLock) {
- mLocalCallbacks.forEach(l -> l.onRegistered(imsRadioTech));
- }
+ mLocalCallbacks.forEach(l -> l.onRegistered(imsRadioTech));
}
@Override
public void onRegistering(int imsRadioTech) {
Log.i(TAG, "onRegistering ::");
- synchronized (mLock) {
- mLocalCallbacks.forEach(l -> l.onRegistering(imsRadioTech));
- }
+ mLocalCallbacks.forEach(l -> l.onRegistering(imsRadioTech));
}
@Override
public void onDeregistered(ImsReasonInfo imsReasonInfo) {
Log.i(TAG, "onDeregistered ::");
- synchronized (mLock) {
- mLocalCallbacks.forEach(l -> l.onDeregistered(imsReasonInfo));
- }
+ mLocalCallbacks.forEach(l -> l.onDeregistered(imsReasonInfo));
}
@Override
@@ -168,18 +170,15 @@ public class MmTelFeatureConnection {
Log.i(TAG, "onTechnologyChangeFailed :: targetAccessTech=" + targetRadioTech +
", imsReasonInfo=" + imsReasonInfo);
- synchronized (mLock) {
mLocalCallbacks.forEach(l -> l.onTechnologyChangeFailed(targetRadioTech,
imsReasonInfo));
- }
}
@Override
public void onSubscriberAssociatedUriChanged(Uri[] uris) {
Log.i(TAG, "onSubscriberAssociatedUriChanged");
- synchronized (mLock) {
- mLocalCallbacks.forEach(l -> l.onSubscriberAssociatedUriChanged(uris));
- }
+
+ mLocalCallbacks.forEach(l -> l.onSubscriberAssociatedUriChanged(uris));
}
}
@@ -220,16 +219,18 @@ public class MmTelFeatureConnection {
// Called when the Capabilities Status on this connection have changed.
@Override
public void onCapabilitiesStatusChanged(ImsFeature.Capabilities config) {
- synchronized (mLock) {
- mLocalCallbacks.forEach(
- callback -> callback.onCapabilitiesStatusChanged(config));
- }
+ mLocalCallbacks.forEach(
+ callback -> callback.onCapabilitiesStatusChanged(config));
}
}
@Override
boolean createConnection() throws RemoteException {
- IImsMmTelFeature binder = getServiceInterface(mBinder);
+ IImsMmTelFeature binder;
+ synchronized (mLock) {
+ checkServiceIsReady();
+ binder = getServiceInterface(mBinder);
+ }
if (binder != null) {
binder.addCapabilityCallback(mCallbackAdapter);
return true;
@@ -241,7 +242,15 @@ public class MmTelFeatureConnection {
@Override
void removeConnection() {
- IImsMmTelFeature binder = getServiceInterface(mBinder);
+ IImsMmTelFeature binder = null;
+ synchronized (mLock) {
+ try {
+ checkServiceIsReady();
+ binder = getServiceInterface(mBinder);
+ } catch (RemoteException e) {
+ // binder is null
+ }
+ }
if (binder != null) {
try {
binder.removeCapabilityCallback(mCallbackAdapter);
@@ -333,14 +342,8 @@ public class MmTelFeatureConnection {
}
switch (feature) {
case ImsFeature.FEATURE_MMTEL: {
- if (mIsAvailable) {
- Log.i(TAG, "MmTel disabled on slotId: " + slotId);
- mIsAvailable = false;
- mmTelFeatureRemoved();
- if (mStatusCallback != null) {
- mStatusCallback.notifyUnavailable();
- }
- }
+ Log.i(TAG, "MmTel removed on slotId: " + slotId);
+ onRemovedOrDied();
break;
}
case ImsFeature.FEATURE_EMERGENCY_MMTEL : {
@@ -372,12 +375,23 @@ public class MmTelFeatureConnection {
mContext = context;
}
- // Called when the MmTelFeatureConnection has received an unavailable notification.
- private void mmTelFeatureRemoved() {
+ /**
+ * Called when the MmTelFeature has either been removed by Telephony or crashed.
+ */
+ private void onRemovedOrDied() {
synchronized (mLock) {
- // invalidate caches.
- mRegistrationBinder = null;
- mConfigBinder = null;
+ if (mIsAvailable) {
+ mIsAvailable = false;
+ // invalidate caches.
+ mRegistrationBinder = null;
+ mConfigBinder = null;
+ if (mBinder != null) {
+ mBinder.unlinkToDeath(mDeathRecipient, 0);
+ }
+ if (mStatusCallback != null) {
+ mStatusCallback.notifyUnavailable();
+ }
+ }
}
}
@@ -430,7 +444,16 @@ public class MmTelFeatureConnection {
}
public void setBinder(IBinder binder) {
- mBinder = binder;
+ synchronized (mLock) {
+ mBinder = binder;
+ try {
+ if (mBinder != null) {
+ mBinder.linkToDeath(mDeathRecipient, 0);
+ }
+ } catch (RemoteException e) {
+ // No need to do anything if the binder is already dead.
+ }
+ }
}
/**
diff --git a/tests/Android.mk b/tests/Android.mk
index e07cab5c..a0b998b8 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -25,7 +25,9 @@ LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := tests
-LOCAL_JAVA_LIBRARIES := ims-common android.test.runner
+LOCAL_JAVA_LIBRARIES := ims-common \
+ android.test.runner \
+ android.test.base
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-test \
diff --git a/tests/src/com/android/ims/ImsConfigTest.java b/tests/src/com/android/ims/ImsConfigTest.java
index 4cf7a926..31d9bcb0 100644
--- a/tests/src/com/android/ims/ImsConfigTest.java
+++ b/tests/src/com/android/ims/ImsConfigTest.java
@@ -18,6 +18,7 @@ package com.android.ims;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.aidl.IImsConfig;
+import android.test.suitebuilder.annotation.SmallTest;
import org.junit.After;
import org.junit.Before;
@@ -42,7 +43,7 @@ public class ImsConfigTest extends ImsTestBase {
@Override
public void setUp() throws Exception {
super.setUp();
- mTestImsConfig = new ImsConfig(mMockImsConfigInterface, mContext);
+ mTestImsConfig = new ImsConfig(mMockImsConfigInterface);
}
@After
@@ -53,10 +54,11 @@ public class ImsConfigTest extends ImsTestBase {
}
@Test
+ @SmallTest
public void testImsConfigGetProvisionedValue() throws Exception {
int testItem = 0;
- mTestImsConfig.getProvisionedValue(testItem);
+ mTestImsConfig.getConfigInt(testItem);
verify(mMockImsConfigInterface).getConfigInt(eq(testItem));
}