Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5c128c5 authored by Brad Ebinger's avatar Brad Ebinger Committed by Automerger Merge Worker
Browse files

Remove persistent state in ImsManager and move to MmTelFeatureConnection am: 71aec9b4

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/net/ims/+/1427580

Change-Id: I42a9f5d9c8b547ce76406ccd6909bdae213d82d7
parents 30b93283 71aec9b4
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -68,6 +69,7 @@ public abstract class FeatureConnection {
    protected Integer mFeatureStateCached = null;
    protected IFeatureUpdate mStatusCallback;
    protected IImsRegistration mRegistrationBinder;
    protected IImsConfig mConfigBinder;
    protected final Object mLock = new Object();

    public FeatureConnection(Context context, int slotId) {
@@ -208,6 +210,26 @@ public abstract class FeatureConnection {
        return mRegistrationBinder;
    }

    public @Nullable
    IImsConfig getConfig() {
        synchronized (mLock) {
            // null if cache is invalid;
            if (mConfigBinder != null) {
                return mConfigBinder;
            }
        }
        // We don't want to synchronize on a binder call to another process.
        IImsConfig configBinder = getConfigBinder();
        synchronized (mLock) {
            // mRegistrationBinder may have changed while we tried to get the registration
            // interface.
            if (mConfigBinder == null) {
                mConfigBinder = configBinder;
            }
        }
        return mConfigBinder;
    }

    @VisibleForTesting
    public void checkServiceIsReady() throws RemoteException {
        if (!sImsSupportedOnDevice) {
@@ -295,4 +317,9 @@ public abstract class FeatureConnection {
     * @return The ImsRegistration instance associated with the FeatureConnection.
     */
    protected abstract IImsRegistration getRegistrationBinder();

    /**
     * @return The ImsRegistration instance associated with the FeatureConnection.
     */
    protected abstract IImsConfig getConfigBinder();
}
+53 −146
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemProperties;
@@ -56,9 +55,6 @@ import android.telephony.ims.stub.ImsConfigImplBase;
import android.telephony.ims.stub.ImsRegistrationImplBase;

import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsEcbm;
import com.android.ims.internal.IImsMultiEndpoint;
import com.android.ims.internal.IImsUt;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.util.HandlerExecutor;
@@ -66,11 +62,9 @@ import com.android.telephony.Rlog;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
@@ -323,11 +317,6 @@ public class ImsManager implements IFeatureConnector {
    public static final String TRUE = "true";
    public static final String FALSE = "false";

    // mRecentDisconnectReasons stores the last 16 disconnect reasons
    private static final int MAX_RECENT_DISCONNECT_REASONS = 16;
    private ConcurrentLinkedDeque<ImsReasonInfo> mRecentDisconnectReasons =
            new ConcurrentLinkedDeque<>();

    /**
     * Gets a manager instance.
     *
@@ -1355,38 +1344,8 @@ public class ImsManager implements IFeatureConnector {

    /**
     * Sync carrier config and user settings with ImsConfigImplBase implementation.
     *
     * @param context for the manager object
     * @param phoneId phone id
     * @param force update
     *
     * @deprecated Doesn't support MSIM devices. Use {@link #updateImsServiceConfig(boolean)}
     * instead.
     */
    public static void updateImsServiceConfig(Context context, int phoneId, boolean force) {
        ImsManager mgr = ImsManager.getInstance(context, phoneId);
        if (mgr != null) {
            mgr.updateImsServiceConfig(force);
        }
        Rlog.e(TAG, "updateImsServiceConfig: ImsManager null, returning without update.");
    }

    /**
     * Sync carrier config and user settings with ImsConfigImplBase implementation.
     *
     * @param force update
     */
    public void updateImsServiceConfig(boolean force) {
        if (!force) {
            TelephonyManager tm = new TelephonyManager(mContext, getSubId());
            if (tm.getSimState() != TelephonyManager.SIM_STATE_READY) {
                log("updateImsServiceConfig: SIM not ready");
                // Don't disable IMS if SIM is not ready
                return;
            }
        }

        if (!mConfigUpdated || force) {
    public void updateImsServiceConfig() {
        try {
            PersistableBundle imsCarrierConfigs =
                    mConfigManager.getConfigByComponentForSubId(
@@ -1424,14 +1383,12 @@ public class ImsManager implements IFeatureConnector {
                log("updateImsServiceConfig: turnOffIms");
                turnOffIms();
            }

            mConfigUpdated = true;
        } catch (ImsException e) {
            loge("updateImsServiceConfig: ", e);
            mConfigUpdated = false;
        }
    }
    }

    private boolean isImsNeeded(CapabilityChangeRequest r) {
        // IMS is not needed for UT, so only enabled IMS if any other capability is enabled.
@@ -1958,9 +1915,6 @@ public class ImsManager implements IFeatureConnector {
        if (mMmTelFeatureConnection != null) {
            mMmTelFeatureConnection.closeConnection();
        }
        mUt = null;
        mEcbm = null;
        mMultiEndpoint = null;
    }

    /**
@@ -1970,26 +1924,20 @@ public class ImsManager implements IFeatureConnector {
     * @throws ImsException if getting the Ut interface results in an error
     */
    public ImsUtInterface getSupplementaryServiceConfiguration() throws ImsException {
        // FIXME: manage the multiple Ut interfaces based on the session id
        if (mUt != null && mUt.isBinderAlive()) {
            return mUt;
        }

        ImsUt iUt = null;
        checkAndThrowExceptionIfServiceUnavailable();
        try {
            IImsUt iUt = mMmTelFeatureConnection.getUtInterface();
            iUt = mMmTelFeatureConnection.getUtInterface();

            if (iUt == null) {
                throw new ImsException("getSupplementaryServiceConfiguration()",
                        ImsReasonInfo.CODE_UT_NOT_SUPPORTED);
            }

            mUt = new ImsUt(iUt);
        } catch (RemoteException e) {
            throw new ImsException("getSupplementaryServiceConfiguration()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }
        return mUt;
        return iUt;
    }

    /**
@@ -2092,7 +2040,7 @@ public class ImsManager implements IFeatureConnector {
    public ImsConfig getConfigInterface() throws ImsException {
        checkAndThrowExceptionIfServiceUnavailable();

        IImsConfig config = mMmTelFeatureConnection.getConfigInterface();
        IImsConfig config = mMmTelFeatureConnection.getConfig();
        if (config == null) {
            throw new ImsException("getConfigInterface()",
                    ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
@@ -2293,31 +2241,6 @@ public class ImsManager implements IFeatureConnector {
        }
    }

    private ImsReasonInfo makeACopy(ImsReasonInfo imsReasonInfo) {
        Parcel p = Parcel.obtain();
        imsReasonInfo.writeToParcel(p, 0);
        p.setDataPosition(0);
        ImsReasonInfo clonedReasonInfo = ImsReasonInfo.CREATOR.createFromParcel(p);
        p.recycle();
        return clonedReasonInfo;
    }

    /**
     * Get Recent IMS Disconnect Reasons.
     *
     * @return ArrayList of ImsReasonInfo objects. MAX size of the arraylist
     * is MAX_RECENT_DISCONNECT_REASONS. The objects are in the
     * chronological order.
     */
    public ArrayList<ImsReasonInfo> getRecentImsDisconnectReasons() {
        ArrayList<ImsReasonInfo> disconnectReasons = new ArrayList<>();

        for (ImsReasonInfo reason : mRecentDisconnectReasons) {
            disconnectReasons.add(makeACopy(reason));
        }
        return disconnectReasons;
    }

    @Override
    public int getImsServiceState() throws ImsException {
        return mMmTelFeatureConnection.getFeatureState();
@@ -2539,14 +2462,6 @@ public class ImsManager implements IFeatureConnector {
        tm.disableIms(mPhoneId);
    }

    private void addToRecentDisconnectReasons(ImsReasonInfo reason) {
        if (reason == null) return;
        while (mRecentDisconnectReasons.size() >= MAX_RECENT_DISCONNECT_REASONS) {
            mRecentDisconnectReasons.removeFirst();
        }
        mRecentDisconnectReasons.addLast(reason);
    }

    /**
     * Gets the ECBM interface to request ECBM exit.
     *
@@ -2554,24 +2469,20 @@ public class ImsManager implements IFeatureConnector {
     * @throws ImsException if getting the ECBM interface results in an error
     */
    public ImsEcbm getEcbmInterface() throws ImsException {
        if (mEcbm != null && mEcbm.isBinderAlive()) {
            return mEcbm;
        }

        ImsEcbm iEcbm = null;
        checkAndThrowExceptionIfServiceUnavailable();
        try {
            IImsEcbm iEcbm = mMmTelFeatureConnection.getEcbmInterface();
            iEcbm = mMmTelFeatureConnection.getEcbmInterface();

            if (iEcbm == null) {
                throw new ImsException("getEcbmInterface()",
                        ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED);
            }
            mEcbm = new ImsEcbm(iEcbm);
        } catch (RemoteException e) {
            throw new ImsException("getEcbmInterface()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }
        return mEcbm;
        return iEcbm;
    }

    public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
@@ -2657,25 +2568,21 @@ public class ImsManager implements IFeatureConnector {
     * @throws ImsException if getting the multi-endpoint interface results in an error
     */
    public ImsMultiEndpoint getMultiEndpointInterface() throws ImsException {
        if (mMultiEndpoint != null && mMultiEndpoint.isBinderAlive()) {
            return mMultiEndpoint;
        }

        checkAndThrowExceptionIfServiceUnavailable();
        ImsMultiEndpoint iImsMultiEndpoint;
        try {
            IImsMultiEndpoint iImsMultiEndpoint = mMmTelFeatureConnection.getMultiEndpointInterface();
            iImsMultiEndpoint = mMmTelFeatureConnection.getMultiEndpointInterface();

            if (iImsMultiEndpoint == null) {
                throw new ImsException("getMultiEndpointInterface()",
                        ImsReasonInfo.CODE_MULTIENDPOINT_NOT_SUPPORTED);
            }
            mMultiEndpoint = new ImsMultiEndpoint(iImsMultiEndpoint);
        } catch (RemoteException e) {
            throw new ImsException("getMultiEndpointInterface()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }

        return mMultiEndpoint;
        return iImsMultiEndpoint;
    }

    /**
@@ -2742,7 +2649,7 @@ public class ImsManager implements IFeatureConnector {
        }

        // Push settings to ImsConfig
        updateImsServiceConfig(true);
        updateImsServiceConfig();
    }

    public void setVolteProvisioned(boolean isProvisioned) {
@@ -2852,7 +2759,7 @@ public class ImsManager implements IFeatureConnector {
    private void updateImsCarrierConfigs(PersistableBundle configs) throws ImsException {
        checkAndThrowExceptionIfServiceUnavailable();

        IImsConfig config = mMmTelFeatureConnection.getConfigInterface();
        IImsConfig config = mMmTelFeatureConnection.getConfig();
        if (config == null) {
            throw new ImsException("getConfigInterface()",
                    ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
+38 −36
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.os.Message;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsService;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsConfigCallback;
@@ -48,7 +49,7 @@ import com.android.telephony.Rlog;
 */

public class MmTelFeatureConnection extends FeatureConnection {
    protected static final String TAG = "MmTelFeatureConnection";
    protected static final String TAG = "MmTelFeatureConn";

    private class ImsRegistrationCallbackAdapter extends
            ImsCallbackAdapterManager<IImsRegistrationCallback> {
@@ -160,7 +161,7 @@ public class MmTelFeatureConnection extends FeatureConnection {

        @Override
        public void registerCallback(IImsConfigCallback localCallback) {
            IImsConfig binder = getConfigInterface();
            IImsConfig binder = getConfig();
            if (binder == null) {
                // Config interface is not currently available.
                Log.w(TAG + " [" + mSlotId + "]", "ProvisioningCallbackManager - couldn't register,"
@@ -176,7 +177,7 @@ public class MmTelFeatureConnection extends FeatureConnection {

        @Override
        public void unregisterCallback(IImsConfigCallback localCallback) {
            IImsConfig binder = getConfigInterface();
            IImsConfig binder = getConfig();
            if (binder == null) {
                Log.w(TAG + " [" + mSlotId + "]", "ProvisioningCallbackManager - couldn't"
                        + " unregister, binder is null.");
@@ -193,10 +194,11 @@ public class MmTelFeatureConnection extends FeatureConnection {

    // Updated by IImsServiceFeatureCallback when FEATURE_EMERGENCY_MMTEL is sent.
    private boolean mSupportsEmergencyCalling = false;
    // MMTEL specific binder Interfaces
    private ImsUt mUt;
    private ImsEcbm mEcbm;
    private ImsMultiEndpoint mMultiEndpoint;

    // Cache the Registration and Config interfaces as long as the MmTel feature is connected. If
    // it becomes disconnected, invalidate.
    private IImsConfig mConfigBinder;
    private final ImsRegistrationCallbackAdapter mRegistrationCallbackManager;
    private final CapabilityCallbackManager mCapabilityCallbackManager;
    private final ProvisioningCallbackManager mProvisioningCallbackManager;
@@ -245,7 +247,6 @@ public class MmTelFeatureConnection extends FeatureConnection {
            mRegistrationCallbackManager.close();
            mCapabilityCallbackManager.close();
            mProvisioningCallbackManager.close();
            mConfigBinder = null;
        }
    }

@@ -256,25 +257,6 @@ public class MmTelFeatureConnection extends FeatureConnection {
        }
    }

    private IImsConfig getConfig() {
        synchronized (mLock) {
            // null if cache is invalid;
            if (mConfigBinder != null) {
                return mConfigBinder;
            }
        }
        TelephonyManager tm = getTelephonyManager();
        IImsConfig configBinder = tm != null
                ? tm.getImsConfig(mSlotId, ImsFeature.FEATURE_MMTEL) : null;
        synchronized (mLock) {
            // mConfigBinder may have changed while we tried to get the config interface.
            if (mConfigBinder == null) {
                mConfigBinder = configBinder;
            }
        }
        return mConfigBinder;
    }

    @Override
    protected void handleImsFeatureCreatedCallback(int slotId, int feature) {
        // The feature has been enabled. This happens when the feature is first created and
@@ -360,6 +342,12 @@ public class MmTelFeatureConnection extends FeatureConnection {
        mProvisioningCallbackManager.close();
        try {
            synchronized (mLock) {
                if (mUt != null) {
                    mUt.close();
                    mUt = null;
                }
                mEcbm = null;
                mMultiEndpoint = null;
                if (isBinderAlive()) {
                    getServiceInterface(mBinder).setListener(null);
                }
@@ -456,21 +444,25 @@ public class MmTelFeatureConnection extends FeatureConnection {
        }
    }

    public IImsUt getUtInterface() throws RemoteException {
    public ImsUt getUtInterface() throws RemoteException {
        synchronized (mLock) {
            if (mUt != null) return mUt;

            checkServiceIsReady();
            return getServiceInterface(mBinder).getUtInterface();
        }
            IImsUt imsUt = getServiceInterface(mBinder).getUtInterface();
            mUt = (imsUt != null) ? new ImsUt(imsUt) : null;
            return mUt;
        }

    public IImsConfig getConfigInterface() {
        return getConfig();
    }

    public IImsEcbm getEcbmInterface() throws RemoteException {
    public ImsEcbm getEcbmInterface() throws RemoteException {
        synchronized (mLock) {
            if (mEcbm != null) return mEcbm;

            checkServiceIsReady();
            return getServiceInterface(mBinder).getEcbmInterface();
            IImsEcbm imsEcbm = getServiceInterface(mBinder).getEcbmInterface();
            mEcbm = (imsEcbm != null) ? new ImsEcbm(imsEcbm) : null;
            return mEcbm;
        }
    }

@@ -482,10 +474,14 @@ public class MmTelFeatureConnection extends FeatureConnection {
        }
    }

    public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
    public ImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
        synchronized (mLock) {
            if(mMultiEndpoint != null) return mMultiEndpoint;

            checkServiceIsReady();
            return getServiceInterface(mBinder).getMultiEndpointInterface();
            IImsMultiEndpoint imEndpoint = getServiceInterface(mBinder).getMultiEndpointInterface();
            mMultiEndpoint = (imEndpoint != null) ? new ImsMultiEndpoint(imEndpoint) : null;
            return mMultiEndpoint;
        }
    }

@@ -567,6 +563,12 @@ public class MmTelFeatureConnection extends FeatureConnection {
        return  tm != null ? tm.getImsRegistration(mSlotId, ImsFeature.FEATURE_MMTEL) : null;
    }

    @Override
    protected IImsConfig getConfigBinder() {
        TelephonyManager tm = getTelephonyManager();
        return  tm != null ? tm.getImsConfig(mSlotId, ImsFeature.FEATURE_MMTEL) : null;
    }

    private IImsMmTelFeature getServiceInterface(IBinder b) {
        return IImsMmTelFeature.Stub.asInterface(b);
    }
+7 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsRcsFeature;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
@@ -335,6 +336,12 @@ public class RcsFeatureConnection extends FeatureConnection {
        return  tm != null ? tm.getImsRegistration(mSlotId, ImsFeature.FEATURE_RCS) : null;
    }

    @Override
    protected IImsConfig getConfigBinder() {
        TelephonyManager tm = getTelephonyManager();
        return  tm != null ? tm.getImsConfig(mSlotId, ImsFeature.FEATURE_RCS) : null;
    }

    @VisibleForTesting
    public IImsRcsFeature getServiceInterface(IBinder b) {
        return IImsRcsFeature.Stub.asInterface(b);
+11 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -99,6 +100,11 @@ public class FeatureConnectionTest extends ImsTestBase {
            return getTestRegistrationBinder();
        }

        @Override
        protected IImsConfig getConfigBinder() {
            return getTestConfigBinder();
        }

        public void setFeatureState(int state) {
            mFeatureState = state;
        }
@@ -107,6 +113,7 @@ public class FeatureConnectionTest extends ImsTestBase {
    private TestFeatureConnection mTestFeatureConnection;
    @Mock IBinder mBinder;
    @Mock IImsRegistration mRegistrationBinder;
    @Mock IImsConfig mConfigBinder;

    public static final int PHONE_ID = 1;

@@ -215,6 +222,10 @@ public class FeatureConnectionTest extends ImsTestBase {
        }
    }

    private IImsConfig getTestConfigBinder() {
        return mConfigBinder;
    }

    private IImsRegistration getTestRegistrationBinder() {
        return mRegistrationBinder;
    }
Loading