Loading src/java/com/android/ims/ImsConnectionStateListener.java +1 −1 Original line number Diff line number Diff line Loading @@ -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] = Loading src/java/com/android/ims/ImsManager.java +47 −46 Original line number Diff line number Diff line Loading @@ -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 = Loading Loading @@ -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( Loading Loading @@ -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); } /** Loading Loading @@ -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. Loading Loading @@ -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; } } Loading Loading @@ -902,7 +904,7 @@ public class ImsManager { } setWfcModeInternal(imsWfcModeFeatureValue); } catch (ImsException | RemoteException e) { } catch (ImsException e) { loge("setWfcSetting(): ", e); } } Loading Loading @@ -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; } } Loading Loading @@ -1301,7 +1303,7 @@ public class ImsManager { } mConfigUpdated = true; } catch (ImsException | RemoteException e) { } catch (ImsException e) { loge("updateImsServiceConfig: ", e); mConfigUpdated = false; } Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -1652,7 +1654,6 @@ public class ImsManager { mMmTelFeatureConnection.closeConnection(); } mUt = null; mConfig = null; mEcbm = null; mMultiEndpoint = null; } Loading Loading @@ -1801,35 +1802,34 @@ 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); } try { mMmTelFeatureConnection.changeEnabledCapabilities(request, null); if (mImsConfigListener != null) { mImsConfigListener.onSetFeatureResponse(capability, Loading @@ -1837,6 +1837,10 @@ public class ImsManager { isEnabled ? ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF, -1); } } catch (RemoteException e) { throw new ImsException("changeMmTelCapability()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); } } public void setRttEnabled(boolean enabled) { Loading Loading @@ -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 { Loading Loading @@ -2140,20 +2153,6 @@ public class ImsManager { mRecentDisconnectReasons.addLast(reason); } /** * 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. * Loading Loading @@ -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(), Loading src/java/com/android/ims/MmTelFeatureConnection.java +67 −44 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -73,10 +75,16 @@ 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 { Loading @@ -91,16 +99,16 @@ public class MmTelFeatureConnection { throw new RemoteException("Can not create connection!"); } } } 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. synchronized (mLock) { Log.i(TAG, "Local callback removed: " + localCallback); mLocalCallbacks.remove(localCallback); synchronized (mLock) { // If we have removed all local callbacks, remove callback to ImsService. if(mHasConnected) { if (mLocalCallbacks.isEmpty()) { Loading @@ -118,10 +126,10 @@ 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(); } } abstract boolean createConnection() throws RemoteException; Loading @@ -140,48 +148,39 @@ public class MmTelFeatureConnection { public void onRegistered(int imsRadioTech) { Log.i(TAG, "onRegistered ::"); synchronized (mLock) { mLocalCallbacks.forEach(l -> l.onRegistered(imsRadioTech)); } } @Override public void onRegistering(int imsRadioTech) { Log.i(TAG, "onRegistering ::"); synchronized (mLock) { mLocalCallbacks.forEach(l -> l.onRegistering(imsRadioTech)); } } @Override public void onDeregistered(ImsReasonInfo imsReasonInfo) { Log.i(TAG, "onDeregistered ::"); synchronized (mLock) { mLocalCallbacks.forEach(l -> l.onDeregistered(imsReasonInfo)); } } @Override public void onTechnologyChangeFailed(int targetRadioTech, ImsReasonInfo imsReasonInfo) { 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)); } } } @Override boolean createConnection() throws RemoteException { Loading Loading @@ -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)); } } } @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; Loading @@ -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); Loading Loading @@ -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 : { Loading Loading @@ -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) { if (mIsAvailable) { mIsAvailable = false; // invalidate caches. mRegistrationBinder = null; mConfigBinder = null; if (mBinder != null) { mBinder.unlinkToDeath(mDeathRecipient, 0); } if (mStatusCallback != null) { mStatusCallback.notifyUnavailable(); } } } } Loading Loading @@ -430,7 +444,16 @@ public class MmTelFeatureConnection { } public void setBinder(IBinder 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. } } } /** Loading tests/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -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 \ Loading tests/src/com/android/ims/ImsConfigTest.java +4 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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)); } Loading Loading
src/java/com/android/ims/ImsConnectionStateListener.java +1 −1 Original line number Diff line number Diff line Loading @@ -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] = Loading
src/java/com/android/ims/ImsManager.java +47 −46 Original line number Diff line number Diff line Loading @@ -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 = Loading Loading @@ -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( Loading Loading @@ -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); } /** Loading Loading @@ -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. Loading Loading @@ -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; } } Loading Loading @@ -902,7 +904,7 @@ public class ImsManager { } setWfcModeInternal(imsWfcModeFeatureValue); } catch (ImsException | RemoteException e) { } catch (ImsException e) { loge("setWfcSetting(): ", e); } } Loading Loading @@ -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; } } Loading Loading @@ -1301,7 +1303,7 @@ public class ImsManager { } mConfigUpdated = true; } catch (ImsException | RemoteException e) { } catch (ImsException e) { loge("updateImsServiceConfig: ", e); mConfigUpdated = false; } Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -1652,7 +1654,6 @@ public class ImsManager { mMmTelFeatureConnection.closeConnection(); } mUt = null; mConfig = null; mEcbm = null; mMultiEndpoint = null; } Loading Loading @@ -1801,35 +1802,34 @@ 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); } try { mMmTelFeatureConnection.changeEnabledCapabilities(request, null); if (mImsConfigListener != null) { mImsConfigListener.onSetFeatureResponse(capability, Loading @@ -1837,6 +1837,10 @@ public class ImsManager { isEnabled ? ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF, -1); } } catch (RemoteException e) { throw new ImsException("changeMmTelCapability()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); } } public void setRttEnabled(boolean enabled) { Loading Loading @@ -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 { Loading Loading @@ -2140,20 +2153,6 @@ public class ImsManager { mRecentDisconnectReasons.addLast(reason); } /** * 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. * Loading Loading @@ -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(), Loading
src/java/com/android/ims/MmTelFeatureConnection.java +67 −44 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -73,10 +75,16 @@ 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 { Loading @@ -91,16 +99,16 @@ public class MmTelFeatureConnection { throw new RemoteException("Can not create connection!"); } } } 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. synchronized (mLock) { Log.i(TAG, "Local callback removed: " + localCallback); mLocalCallbacks.remove(localCallback); synchronized (mLock) { // If we have removed all local callbacks, remove callback to ImsService. if(mHasConnected) { if (mLocalCallbacks.isEmpty()) { Loading @@ -118,10 +126,10 @@ 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(); } } abstract boolean createConnection() throws RemoteException; Loading @@ -140,48 +148,39 @@ public class MmTelFeatureConnection { public void onRegistered(int imsRadioTech) { Log.i(TAG, "onRegistered ::"); synchronized (mLock) { mLocalCallbacks.forEach(l -> l.onRegistered(imsRadioTech)); } } @Override public void onRegistering(int imsRadioTech) { Log.i(TAG, "onRegistering ::"); synchronized (mLock) { mLocalCallbacks.forEach(l -> l.onRegistering(imsRadioTech)); } } @Override public void onDeregistered(ImsReasonInfo imsReasonInfo) { Log.i(TAG, "onDeregistered ::"); synchronized (mLock) { mLocalCallbacks.forEach(l -> l.onDeregistered(imsReasonInfo)); } } @Override public void onTechnologyChangeFailed(int targetRadioTech, ImsReasonInfo imsReasonInfo) { 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)); } } } @Override boolean createConnection() throws RemoteException { Loading Loading @@ -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)); } } } @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; Loading @@ -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); Loading Loading @@ -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 : { Loading Loading @@ -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) { if (mIsAvailable) { mIsAvailable = false; // invalidate caches. mRegistrationBinder = null; mConfigBinder = null; if (mBinder != null) { mBinder.unlinkToDeath(mDeathRecipient, 0); } if (mStatusCallback != null) { mStatusCallback.notifyUnavailable(); } } } } Loading Loading @@ -430,7 +444,16 @@ public class MmTelFeatureConnection { } public void setBinder(IBinder 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. } } } /** Loading
tests/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -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 \ Loading
tests/src/com/android/ims/ImsConfigTest.java +4 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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)); } Loading