Loading src/java/com/android/internal/telephony/CarrierServicesSmsFilter.java +71 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading @@ -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; Loading @@ -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( Loading @@ -69,6 +81,7 @@ public class CarrierServicesSmsFilter { mPduFormat = pduFormat; mCarrierServicesSmsFilterCallback = carrierServicesSmsFilterCallback; mLogTag = logTag; mCallbackTimeoutHandler = new CallbackTimeoutHandler(); } /** Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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; } /** Loading @@ -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) { Loading @@ -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; } Loading @@ -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); } } } Loading @@ -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); } } } } tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java +49 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading @@ -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)) Loading @@ -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()); Loading @@ -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()); Loading @@ -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( Loading Loading @@ -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); Loading @@ -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( Loading Loading
src/java/com/android/internal/telephony/CarrierServicesSmsFilter.java +71 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading @@ -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; Loading @@ -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( Loading @@ -69,6 +81,7 @@ public class CarrierServicesSmsFilter { mPduFormat = pduFormat; mCarrierServicesSmsFilterCallback = carrierServicesSmsFilterCallback; mLogTag = logTag; mCallbackTimeoutHandler = new CallbackTimeoutHandler(); } /** Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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; } /** Loading @@ -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) { Loading @@ -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; } Loading @@ -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); } } } Loading @@ -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); } } } }
tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java +49 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading @@ -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)) Loading @@ -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()); Loading @@ -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()); Loading @@ -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( Loading Loading @@ -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); Loading @@ -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( Loading