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

Commit b089d7c0 authored by Brad Ebinger's avatar Brad Ebinger Committed by Gerrit Code Review
Browse files

Merge "Refactor ImsService structure"

parents 82e00870 81011e81
Loading
Loading
Loading
Loading
+54 −16
Original line number Diff line number Diff line
@@ -38,8 +38,9 @@ import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;

import com.android.ims.internal.IImsServiceController;
import com.android.ims.internal.IImsServiceFeatureListener;
import com.android.ims.internal.IImsMMTelFeature;
import com.android.ims.internal.IImsRcsFeature;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.PhoneConstants;

@@ -295,21 +296,58 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
    }

    /**
     * Returns the {@link IImsServiceController} that corresponds to the given slot Id and IMS
     * feature or {@link null} if the service is not available. If an ImsServiceController is
     * available, the {@link IImsServiceFeatureListener} callback is registered as a listener for
     * feature updates.
     * @param slotId The SIM slot that we are requesting the {@link IImsServiceController} for.
     * @param feature The IMS Feature we are requesting.
     * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id or {@link null} if
     * the service is not available. If an IImsMMTelFeature is available, the
     * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
     * @param slotId The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
     * @param callback Listener that will send updates to ImsManager when there are updates to
     * ImsServiceController.
     * @return {@link IImsServiceController} interface for the feature specified or {@link null} if
     * it is unavailable.
     * the feature.
     * @return {@link IImsMMTelFeature} interface or {@link null} if it is unavailable.
     */
    public IImsServiceController getImsServiceControllerAndListen(int slotId, int feature,
            IImsServiceFeatureListener callback) {
        if (slotId < 0 || slotId >= mNumSlots || feature <= ImsFeature.INVALID
                || feature >= ImsFeature.MAX) {
    public IImsMMTelFeature getMMTelFeatureAndListen(int slotId,
            IImsServiceFeatureCallback callback) {
        ImsServiceController controller = getImsServiceControllerAndListen(slotId, ImsFeature.MMTEL,
                callback);
        return (controller != null) ? controller.getMMTelFeature(slotId) : null;
    }

    /**
     * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id for emergency
     * calling or {@link null} if the service is not available. If an IImsMMTelFeature is
     * available, the {@link IImsServiceFeatureCallback} callback is registered as a listener for
     * feature updates.
     * @param slotId The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
     * @param callback listener that will send updates to ImsManager when there are updates to
     * the feature.
     * @return {@link IImsMMTelFeature} interface or {@link null} if it is unavailable.
     */
    public IImsMMTelFeature getEmergencyMMTelFeatureAndListen(int slotId,
            IImsServiceFeatureCallback callback) {
        ImsServiceController controller = getImsServiceControllerAndListen(slotId,
                ImsFeature.EMERGENCY_MMTEL, callback);
        return (controller != null) ? controller.getEmergencyMMTelFeature(slotId) : null;
    }

    /**
     * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id for emergency
     * calling or {@link null} if the service is not available. If an IImsMMTelFeature is
     * available, the {@link IImsServiceFeatureCallback} callback is registered as a listener for
     * feature updates.
     * @param slotId The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
     * @param callback listener that will send updates to ImsManager when there are updates to
     * the feature.
     * @return {@link IImsMMTelFeature} interface or {@link null} if it is unavailable.
     */
    public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
        ImsServiceController controller = getImsServiceControllerAndListen(slotId, ImsFeature.RCS,
                callback);
        return (controller != null) ? controller.getRcsFeature(slotId) : null;
    }

    @VisibleForTesting
    public ImsServiceController getImsServiceControllerAndListen(int slotId, int feature,
            IImsServiceFeatureCallback callback) {
        if (slotId < 0 || slotId >= mNumSlots) {
            return null;
        }
        ImsServiceController controller;
@@ -322,7 +360,7 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
        }
        if (controller != null) {
            controller.addImsServiceFeatureListener(callback);
            return controller.getImsServiceController();
            return controller;
        }
        return null;
    }
+138 −11
Original line number Diff line number Diff line
@@ -24,14 +24,18 @@ import android.content.pm.IPackageManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.ims.feature.ImsFeature;
import android.util.Log;
import android.util.Pair;

import com.android.ims.internal.IImsFeatureStatusCallback;
import com.android.ims.internal.IImsMMTelFeature;
import com.android.ims.internal.IImsRcsFeature;
import com.android.ims.internal.IImsServiceController;
import com.android.ims.internal.IImsServiceFeatureListener;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.ExponentialBackoff;

@@ -171,15 +175,54 @@ public class ImsServiceController {
    private boolean mIsBinding = false;
    // Set of a pair of slotId->feature
    private HashSet<Pair<Integer, Integer>> mImsFeatures;
    // Binder interfaces to the features set in mImsFeatures;
    private HashSet<ImsFeatureContainer> mImsFeatureBinders = new HashSet<>();
    private IImsServiceController mIImsServiceController;
    // Easier for testing.
    private IBinder mImsServiceControllerBinder;
    private ImsServiceConnection mImsServiceConnection;
    private ImsDeathRecipient mImsDeathRecipient;
    private Set<IImsServiceFeatureListener> mImsStatusCallbacks = new HashSet<>();
    private Set<IImsServiceFeatureCallback> mImsStatusCallbacks = new HashSet<>();
    // Only added or removed, never accessed on purpose.
    private Set<ImsFeatureStatusCallback> mFeatureStatusCallbacks = new HashSet<>();

    private class ImsFeatureContainer {
        public int slotId;
        public int featureType;
        private IInterface mBinder;

        ImsFeatureContainer(int slotId, int featureType, IInterface binder) {
            this.slotId = slotId;
            this.featureType = featureType;
            this.mBinder = binder;
        }

        // Casts the IInterface into the binder class we are looking for.
        public <T extends IInterface> T resolve(Class<T> className) {
            return className.cast(mBinder);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            ImsFeatureContainer that = (ImsFeatureContainer) o;

            if (slotId != that.slotId) return false;
            if (featureType != that.featureType) return false;
            return mBinder != null ? mBinder.equals(that.mBinder) : that.mBinder == null;
        }

        @Override
        public int hashCode() {
            int result = slotId;
            result = 31 * result + featureType;
            result = 31 * result + (mBinder != null ? mBinder.hashCode() : 0);
            return result;
        }
    }

    /**
     * Container class for the IImsFeatureStatusCallback callback implementation. This class is
     * never used directly, but we need to keep track of the IImsFeatureStatusCallback
@@ -373,12 +416,56 @@ public class ImsServiceController {
    /**
     * Add a callback to ImsManager that signals a new feature that the ImsServiceProxy can handle.
     */
    public void addImsServiceFeatureListener(IImsServiceFeatureListener callback) {
    public void addImsServiceFeatureListener(IImsServiceFeatureCallback callback) {
        synchronized (mLock) {
            mImsStatusCallbacks.add(callback);
        }
    }

    /**
     * Return the {@Link MMTelFeature} binder on the slot associated with the slotId.
     * Used for normal calling.
     */
    public IImsMMTelFeature getMMTelFeature(int slotId) {
        synchronized (mLock) {
            ImsFeatureContainer f = getImsFeatureContainer(slotId, ImsFeature.MMTEL);
            if (f == null) {
                Log.w(LOG_TAG, "Requested null MMTelFeature on slot " + slotId);
                return null;
            }
            return f.resolve(IImsMMTelFeature.class);
        }
    }

    /**
     * Return the {@Link MMTelFeature} binder on the slot associated with the slotId.
     * Used for emergency calling only.
     */
    public IImsMMTelFeature getEmergencyMMTelFeature(int slotId) {
        synchronized (mLock) {
            ImsFeatureContainer f = getImsFeatureContainer(slotId, ImsFeature.EMERGENCY_MMTEL);
            if (f == null) {
                Log.w(LOG_TAG, "Requested null Emergency MMTelFeature on slot " + slotId);
                return null;
            }
            return f.resolve(IImsMMTelFeature.class);
        }
    }

    /**
     * Return the {@Link RcsFeature} binder on the slot associated with the slotId.
     */
    public IImsRcsFeature getRcsFeature(int slotId) {
        synchronized (mLock) {
            ImsFeatureContainer f = getImsFeatureContainer(slotId, ImsFeature.RCS);
            if (f == null) {
                Log.w(LOG_TAG, "Requested null RcsFeature on slot " + slotId);
                return null;
            }
            return f.resolve(IImsRcsFeature.class);
        }
    }

    private void removeImsServiceFeatureListener() {
        synchronized (mLock) {
            mImsStatusCallbacks.clear();
@@ -407,9 +494,9 @@ public class ImsServiceController {

    private void sendImsFeatureCreatedCallback(int slot, int feature) {
        synchronized (mLock) {
            for (Iterator<IImsServiceFeatureListener> i = mImsStatusCallbacks.iterator();
            for (Iterator<IImsServiceFeatureCallback> i = mImsStatusCallbacks.iterator();
                    i.hasNext(); ) {
                IImsServiceFeatureListener callbacks = i.next();
                IImsServiceFeatureCallback callbacks = i.next();
                try {
                    callbacks.imsFeatureCreated(slot, feature);
                } catch (RemoteException e) {
@@ -424,9 +511,9 @@ public class ImsServiceController {

    private void sendImsFeatureRemovedCallback(int slot, int feature) {
        synchronized (mLock) {
            for (Iterator<IImsServiceFeatureListener> i = mImsStatusCallbacks.iterator();
            for (Iterator<IImsServiceFeatureCallback> i = mImsStatusCallbacks.iterator();
                    i.hasNext(); ) {
                IImsServiceFeatureListener callbacks = i.next();
                IImsServiceFeatureCallback callbacks = i.next();
                try {
                    callbacks.imsFeatureRemoved(slot, feature);
                } catch (RemoteException e) {
@@ -441,9 +528,9 @@ public class ImsServiceController {

    private void sendImsFeatureStatusChanged(int slot, int feature, int status) {
        synchronized (mLock) {
            for (Iterator<IImsServiceFeatureListener> i = mImsStatusCallbacks.iterator();
            for (Iterator<IImsServiceFeatureCallback> i = mImsStatusCallbacks.iterator();
                    i.hasNext(); ) {
                IImsServiceFeatureListener callbacks = i.next();
                IImsServiceFeatureCallback callbacks = i.next();
                try {
                    callbacks.imsStatusChanged(slot, feature, status);
                } catch (RemoteException e) {
@@ -465,8 +552,8 @@ public class ImsServiceController {
        ImsFeatureStatusCallback c = new ImsFeatureStatusCallback(featurePair.first,
                featurePair.second);
        mFeatureStatusCallbacks.add(c);
        mIImsServiceController.createImsFeature(featurePair.first, featurePair.second,
                c.getCallback());
        IInterface f = createImsFeature(featurePair.first, featurePair.second, c.getCallback());
        addImsFeatureBinder(featurePair.first, featurePair.second, f);
        // Signal ImsResolver to change supported ImsFeatures for this ImsServiceController
        mCallbacks.imsServiceFeatureCreated(featurePair.first, featurePair.second, this);
        // Send callback to ImsServiceProxy to change supported ImsFeatures
@@ -489,6 +576,7 @@ public class ImsServiceController {
        }
        mIImsServiceController.removeImsFeature(featurePair.first, featurePair.second,
                (callbackToRemove != null ? callbackToRemove.getCallback() : null));
        removeImsFeatureBinder(featurePair.first, featurePair.second);
        // Signal ImsResolver to change supported ImsFeatures for this ImsServiceController
        mCallbacks.imsServiceFeatureRemoved(featurePair.first, featurePair.second, this);
        // Send callback to ImsServiceProxy to change supported ImsFeatures
@@ -498,6 +586,45 @@ public class ImsServiceController {
        sendImsFeatureRemovedCallback(featurePair.first, featurePair.second);
    }

    // This method should only be called when already synchronized on mLock;
    private IInterface createImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
            throws RemoteException {
        switch (featureType) {
            case ImsFeature.EMERGENCY_MMTEL: {
                return mIImsServiceController.createEmergencyMMTelFeature(slotId, c);
            }
            case ImsFeature.MMTEL: {
                return mIImsServiceController.createMMTelFeature(slotId, c);
            }
            case ImsFeature.RCS: {
                return mIImsServiceController.createRcsFeature(slotId, c);
            }
            default:
                return null;
        }
    }

    // This method should only be called when synchronized on mLock
    private void addImsFeatureBinder(int slotId, int featureType, IInterface b) {
        mImsFeatureBinders.add(new ImsFeatureContainer(slotId, featureType, b));
    }

    // This method should only be called when synchronized on mLock
    private void removeImsFeatureBinder(int slotId, int featureType) {
        ImsFeatureContainer container = mImsFeatureBinders.stream()
                .filter(f-> (f.slotId == slotId && f.featureType == featureType))
                .findFirst().orElse(null);
        if (container != null) {
            mImsFeatureBinders.remove(container);
        }
    }

    private ImsFeatureContainer getImsFeatureContainer(int slotId, int featureType) {
        return mImsFeatureBinders.stream()
                .filter(f-> (f.slotId == slotId && f.featureType == featureType))
                .findFirst().orElse(null);
    }

    private void notifyAllFeaturesRemoved() {
        if (mCallbacks == null) {
            Log.w(LOG_TAG, "notifyAllFeaturesRemoved called with invalid callbacks.");
+8 −31
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.telephony.ims;

import android.os.IInterface;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.feature.ImsFeature;
import android.test.suitebuilder.annotation.SmallTest;
@@ -30,9 +31,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

@RunWith(AndroidJUnit4.class)
@@ -44,20 +43,21 @@ public class ImsFeatureTest {
    private IImsFeatureStatusCallback mTestStatusCallback;
    @Mock
    private IImsFeatureStatusCallback mTestStatusCallback2;
    @Mock
    private ImsFeature.INotifyFeatureRemoved mTestRemovedCallback;

    private class TestImsFeature extends ImsFeature {

        public boolean featureRemovedCalled = false;
        public void testSetFeatureState(int featureState) {
            setFeatureState(featureState);
        }

        @Override
        public void onFeatureRemoved() {
            featureRemovedCalled = true;

        }

        public void testSetFeatureState(int featureState) {
            setFeatureState(featureState);
        @Override
        public IInterface getBinder() {
            return null;
        }
    }

@@ -94,27 +94,4 @@ public class ImsFeatureTest {
        verify(mTestStatusCallback2).notifyImsFeatureStatus(eq(ImsFeature.STATE_READY));
        assertEquals(ImsFeature.STATE_READY, mTestImsService.getFeatureState());
    }

    @Test
    @SmallTest
    public void testRegisterAndNotifyRemoveFeature() {
        mTestImsService.addFeatureRemovedListener(mTestRemovedCallback);

        mTestImsService.notifyFeatureRemoved(0);

        verify(mTestRemovedCallback).onFeatureRemoved(eq(0));
        assertTrue(mTestImsService.featureRemovedCalled);
    }

    @Test
    @SmallTest
    public void testRegisterAndUnregisterNotify() {
        mTestImsService.addFeatureRemovedListener(mTestRemovedCallback);
        mTestImsService.removeFeatureRemovedListener(mTestRemovedCallback);

        mTestImsService.notifyFeatureRemoved(0);

        verify(mTestRemovedCallback, never()).onFeatureRemoved(eq(0));
        assertTrue(mTestImsService.featureRemovedCalled);
    }
}
+25 −79
Original line number Diff line number Diff line
@@ -16,44 +16,33 @@

package android.telephony.ims;

import static android.Manifest.permission.MODIFY_PHONE_STATE;
import static android.Manifest.permission.READ_PHONE_STATE;
import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;

import static com.android.internal.telephony.ims.ImsResolver.SERVICE_INTERFACE;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.support.test.filters.FlakyTest;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MMTelFeature;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.SparseArray;

import com.android.ims.ImsManager;
import com.android.ims.internal.IImsFeatureStatusCallback;
import com.android.ims.internal.IImsMMTelFeature;
import com.android.ims.internal.IImsServiceController;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -94,88 +83,45 @@ public class ImsServiceTest {
    @Test
    @SmallTest
    public void testCreateMMTelFeature() throws RemoteException {
        mTestImsServiceBinder.createImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);
        when(mTestImsService.mSpyMMTelFeature.getFeatureState()).thenReturn(
                ImsFeature.STATE_READY);

        SparseArray<ImsFeature> features = mTestImsService.getImsFeatureMap(TEST_SLOT_0);
        assertEquals(mTestImsService.mSpyMMTelFeature,
                mTestImsService.getImsFeatureFromType(features, ImsFeature.MMTEL));
        IImsMMTelFeature f = mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);
        mTestImsService.mTestMMTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);

        SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
        ImsFeature featureToVerify = features.get(ImsFeature.MMTEL);
        MMTelFeature testMMTelFeature = null;
        if (featureToVerify instanceof MMTelFeature) {
            testMMTelFeature = (MMTelFeature) featureToVerify;
        } else {
            fail();
        }
        assertEquals(mTestImsService.mSpyMMTelFeature, testMMTelFeature);
        // Verify that upon creating a feature, we assign the callback and get the set feature state
        // when querying it.
        verify(mTestImsService.mSpyMMTelFeature).addImsFeatureStatusCallback(eq(mTestCallback));
        assertEquals(ImsFeature.STATE_READY, mTestImsServiceBinder.getFeatureStatus(TEST_SLOT_0,
                ImsFeature.MMTEL));
        assertEquals(ImsFeature.STATE_READY, f.getFeatureStatus());
    }

    @Test
    @SmallTest
    public void testRemoveMMTelFeature() throws RemoteException {
        mTestImsServiceBinder.createImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);
        mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);

        mTestImsServiceBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);

        verify(mTestImsService.mSpyMMTelFeature).notifyFeatureRemoved(eq(0));
        verify(mTestImsService.mSpyMMTelFeature).onFeatureRemoved();
        verify(mTestImsService.mSpyMMTelFeature).removeImsFeatureStatusCallback(mTestCallback);
        SparseArray<ImsFeature> features = mTestImsService.getImsFeatureMap(TEST_SLOT_0);
        assertNull(mTestImsService.getImsFeatureFromType(features, ImsFeature.MMTEL));
        SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
        assertNull(features.get(ImsFeature.MMTEL));
    }

    @Test
    @SmallTest
    public void testCallMethodOnCreatedFeature() throws RemoteException {
        mTestImsServiceBinder.createImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);

        mTestImsServiceBinder.isConnected(TEST_SLOT_0, ImsFeature.MMTEL, 0 /*callSessionType*/,
                0 /*callType*/);

        verify(mTestImsService.mSpyMMTelFeature).isConnected(anyInt(), anyInt());
    }

    @Test
    @SmallTest
    public void testCallMethodWithNoCreatedFeature() throws RemoteException {
        mTestImsServiceBinder.createImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);

        mTestImsServiceBinder.isConnected(TEST_SLOT_1, ImsFeature.MMTEL, 0 /*callSessionType*/,
                0 /*callType*/);

        verify(mTestImsService.mSpyMMTelFeature, never()).isConnected(anyInt(), anyInt());
    }
        IImsMMTelFeature f = mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);

    @Test
    @SmallTest
    public void testCreateFeatureWithNoPermissions() throws RemoteException {
        doThrow(new SecurityException()).when(mMockContext).enforceCallingOrSelfPermission(
                eq(MODIFY_PHONE_STATE), anyString());

        try {
            mTestImsServiceBinder.createImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);
            fail();
        } catch (SecurityException e) {
            // Expected
        }
    }

    @FlakyTest
    @Ignore
    @Test
    public void testMethodWithNoPermissions() throws RemoteException {
        when(mMockContext.checkCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE)).thenReturn(
                PackageManager.PERMISSION_DENIED);
        doThrow(new SecurityException()).when(mMockContext).enforceCallingOrSelfPermission(
                eq(READ_PHONE_STATE), nullable(String.class));
        mTestImsServiceBinder.createImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);

        try {
            mTestImsServiceBinder.isConnected(TEST_SLOT_1, ImsFeature.MMTEL, 0 /*callSessionType*/,
                    0 /*callType*/);
            fail();
        } catch (SecurityException e) {
            // Expected
        }
        f.isConnected(0/*callSessionType*/, 0 /*callType*/);

        verify(mTestImsService.mSpyMMTelFeature, never()).isConnected(anyInt(), anyInt());
        assertTrue(mTestImsService.mTestMMTelFeature.isConnectedCalled);
    }

    /**
@@ -185,7 +131,7 @@ public class ImsServiceTest {
    @Test
    @SmallTest
    public void testImsServiceUpSentCompat() throws RemoteException {
        mTestImsServiceBinder.createImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);
        mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);

        mTestImsService.mSpyMMTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);

@@ -207,7 +153,7 @@ public class ImsServiceTest {
    @Test
    @SmallTest
    public void testImsServiceDownSentCompatInitializing() throws RemoteException {
        mTestImsServiceBinder.createImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);
        mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);

        mTestImsService.mSpyMMTelFeature.sendSetFeatureState(ImsFeature.STATE_INITIALIZING);

+1 −2
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.telephony.ims.feature.MMTelFeature;
import android.telephony.ims.feature.RcsFeature;

import org.mockito.MockitoAnnotations;
import org.mockito.Spy;

import static org.mockito.Mockito.spy;

@@ -32,7 +31,7 @@ import static org.mockito.Mockito.spy;
public class TestImsService extends ImsService {

    public TestMMTelFeature mSpyMMTelFeature;
    private TestMMTelFeature mTestMMTelFeature;
    public TestMMTelFeature mTestMMTelFeature;

    public TestImsService(Context context) {
        attachBaseContext(context);
Loading