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

Commit 6a2f17ee authored by ashastry's avatar ashastry Committed by android-build-merger
Browse files

Merge "Unit tests for carrier SMS filtering."

am: fe6f1e75

Change-Id: I33bb1131d1a51c63a2815fd4ecb4ade9ce5ba055
parents e168cc75 fe6f1e75
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.service.carrier.MessagePdu;
import android.telephony.CarrierMessagingServiceManager;
import android.telephony.Rlog;

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

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

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

+177 −0
Original line number 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 Diff line number Diff line
@@ -16,12 +16,14 @@

package com.android.internal.telephony;

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 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;

import android.app.AlarmManager;
import android.app.AppOpsManager;
@@ -63,6 +65,13 @@ import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
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.Arrays;
import java.util.Collection;
@@ -72,15 +81,6 @@ import java.util.List;
import java.util.Locale;
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
 * {@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());
            if (service == null) {
                throw new RuntimeException("ServiceConnection not found: "
                        + serviceIntent.getComponent());
                service = mServiceByPackageName.get(serviceIntent.getPackage());
            }
            if (service == null) {
                throw new RuntimeException(
                        String.format("ServiceConnection not found for component: %s, package: %s",
                                serviceIntent.getComponent(), serviceIntent.getPackage()));
            }
            mServiceByServiceConnection.put(connection, service);
            connection.onServiceConnected(serviceIntent.getComponent(), service.asBinder());
@@ -444,6 +448,8 @@ public class ContextFixture implements TestFixture<Context> {
            ArrayListMultimap.create();
    private final Map<ComponentName, IInterface> mServiceByComponentName =
            new HashMap<ComponentName, IInterface>();
    private final Map<String, IInterface> mServiceByPackageName =
            new HashMap<String, IInterface>();
    private final Map<ComponentName, ServiceInfo> mServiceInfoByComponentName =
            new HashMap<ComponentName, ServiceInfo>();
    private final Map<IInterface, ComponentName> mComponentNameByService =
@@ -553,9 +559,11 @@ public class ContextFixture implements TestFixture<Context> {
        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);
        mServiceByComponentName.put(name, service);
        mServiceInfoByComponentName.put(name, serviceInfo);
        mServiceByPackageName.put(packageName, service);
        mComponentNameByService.put(service, name);
    }