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

Commit fe6f1e75 authored by ashastry's avatar ashastry Committed by Gerrit Code Review
Browse files

Merge "Unit tests for carrier SMS filtering."

parents 84869eee 311e8950
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import android.service.carrier.MessagePdu;
import android.telephony.CarrierMessagingServiceManager;
import android.telephony.CarrierMessagingServiceManager;
import android.telephony.Rlog;
import android.telephony.Rlog;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccController;


@@ -53,7 +54,8 @@ public class CarrierServicesSmsFilter {
    private final CarrierServicesSmsFilterCallbackInterface mCarrierServicesSmsFilterCallback;
    private final CarrierServicesSmsFilterCallbackInterface mCarrierServicesSmsFilterCallback;
    private final String mLogTag;
    private final String mLogTag;


    CarrierServicesSmsFilter(
    @VisibleForTesting
    public CarrierServicesSmsFilter(
            Context context,
            Context context,
            int phoneId,
            int phoneId,
            int subId,
            int subId,
@@ -75,7 +77,8 @@ public class CarrierServicesSmsFilter {
    /**
    /**
     * @return {@code true} if the SMS was handled by carrier services.
     * @return {@code true} if the SMS was handled by carrier services.
     */
     */
    boolean filter() {
    @VisibleForTesting
    public boolean filter() {
        Optional<String> carrierAppForFiltering = getCarrierAppPackageForFiltering();
        Optional<String> carrierAppForFiltering = getCarrierAppPackageForFiltering();
        List<String> smsFilterPackages = new ArrayList<>();
        List<String> smsFilterPackages = new ArrayList<>();
        if (carrierAppForFiltering.isPresent()) {
        if (carrierAppForFiltering.isPresent()) {
@@ -161,7 +164,8 @@ public class CarrierServicesSmsFilter {
    /**
    /**
     * Result of filtering SMS is returned in this callback.
     * Result of filtering SMS is returned in this callback.
     */
     */
    interface CarrierServicesSmsFilterCallbackInterface {
    @VisibleForTesting
    public interface CarrierServicesSmsFilterCallbackInterface {
        void onFilterComplete(int result);
        void onFilterComplete(int result);
    }
    }


+177 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.RemoteException;
import android.service.carrier.CarrierMessagingService;
import android.service.carrier.ICarrierMessagingCallback;
import android.service.carrier.ICarrierMessagingService;
import android.service.carrier.MessagePdu;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.internal.telephony.uicc.UiccCard;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.util.ArrayList;
import java.util.List;

/**
 * Tests SMS filtering by carrier services.
 */
public class CarrierServicesSmsFilterTest extends TelephonyTest {
    private static final byte[] SMS_PDU = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
    private static final String CARRIER_APP_PACKAGE_NAME = "com.android.carrier";
    private static final String SYSTEM_APP_PACKAGE_NAME = "com.android.system";

    private CarrierServicesSmsFilter mCarrierServicesSmsFilterUT;
    @Mock
    private CarrierServicesSmsFilter.CarrierServicesSmsFilterCallbackInterface mFilterCallback;
    @Mock
    private UiccCard mUiccCard;
    @Mock
    private ICarrierMessagingService.Stub mICarrierAppMessagingService;
    @Mock
    private ICarrierMessagingService.Stub mISystemCarrierMessagingService;

    @Before
    public void setUp() throws Exception {
        super.setUp(getClass().getSimpleName());
        mCarrierServicesSmsFilterUT = new CarrierServicesSmsFilter(
                mContext, mPhone.getPhoneId(), mPhone.getSubId(), new byte[][]{SMS_PDU},
                0, null, mFilterCallback, getClass().getSimpleName());
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    @SmallTest
    public void testFilter_noCarrierServicesFilter_notHandled() throws Exception {
        assertFalse(mCarrierServicesSmsFilterUT.filter());
    }

    @Test
    @SmallTest
    public void testFilter_carrierAppPresent_handled() throws Exception {
        mockCarrierApp();
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mICarrierAppMessagingService);
        assertTrue(mCarrierServicesSmsFilterUT.filter());

        verify(mFilterCallback, timeout(100))
                .onFilterComplete(eq(CarrierMessagingService.RECEIVE_OPTIONS_DROP));
    }

    @Test
    @SmallTest
    public void testFilter_systemAppPresent_handled() throws Exception {
        mockSystemApp();
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mISystemCarrierMessagingService);

        assertTrue(mCarrierServicesSmsFilterUT.filter());

        verify(mFilterCallback, timeout(100))
                .onFilterComplete(eq(CarrierMessagingService.RECEIVE_OPTIONS_DROP));
    }

    @Test
    @SmallTest
    public void testFilter_bothCarrierAndSystemAppPresent_carrierAppDecides() throws Exception {
        mockCarrierApp();
        mockSystemApp();
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT, mICarrierAppMessagingService);
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mISystemCarrierMessagingService);

        assertTrue(mCarrierServicesSmsFilterUT.filter());

        verify(mFilterCallback, timeout(100))
                .onFilterComplete(eq(CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT));
    }

    private void mockCarrierApp()
            throws RemoteException {
        mContextFixture.addService(
                CarrierMessagingService.SERVICE_INTERFACE,
                new ComponentName(CARRIER_APP_PACKAGE_NAME, "CarrierAppFilterClass"),
                CARRIER_APP_PACKAGE_NAME,
                mICarrierAppMessagingService,
                new ServiceInfo());
        mockUiccWithCarrierApp();
    }

    private void mockUiccWithCarrierApp() {
        when(mUiccController.getUiccCard(mPhone.getPhoneId())).thenReturn(mUiccCard);
        List<String> carrierPackages = new ArrayList<>();
        carrierPackages.add(CARRIER_APP_PACKAGE_NAME);
        when(mUiccCard.getCarrierPackageNamesForIntent(
                any(PackageManager.class), any(Intent.class))).thenReturn(carrierPackages);
    }

    private void mockSystemApp() {
        ServiceInfo serviceInfo = new ServiceInfo();
        serviceInfo.packageName = SYSTEM_APP_PACKAGE_NAME;
        mContextFixture.addService(
                CarrierMessagingService.SERVICE_INTERFACE,
                new ComponentName(SYSTEM_APP_PACKAGE_NAME, "SystemFilterClass"),
                SYSTEM_APP_PACKAGE_NAME,
                mISystemCarrierMessagingService,
                serviceInfo);
    }

    private void mockCarrierAppStubResults(final int result, ICarrierMessagingService.Stub stub)
            throws RemoteException {
        when(stub.queryLocalInterface(anyString())).thenReturn(stub);
        when(stub.asBinder()).thenReturn(stub);
        doAnswer(new Answer<Void>() {
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                Object[] args = invocation.getArguments();
                ICarrierMessagingCallback callback = (ICarrierMessagingCallback) args[4];
                callback.onFilterComplete(result);
                return null;
            }
        }).when(stub).filterSms(
                any(MessagePdu.class), anyString(), anyInt(), anyInt(),
                any(ICarrierMessagingCallback.class));
    }
}
+27 −19
Original line number Original line Diff line number Diff line
@@ -16,12 +16,14 @@


package com.android.internal.telephony;
package com.android.internal.telephony;


import com.google.common.collect.ArrayListMultimap;
import static org.mockito.Mockito.any;
import com.google.common.collect.Multimap;
import static org.mockito.Mockito.anyInt;

import static org.mockito.Mockito.doAnswer;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.doReturn;
import org.mockito.invocation.InvocationOnMock;
import static org.mockito.Mockito.eq;
import org.mockito.stubbing.Answer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;


import android.app.AlarmManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.AppOpsManager;
@@ -63,6 +65,13 @@ import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.test.mock.MockContext;
import android.util.Log;
import android.util.Log;


import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collection;
@@ -72,15 +81,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Locale;
import java.util.Map;
import java.util.Map;


import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

/**
/**
 * Controls a test {@link Context} as would be provided by the Android framework to an
 * Controls a test {@link Context} as would be provided by the Android framework to an
 * {@code Activity}, {@code Service} or other system-instantiated component.
 * {@code Activity}, {@code Service} or other system-instantiated component.
@@ -181,8 +181,12 @@ public class ContextFixture implements TestFixture<Context> {
            }
            }
            IInterface service = mServiceByComponentName.get(serviceIntent.getComponent());
            IInterface service = mServiceByComponentName.get(serviceIntent.getComponent());
            if (service == null) {
            if (service == null) {
                throw new RuntimeException("ServiceConnection not found: "
                service = mServiceByPackageName.get(serviceIntent.getPackage());
                        + serviceIntent.getComponent());
            }
            if (service == null) {
                throw new RuntimeException(
                        String.format("ServiceConnection not found for component: %s, package: %s",
                                serviceIntent.getComponent(), serviceIntent.getPackage()));
            }
            }
            mServiceByServiceConnection.put(connection, service);
            mServiceByServiceConnection.put(connection, service);
            connection.onServiceConnected(serviceIntent.getComponent(), service.asBinder());
            connection.onServiceConnected(serviceIntent.getComponent(), service.asBinder());
@@ -444,6 +448,8 @@ public class ContextFixture implements TestFixture<Context> {
            ArrayListMultimap.create();
            ArrayListMultimap.create();
    private final Map<ComponentName, IInterface> mServiceByComponentName =
    private final Map<ComponentName, IInterface> mServiceByComponentName =
            new HashMap<ComponentName, IInterface>();
            new HashMap<ComponentName, IInterface>();
    private final Map<String, IInterface> mServiceByPackageName =
            new HashMap<String, IInterface>();
    private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName =
    private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName =
            new HashMap<ComponentName, ServiceInfo>();
            new HashMap<ComponentName, ServiceInfo>();
    private final Map<IInterface, ComponentName> mComponentNameByService =
    private final Map<IInterface, ComponentName> mComponentNameByService =
@@ -553,9 +559,11 @@ public class ContextFixture implements TestFixture<Context> {
        return mBundle;
        return mBundle;
    }
    }


    private void addService(String action, ComponentName name, IInterface service) {
    public void addService(String action, ComponentName name, String packageName,
                           IInterface service, ServiceInfo serviceInfo) {
        mComponentNamesByAction.put(action, name);
        mComponentNamesByAction.put(action, name);
        mServiceByComponentName.put(name, service);
        mServiceInfoByComponentName.put(name, serviceInfo);
        mServiceByPackageName.put(packageName, service);
        mComponentNameByService.put(service, name);
        mComponentNameByService.put(service, name);
    }
    }