Loading src/java/com/android/internal/telephony/CarrierServicesSmsFilter.java +7 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,13 @@ import java.util.Set; /** * Filters incoming SMS with carrier services. * * <p>A new instance must be created for filtering each message. * * <p>Note that if a carrier services app is unavailable at the time a message is received because * credential-encrypted storage is unavailable and it is not direct-boot aware, and the message ends * up being handled by a filter further down the chain, that message will not be redelivered to the * carrier app once the user unlocks the storage. */ public class CarrierServicesSmsFilter { protected static final boolean DBG = true; Loading src/java/com/android/internal/telephony/InboundSmsHandler.java +22 −12 Original line number Diff line number Diff line Loading @@ -187,8 +187,10 @@ public abstract class InboundSmsHandler extends StateMachine { // The notitfication tag used when showing a notification. The combination of notification tag // and notification id should be unique within the phone app. private static final String NOTIFICATION_TAG = "InboundSmsHandler"; private static final int NOTIFICATION_ID_NEW_MESSAGE = 1; @VisibleForTesting public static final String NOTIFICATION_TAG = "InboundSmsHandler"; @VisibleForTesting public static final int NOTIFICATION_ID_NEW_MESSAGE = 1; /** URI for raw table of SMS provider. */ protected static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); Loading Loading @@ -987,7 +989,8 @@ public abstract class InboundSmsHandler extends StateMachine { tracker, (isWapPush ? new byte[][] {output.toByteArray()} : pdus), destPort, resultReceiver); resultReceiver, block); } if (isWapPush) { Loading Loading @@ -1045,7 +1048,7 @@ public abstract class InboundSmsHandler extends StateMachine { * @return true if an ordered broadcast was sent to the carrier app; false otherwise. */ private boolean processMessagePartWithUserLocked(InboundSmsTracker tracker, byte[][] pdus, int destPort, SmsBroadcastReceiver resultReceiver) { byte[][] pdus, int destPort, SmsBroadcastReceiver resultReceiver, boolean block) { log("Credential-encrypted storage not available. Port: " + destPort); if (destPort == SmsHeader.PORT_WAP_PUSH && mWapPush.isWapPushForMms(pdus[0], this)) { showNewMessageNotification(); Loading @@ -1055,14 +1058,15 @@ public abstract class InboundSmsHandler extends StateMachine { // This is a regular SMS - hand it to the carrier or system app for filtering. boolean filterInvoked = filterSms( pdus, destPort, tracker, resultReceiver, false /* userUnlocked */, false /* block */); block); if (filterInvoked) { // filter invoked, wait for it to return the result. return true; } else { // filter not invoked, show the notification and do nothing further. } else if (!block) { // filter not invoked and message not blocked, show the notification and do nothing // further. Even if the message is blocked, we keep it in the database so it can be // reprocessed by filters once credential-encrypted storage is available. showNewMessageNotification(); return false; } } return false; Loading Loading @@ -1664,10 +1668,16 @@ public abstract class InboundSmsHandler extends StateMachine { } // Now that all filters have been invoked, drop the message if it is blocked. // TODO(b/156910035): Remove mUserUnlocked once we stop showing the new message // notification for blocked numbers. if (mUserUnlocked && mBlock) { if (mBlock) { // Only delete the message if the user is unlocked. Otherwise, we should reprocess // the message after unlock so the filter has a chance to run while credential- // encrypted storage is available. if (mUserUnlocked) { dropFilteredSms(mTracker, mSmsBroadcastReceiver, mBlock); } else { // Just complete handling of the message without dropping it. sendMessage(EVENT_BROADCAST_COMPLETE); } return; } Loading tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java +57 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.ContentValues; import android.content.Context; Loading Loading @@ -378,6 +380,61 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { verifySmsFiltersInvoked(times(1)); } @Test @MediumTest public void testNewSmsWithUserLocked_notificationShown() { // user locked UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); doReturn(false).when(userManager).isUserUnlocked(); transitionFromStartupToIdle(); sendNewSms(); verify(mContext, never()).sendBroadcast(any(Intent.class)); assertEquals("IdleState", getCurrentState().getName()); // Filter should be invoked. verifySmsFiltersInvoked(times(1)); // New message notification should be shown. NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); verify(notificationManager).notify( eq(InboundSmsHandler.NOTIFICATION_TAG), eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE), any(Notification.class)); } @Test @MediumTest public void testNewSmsFromBlockedNumberWithUserLocked_noNotificationShown() { String blockedNumber = "1234567890"; mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber); // user locked UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); doReturn(false).when(userManager).isUserUnlocked(); transitionFromStartupToIdle(); sendNewSms(); verify(mContext, never()).sendBroadcast(any(Intent.class)); assertEquals("IdleState", getCurrentState().getName()); // Filter should be invoked. verifySmsFiltersInvoked(times(1)); // No new message notification should be shown. NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); verify(notificationManager, never()).notify( eq(InboundSmsHandler.NOTIFICATION_TAG), eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE), any(Notification.class)); } @Test @MediumTest public void testNewSms_filterInvoked_noBroadcastsSent() { Loading Loading
src/java/com/android/internal/telephony/CarrierServicesSmsFilter.java +7 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,13 @@ import java.util.Set; /** * Filters incoming SMS with carrier services. * * <p>A new instance must be created for filtering each message. * * <p>Note that if a carrier services app is unavailable at the time a message is received because * credential-encrypted storage is unavailable and it is not direct-boot aware, and the message ends * up being handled by a filter further down the chain, that message will not be redelivered to the * carrier app once the user unlocks the storage. */ public class CarrierServicesSmsFilter { protected static final boolean DBG = true; Loading
src/java/com/android/internal/telephony/InboundSmsHandler.java +22 −12 Original line number Diff line number Diff line Loading @@ -187,8 +187,10 @@ public abstract class InboundSmsHandler extends StateMachine { // The notitfication tag used when showing a notification. The combination of notification tag // and notification id should be unique within the phone app. private static final String NOTIFICATION_TAG = "InboundSmsHandler"; private static final int NOTIFICATION_ID_NEW_MESSAGE = 1; @VisibleForTesting public static final String NOTIFICATION_TAG = "InboundSmsHandler"; @VisibleForTesting public static final int NOTIFICATION_ID_NEW_MESSAGE = 1; /** URI for raw table of SMS provider. */ protected static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); Loading Loading @@ -987,7 +989,8 @@ public abstract class InboundSmsHandler extends StateMachine { tracker, (isWapPush ? new byte[][] {output.toByteArray()} : pdus), destPort, resultReceiver); resultReceiver, block); } if (isWapPush) { Loading Loading @@ -1045,7 +1048,7 @@ public abstract class InboundSmsHandler extends StateMachine { * @return true if an ordered broadcast was sent to the carrier app; false otherwise. */ private boolean processMessagePartWithUserLocked(InboundSmsTracker tracker, byte[][] pdus, int destPort, SmsBroadcastReceiver resultReceiver) { byte[][] pdus, int destPort, SmsBroadcastReceiver resultReceiver, boolean block) { log("Credential-encrypted storage not available. Port: " + destPort); if (destPort == SmsHeader.PORT_WAP_PUSH && mWapPush.isWapPushForMms(pdus[0], this)) { showNewMessageNotification(); Loading @@ -1055,14 +1058,15 @@ public abstract class InboundSmsHandler extends StateMachine { // This is a regular SMS - hand it to the carrier or system app for filtering. boolean filterInvoked = filterSms( pdus, destPort, tracker, resultReceiver, false /* userUnlocked */, false /* block */); block); if (filterInvoked) { // filter invoked, wait for it to return the result. return true; } else { // filter not invoked, show the notification and do nothing further. } else if (!block) { // filter not invoked and message not blocked, show the notification and do nothing // further. Even if the message is blocked, we keep it in the database so it can be // reprocessed by filters once credential-encrypted storage is available. showNewMessageNotification(); return false; } } return false; Loading Loading @@ -1664,10 +1668,16 @@ public abstract class InboundSmsHandler extends StateMachine { } // Now that all filters have been invoked, drop the message if it is blocked. // TODO(b/156910035): Remove mUserUnlocked once we stop showing the new message // notification for blocked numbers. if (mUserUnlocked && mBlock) { if (mBlock) { // Only delete the message if the user is unlocked. Otherwise, we should reprocess // the message after unlock so the filter has a chance to run while credential- // encrypted storage is available. if (mUserUnlocked) { dropFilteredSms(mTracker, mSmsBroadcastReceiver, mBlock); } else { // Just complete handling of the message without dropping it. sendMessage(EVENT_BROADCAST_COMPLETE); } return; } Loading
tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java +57 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.ContentValues; import android.content.Context; Loading Loading @@ -378,6 +380,61 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { verifySmsFiltersInvoked(times(1)); } @Test @MediumTest public void testNewSmsWithUserLocked_notificationShown() { // user locked UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); doReturn(false).when(userManager).isUserUnlocked(); transitionFromStartupToIdle(); sendNewSms(); verify(mContext, never()).sendBroadcast(any(Intent.class)); assertEquals("IdleState", getCurrentState().getName()); // Filter should be invoked. verifySmsFiltersInvoked(times(1)); // New message notification should be shown. NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); verify(notificationManager).notify( eq(InboundSmsHandler.NOTIFICATION_TAG), eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE), any(Notification.class)); } @Test @MediumTest public void testNewSmsFromBlockedNumberWithUserLocked_noNotificationShown() { String blockedNumber = "1234567890"; mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber); // user locked UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); doReturn(false).when(userManager).isUserUnlocked(); transitionFromStartupToIdle(); sendNewSms(); verify(mContext, never()).sendBroadcast(any(Intent.class)); assertEquals("IdleState", getCurrentState().getName()); // Filter should be invoked. verifySmsFiltersInvoked(times(1)); // No new message notification should be shown. NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); verify(notificationManager, never()).notify( eq(InboundSmsHandler.NOTIFICATION_TAG), eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE), any(Notification.class)); } @Test @MediumTest public void testNewSms_filterInvoked_noBroadcastsSent() { Loading