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

Commit 5eddfcc7 authored by Hunsuk Choi's avatar Hunsuk Choi Committed by Android (Google) Code Review
Browse files

Merge "Refactor DomainSelectionResolver for domain selection service plugin" into main

parents 66dce5fd e50ad860
Loading
Loading
Loading
Loading
+81 −26
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@ import static com.android.internal.telephony.RIL.RADIO_HAL_VERSION_2_1;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.telephony.DomainSelectionService;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Log;
@@ -42,6 +44,8 @@ import java.io.PrintWriter;
 * selector.
 */
public class DomainSelectionResolver {
    @VisibleForTesting
    protected static final String PACKAGE_NAME_NONE = "none";
    private static final String TAG = DomainSelectionResolver.class.getSimpleName();
    private static DomainSelectionResolver sInstance = null;

@@ -49,12 +53,12 @@ public class DomainSelectionResolver {
     * Creates the DomainSelectionResolver singleton instance.
     *
     * @param context The context of the application.
     * @param deviceConfigEnabled The flag to indicate whether or not the device supports
     *                            the domain selection service or not.
     * @param flattenedComponentName A flattened component name for the domain selection service
     *                               to be bound to the domain selection controller.
     */
    public static void make(Context context, boolean deviceConfigEnabled) {
    public static void make(Context context, String flattenedComponentName) {
        if (sInstance == null) {
            sInstance = new DomainSelectionResolver(context, deviceConfigEnabled);
            sInstance = new DomainSelectionResolver(context, flattenedComponentName);
        }
    }

@@ -86,34 +90,33 @@ public class DomainSelectionResolver {
    @VisibleForTesting
    public interface DomainSelectionControllerFactory {
        /**
         * Returns a {@link DomainSelectionController} created using the specified
         * context and {@link DomainSelectionService} instance.
         * Returns a {@link DomainSelectionController} created using the specified context.
         */
        DomainSelectionController create(@NonNull Context context,
                @NonNull DomainSelectionService service);
        DomainSelectionController create(@NonNull Context context);
    }

    private DomainSelectionControllerFactory mDomainSelectionControllerFactory =
            new DomainSelectionControllerFactory() {
                @Override
        public DomainSelectionController create(@NonNull Context context,
                @NonNull DomainSelectionService service) {
            return new DomainSelectionController(context, service);
                public DomainSelectionController create(@NonNull Context context) {
                    return new DomainSelectionController(context);
                }
            };

    // Persistent Logging
    private final LocalLog mEventLog = new LocalLog(10);
    private final Context mContext;
    // The flag to indicate whether the device supports the domain selection service or not.
    private final boolean mDeviceConfigEnabled;
    // Stores the default component name to bind the domain selection service so that
    // the test can override this component name with their own domain selection service.
    private final ComponentName mDefaultComponentName;
    // DomainSelectionController, which are bound to DomainSelectionService.
    private DomainSelectionController mController;

    public DomainSelectionResolver(Context context, boolean deviceConfigEnabled) {
    public DomainSelectionResolver(Context context, String flattenedComponentName) {
        mContext = context;
        mDeviceConfigEnabled = deviceConfigEnabled;
        logi("DomainSelectionResolver created: device-config=" + deviceConfigEnabled);
        flattenedComponentName = (flattenedComponentName == null) ? "" : flattenedComponentName;
        mDefaultComponentName = ComponentName.unflattenFromString(flattenedComponentName);
        logi("DomainSelectionResolver created: componentName=[" + flattenedComponentName + "]");
    }

    /**
@@ -126,7 +129,7 @@ public class DomainSelectionResolver {
     *         {@code false} otherwise.
     */
    public boolean isDomainSelectionSupported() {
        return mDeviceConfigEnabled && PhoneFactory.getDefaultPhone()
        return mDefaultComponentName != null && PhoneFactory.getDefaultPhone()
                .getHalVersion(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1);
    }

@@ -171,14 +174,62 @@ public class DomainSelectionResolver {
    }

    /**
     * Needs to be called after the constructor to create a {@link DomainSelectionController} that
     * is bound to the given {@link DomainSelectionService}.
     * Creates the {@link DomainSelectionController} and requests the domain selection controller
     * to bind to the {@link DomainSelectionService} with the component name.
     */
    public void initialize() {
        logi("Initialize");
        mController = mDomainSelectionControllerFactory.create(mContext);
        if (mDefaultComponentName != null) {
            mController.bind(mDefaultComponentName);
        } else {
            logi("No component name specified for domain selection service.");
        }
    }

    /**
     * Sets the component name of domain selection service to be bound.
     *
     * @param service A {@link DomainSelectionService} to be bound.
     * NOTE: This should only be used for testing.
     *
     * @return {@code true} if the requested operation is successfully done,
     *         {@code false} otherwise.
     */
    public void initialize(@NonNull DomainSelectionService service) {
        logi("Initialize.");
        mController = mDomainSelectionControllerFactory.create(mContext, service);
    @VisibleForTesting
    public boolean setDomainSelectionServiceOverride(@NonNull ComponentName componentName) {
        if (mController == null) {
            logd("Controller is not initialized.");
            return false;
        }
        logi("setDomainSelectionServiceOverride: " + componentName);
        if (TextUtils.isEmpty(componentName.getPackageName())
                || TextUtils.equals(PACKAGE_NAME_NONE, componentName.getPackageName())) {
            // Unbind the active service connection to the domain selection service.
            mController.unbind();
            return true;
        }
        // Override the domain selection service with the given component name.
        return mController.bind(componentName);
    }

    /**
     * Clears the overridden domain selection service and restores the domain selection service
     * with the default component.
     *
     * NOTE: This should only be used for testing.
     *
     * @return {@code true} if the requested operation is successfully done,
     *         {@code false} otherwise.
     */
    @VisibleForTesting
    public boolean clearDomainSelectionServiceOverride() {
        if (mController == null) {
            logd("Controller is not initialized.");
            return false;
        }
        logi("clearDomainSelectionServiceOverride");
        mController.unbind();
        return mController.bind(mDefaultComponentName);
    }

    /**
@@ -205,6 +256,10 @@ public class DomainSelectionResolver {
        ipw.decreaseIndent();
    }

    private void logd(String s) {
        Log.d(TAG, s);
    }

    private void logi(String s) {
        Log.i(TAG, s);
        mEventLog.log(s);
+113 −28
Original line number Diff line number Diff line
@@ -31,10 +31,13 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
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.ComponentName;
import android.content.Context;
import android.telephony.DomainSelectionService;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

@@ -56,10 +59,24 @@ import org.mockito.Mockito;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class DomainSelectionResolverTest extends TelephonyTest {
    private static final String COMPONENT_NAME_STRING =
            "com.android.dss/.TelephonyDomainSelectionService";
    private static final ComponentName DSS_COMPONENT_NAME =
            ComponentName.unflattenFromString(COMPONENT_NAME_STRING);
    private static final String CLASS_NAME = "com.android.dss.TelephonyDomainSelectionService";
    private static final String EMPTY_COMPONENT_NAME_STRING = "/" + CLASS_NAME;
    private static final ComponentName EMPTY_COMPONENT_NAME =
            ComponentName.unflattenFromString(EMPTY_COMPONENT_NAME_STRING);
    private static final String NONE_COMPONENT_NAME_STRING =
            DomainSelectionResolver.PACKAGE_NAME_NONE + "/" + CLASS_NAME;
    private static final ComponentName NONE_COMPONENT_NAME =
            ComponentName.unflattenFromString(NONE_COMPONENT_NAME_STRING);
    private static final String OVERRIDDEN_COMPONENT_NAME_STRING = "test/" + CLASS_NAME;
    private static final ComponentName OVERRIDDEN_COMPONENT_NAME =
            ComponentName.unflattenFromString(OVERRIDDEN_COMPONENT_NAME_STRING);
    // Mock classes
    private DomainSelectionController mDsController;
    private DomainSelectionConnection mDsConnection;
    private DomainSelectionService mDsService;

    private DomainSelectionResolver mDsResolver;

@@ -69,13 +86,11 @@ public class DomainSelectionResolverTest extends TelephonyTest {

        mDsController = Mockito.mock(DomainSelectionController.class);
        mDsConnection = Mockito.mock(DomainSelectionConnection.class);
        mDsService = Mockito.mock(DomainSelectionService.class);
    }

    @After
    public void tearDown() throws Exception {
        mDsResolver = null;
        mDsService = null;
        mDsConnection = null;
        mDsController = null;
        super.tearDown();
@@ -90,7 +105,7 @@ public class DomainSelectionResolverTest extends TelephonyTest {
            DomainSelectionResolver.getInstance();
        });

        DomainSelectionResolver.make(mContext, true);
        DomainSelectionResolver.make(mContext, COMPONENT_NAME_STRING);
        DomainSelectionResolver resolver = DomainSelectionResolver.getInstance();

        assertNotNull(resolver);
@@ -98,8 +113,8 @@ public class DomainSelectionResolverTest extends TelephonyTest {

    @Test
    @SmallTest
    public void testIsDomainSelectionSupportedWhenDeviceConfigDisabled() {
        setUpResolver(false, RADIO_HAL_VERSION_2_1);
    public void testIsDomainSelectionSupportedWhenComponentNameNotConfigured() {
        setUpResolver(null, RADIO_HAL_VERSION_2_1);

        assertFalse(mDsResolver.isDomainSelectionSupported());
    }
@@ -107,7 +122,7 @@ public class DomainSelectionResolverTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testIsDomainSelectionSupportedWhenHalVersionLessThan20() {
        setUpResolver(true, RADIO_HAL_VERSION_2_0);
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_0);

        assertFalse(mDsResolver.isDomainSelectionSupported());
    }
@@ -115,7 +130,7 @@ public class DomainSelectionResolverTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testIsDomainSelectionSupported() {
        setUpResolver(true, RADIO_HAL_VERSION_2_1);
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);

        assertTrue(mDsResolver.isDomainSelectionSupported());
    }
@@ -123,7 +138,7 @@ public class DomainSelectionResolverTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testGetDomainSelectionConnectionWhenNotInitialized() throws Exception {
        setUpResolver(true, RADIO_HAL_VERSION_2_1);
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);

        assertThrows(IllegalStateException.class, () -> {
            mDsResolver.getDomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true);
@@ -133,29 +148,36 @@ public class DomainSelectionResolverTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testGetDomainSelectionConnectionWhenPhoneNull() throws Exception {
        setUpResolver(true, RADIO_HAL_VERSION_2_1);
        mDsResolver.initialize(mDsService);
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize();
        verify(mDsController).bind(eq(DSS_COMPONENT_NAME));

        assertNull(mDsResolver.getDomainSelectionConnection(null, SELECTOR_TYPE_CALLING, true));
    }

    @Test
    @SmallTest
    public void testGetDomainSelectionConnectionWhenImsPhoneNull() throws Exception {
        setUpResolver(true, RADIO_HAL_VERSION_2_1);
        mDsResolver.initialize(mDsService);
        when(mPhone.getImsPhone()).thenReturn(null);
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize();
        verify(mDsController).bind(eq(DSS_COMPONENT_NAME));

        when(mPhone.getImsPhone()).thenReturn(null);
        assertNull(mDsResolver.getDomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true));
    }

    @Test
    @SmallTest
    public void testGetDomainSelectionConnectionWhenImsNotAvailable() throws Exception {
        setUpResolver(true, RADIO_HAL_VERSION_2_1);
        mDsResolver.initialize(mDsService);
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize();
        verify(mDsController).bind(eq(DSS_COMPONENT_NAME));

        when(mPhone.isImsAvailable()).thenReturn(false);
        when(mPhone.getImsPhone()).thenReturn(mImsPhone);

        assertNull(mDsResolver.getDomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, false));
    }

@@ -163,12 +185,13 @@ public class DomainSelectionResolverTest extends TelephonyTest {
    @SmallTest
    public void testGetDomainSelectionConnectionWhenImsNotAvailableForEmergencyCall()
            throws Exception {
        setUpResolver(true, RADIO_HAL_VERSION_2_1);
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize(mDsService);
        mDsResolver.initialize();
        verify(mDsController).bind(eq(DSS_COMPONENT_NAME));

        when(mPhone.isImsAvailable()).thenReturn(false);
        when(mPhone.getImsPhone()).thenReturn(mImsPhone);

        assertNotNull(mDsResolver.getDomainSelectionConnection(mPhone,
                SELECTOR_TYPE_CALLING, true));
    }
@@ -176,18 +199,81 @@ public class DomainSelectionResolverTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testGetDomainSelectionConnection() throws Exception {
        setUpResolver(true, RADIO_HAL_VERSION_2_1);
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize(mDsService);
        mDsResolver.initialize();
        verify(mDsController).bind(eq(DSS_COMPONENT_NAME));

        when(mPhone.isImsAvailable()).thenReturn(true);
        when(mPhone.getImsPhone()).thenReturn(mImsPhone);

        assertNotNull(mDsResolver.getDomainSelectionConnection(
                mPhone, SELECTOR_TYPE_CALLING, true));
    }

    private void setUpResolver(boolean deviceConfigEnabled, HalVersion halVersion) {
        mDsResolver = new DomainSelectionResolver(mContext, deviceConfigEnabled);
    @Test
    @SmallTest
    public void testSetDomainSelectionServiceOverride() throws Exception {
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize();
        mDsResolver.setDomainSelectionServiceOverride(OVERRIDDEN_COMPONENT_NAME);
        verify(mDsController, never()).unbind();
        verify(mDsController).bind(eq(OVERRIDDEN_COMPONENT_NAME));
    }

    @Test
    @SmallTest
    public void testSetDomainSelectionServiceOverrideWithoutInitialize() throws Exception {
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        assertFalse(mDsResolver.setDomainSelectionServiceOverride(OVERRIDDEN_COMPONENT_NAME));
        verify(mDsController, never()).bind(eq(OVERRIDDEN_COMPONENT_NAME));
    }

    @Test
    @SmallTest
    public void testSetDomainSelectionServiceOverrideWithEmptyComponentName() throws Exception {
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize();
        assertTrue(mDsResolver.setDomainSelectionServiceOverride(EMPTY_COMPONENT_NAME));
        verify(mDsController).unbind();
        verify(mDsController, never()).bind(eq(EMPTY_COMPONENT_NAME));
    }

    @Test
    @SmallTest
    public void testSetDomainSelectionServiceOverrideWithNoneComponentName() throws Exception {
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize();
        assertTrue(mDsResolver.setDomainSelectionServiceOverride(NONE_COMPONENT_NAME));
        verify(mDsController).unbind();
        verify(mDsController, never()).bind(eq(NONE_COMPONENT_NAME));
    }

    @Test
    @SmallTest
    public void testClearDomainSelectionServiceOverride() throws Exception {
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        mDsResolver.initialize();
        mDsResolver.clearDomainSelectionServiceOverride();
        verify(mDsController).unbind();
        verify(mDsController, times(2)).bind(eq(DSS_COMPONENT_NAME));
    }

    @Test
    @SmallTest
    public void testClearDomainSelectionServiceOverrideWithoutInitialize() throws Exception {
        setUpResolver(COMPONENT_NAME_STRING, RADIO_HAL_VERSION_2_1);
        setUpController();
        assertFalse(mDsResolver.clearDomainSelectionServiceOverride());
        verify(mDsController, never()).unbind();
    }

    private void setUpResolver(String flattenedComponentName, HalVersion halVersion) {
        mDsResolver = new DomainSelectionResolver(mContext, flattenedComponentName);
        when(mPhone.getHalVersion(eq(HAL_SERVICE_NETWORK))).thenReturn(halVersion);
    }

@@ -195,8 +281,7 @@ public class DomainSelectionResolverTest extends TelephonyTest {
        mDsResolver.setDomainSelectionControllerFactory(
                new DomainSelectionResolver.DomainSelectionControllerFactory() {
                    @Override
                    public DomainSelectionController create(Context context,
                            DomainSelectionService service) {
                    public DomainSelectionController create(Context context) {
                        return mDsController;
                    }
                });