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

Commit 7ff5b78e authored by Nazanin Bakhshi's avatar Nazanin Bakhshi Committed by android-build-merger
Browse files

Merge "FilterSms in carrierSmsFilter should timeout if onFilterComplete() callback is not received"

am: 1a8df66f

Change-Id: Id9ef40be5d3ea78020ce2b6375840d48c0b9dcdb
parents 5e31456d 1a8df66f
Loading
Loading
Loading
Loading
+71 −5
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.service.carrier.CarrierMessagingService;
import android.service.carrier.ICarrierMessagingCallback;
@@ -35,8 +37,10 @@ import com.android.internal.telephony.uicc.UiccController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * Filters incoming SMS with carrier services.
@@ -44,6 +48,11 @@ import java.util.Optional;
 */
public class CarrierServicesSmsFilter {
    protected static final boolean DBG = true;
    /** onFilterComplete is not called. */
    public static final int EVENT_ON_FILTER_COMPLETE_NOT_CALLED = 1;

    /** onFilterComplete timeout. */
    public static final int FILTER_COMPLETE_TIMEOUT_MS = 60000; //10 minutes

    private final Context mContext;
    private final Phone mPhone;
@@ -52,6 +61,9 @@ public class CarrierServicesSmsFilter {
    private final String mPduFormat;
    private final CarrierServicesSmsFilterCallbackInterface mCarrierServicesSmsFilterCallback;
    private final String mLogTag;
    private final CallbackTimeoutHandler mCallbackTimeoutHandler;
    private FilterAggregator mFilterAggregator;


    @VisibleForTesting
    public CarrierServicesSmsFilter(
@@ -69,6 +81,7 @@ public class CarrierServicesSmsFilter {
        mPduFormat = pduFormat;
        mCarrierServicesSmsFilterCallback = carrierServicesSmsFilterCallback;
        mLogTag = logTag;
        mCallbackTimeoutHandler = new CallbackTimeoutHandler();
    }

    /**
@@ -86,9 +99,19 @@ public class CarrierServicesSmsFilter {
        if (carrierImsPackage != null) {
            smsFilterPackages.add(carrierImsPackage);
        }
        FilterAggregator filterAggregator = new FilterAggregator(smsFilterPackages.size());

        if (mFilterAggregator != null) {
            String errMsg = "Cannot reuse the same CarrierServiceSmsFilter object for filtering.";
            loge(errMsg);
            throw new RuntimeException(errMsg);
        }

        mFilterAggregator = new FilterAggregator(smsFilterPackages.size());
        //start the timer
        mCallbackTimeoutHandler.sendMessageDelayed(mCallbackTimeoutHandler
                .obtainMessage(EVENT_ON_FILTER_COMPLETE_NOT_CALLED), FILTER_COMPLETE_TIMEOUT_MS);
        for (String smsFilterPackage : smsFilterPackages) {
            filterWithPackage(smsFilterPackage, filterAggregator);
            filterWithPackage(smsFilterPackage, mFilterAggregator);
        }
        boolean handled = smsFilterPackages.size() > 0;
        return handled;
@@ -127,6 +150,8 @@ public class CarrierServicesSmsFilter {
        CarrierSmsFilter smsFilter = new CarrierSmsFilter(mPdus, mDestPort, mPduFormat);
        CarrierSmsFilterCallback smsFilterCallback =
                new CarrierSmsFilterCallback(filterAggregator, smsFilter);
        filterAggregator.addToCallbacks(smsFilterCallback);

        smsFilter.filterSms(packageName, smsFilterCallback);
    }

@@ -228,11 +253,13 @@ public class CarrierServicesSmsFilter {
    private final class CarrierSmsFilterCallback extends ICarrierMessagingCallback.Stub {
        private final FilterAggregator mFilterAggregator;
        private final CarrierMessagingServiceManager mCarrierMessagingServiceManager;
        private boolean mIsOnFilterCompleteCalled;

        CarrierSmsFilterCallback(FilterAggregator filterAggregator,
                CarrierMessagingServiceManager carrierMessagingServiceManager) {
            mFilterAggregator = filterAggregator;
            mCarrierMessagingServiceManager = carrierMessagingServiceManager;
            mIsOnFilterCompleteCalled = false;
        }

        /**
@@ -240,9 +267,14 @@ public class CarrierServicesSmsFilter {
         */
        @Override
        public void onFilterComplete(int result) {
            // in the case that timeout has already passed and triggered, but the initial callback
            // is run afterwards, we should not follow through
            if (!mIsOnFilterCompleteCalled) {
                mIsOnFilterCompleteCalled = true;
                mCarrierMessagingServiceManager.disposeConnection(mContext);
                mFilterAggregator.onFilterComplete(result);
            }
        }

        @Override
        public void onSendSmsComplete(int result, int messageRef) {
@@ -268,10 +300,12 @@ public class CarrierServicesSmsFilter {
    private final class FilterAggregator {
        private final Object mFilterLock = new Object();
        private int mNumPendingFilters;
        private final Set<CarrierSmsFilterCallback> mCallbacks;
        private int mFilterResult;

        FilterAggregator(int numFilters) {
            mNumPendingFilters = numFilters;
            mCallbacks = new HashSet<>();
            mFilterResult = CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT;
        }

@@ -289,6 +323,9 @@ public class CarrierServicesSmsFilter {
                        // return back to the CarrierMessagingService, restore the calling identity.
                        Binder.restoreCallingIdentity(token);
                    }
                    //all onFilterCompletes called before timeout has triggered
                    //remove the pending message
                    mCallbackTimeoutHandler.removeMessages(EVENT_ON_FILTER_COMPLETE_NOT_CALLED);
                }
            }
        }
@@ -296,5 +333,34 @@ public class CarrierServicesSmsFilter {
        private void combine(int result) {
            mFilterResult = mFilterResult | result;
        }

        private void addToCallbacks(CarrierSmsFilterCallback callback) {
            mCallbacks.add(callback);
        }

    }

    protected final class CallbackTimeoutHandler extends Handler {

        private static final boolean DBG = true;

        @Override
        public void handleMessage(Message msg) {
            if (DBG) {
                log("CallbackTimeoutHandler handleMessage(" + msg.what + ")");
            }

            switch(msg.what) {
                case EVENT_ON_FILTER_COMPLETE_NOT_CALLED:
                    handleFilterCallbacksTimeout();
                    break;
            }
        }

        private void handleFilterCallbacksTimeout() {
            for (CarrierSmsFilterCallback callback : mFilterAggregator.mCallbacks) {
                callback.onFilterComplete(CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT);
            }
        }
    }
}
+49 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ 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.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@@ -31,6 +32,7 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.Looper;
import android.os.RemoteException;
import android.service.carrier.CarrierMessagingService;
import android.service.carrier.ICarrierMessagingCallback;
@@ -71,9 +73,14 @@ public class CarrierServicesSmsFilterTest extends TelephonyTest {
    @Before
    public void setUp() throws Exception {
        super.setUp(getClass().getSimpleName());
        if (Looper.myLooper() == null) {
            Looper.prepare();
            Looper.loop();
        }
        mCarrierServicesSmsFilterUT = new CarrierServicesSmsFilter(
                mContext, mPhone, new byte[][]{SMS_PDU},
                0, "3gpp", mFilterCallback, getClass().getSimpleName());
                0, "3gpp", mFilterCallback, getClass().getSimpleName()
        );
    }

    @After
@@ -92,7 +99,8 @@ public class CarrierServicesSmsFilterTest extends TelephonyTest {
    public void testFilter_carrierAppPresent_handled() throws Exception {
        mockCarrierApp();
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mICarrierAppMessagingService);
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mICarrierAppMessagingService,
                true);
        assertTrue(mCarrierServicesSmsFilterUT.filter());

        verify(mFilterCallback, timeout(100))
@@ -104,7 +112,8 @@ public class CarrierServicesSmsFilterTest extends TelephonyTest {
    public void testFilter_systemAppPresent_handled() throws Exception {
        mockSystemApp();
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mISystemCarrierMessagingService);
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mISystemCarrierMessagingService,
                true);

        assertTrue(mCarrierServicesSmsFilterUT.filter());

@@ -118,9 +127,11 @@ public class CarrierServicesSmsFilterTest extends TelephonyTest {
        mockCarrierApp();
        mockSystemApp();
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT, mICarrierAppMessagingService);
                CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT, mICarrierAppMessagingService,
                true);
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mISystemCarrierMessagingService);
                CarrierMessagingService.RECEIVE_OPTIONS_DROP, mISystemCarrierMessagingService,
                true);

        assertTrue(mCarrierServicesSmsFilterUT.filter());

@@ -128,6 +139,34 @@ public class CarrierServicesSmsFilterTest extends TelephonyTest {
                .onFilterComplete(eq(CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT));
    }

    @Test
    public void testFilterSmsShouldNotTimeout_whenOnFilterCompleteCalled() throws Exception {
        //This will make sure mCarrierServicesSmsFilterUT.filter() will return true, and therefore
        // filterSms() will return true
        mockCarrierApp();
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT, mICarrierAppMessagingService,
                true);
        assertTrue(mCarrierServicesSmsFilterUT.filter());

        verify(mFilterCallback, times(1))
                .onFilterComplete(eq(CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT));
    }

    @Test
    public void testFilterSmsShouldTimeout_whenOnFilterCompleteNotCalled() throws Exception {
        //This will make sure mCarrierServicesSmsFilterUT.filter() will return true, and therefore
        // filterSms() will return true
        mockCarrierApp();
        mockCarrierAppStubResults(
                CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT, mICarrierAppMessagingService,
                false);
        assertTrue(mCarrierServicesSmsFilterUT.filter());

        verify(mFilterCallback, times(0))
                .onFilterComplete(anyInt());
    }

    private void mockCarrierApp()
            throws RemoteException {
        mContextFixture.addService(
@@ -158,7 +197,8 @@ public class CarrierServicesSmsFilterTest extends TelephonyTest {
                serviceInfo);
    }

    private void mockCarrierAppStubResults(final int result, ICarrierMessagingService.Stub stub)
    private void mockCarrierAppStubResults(final int result, ICarrierMessagingService.Stub stub,
            boolean callOnFilterComplete)
            throws RemoteException {
        when(stub.queryLocalInterface(anyString())).thenReturn(stub);
        when(stub.asBinder()).thenReturn(stub);
@@ -167,7 +207,9 @@ public class CarrierServicesSmsFilterTest extends TelephonyTest {
            public Void answer(InvocationOnMock invocation) throws Throwable {
                Object[] args = invocation.getArguments();
                ICarrierMessagingCallback callback = (ICarrierMessagingCallback) args[4];
                if (callOnFilterComplete) {
                    callback.onFilterComplete(result);
                }
                return null;
            }
        }).when(stub).filterSms(