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

Commit 1a8df66f authored by Nazanin Bakhshi's avatar Nazanin Bakhshi Committed by Gerrit Code Review
Browse files

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

parents a7422413 48cbe777
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(