CdmaInboundSmsHandlerTest.java revision cfcdffe371d0e69631034beefc2b0995540c1824
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony.cdma; 18 19import android.content.ContentValues; 20import android.content.Context; 21import android.content.Intent; 22import android.os.AsyncResult; 23import android.os.HandlerThread; 24import android.os.RemoteException; 25import android.os.UserHandle; 26import android.os.UserManager; 27import android.provider.Telephony; 28import android.telephony.TelephonyManager; 29import android.test.mock.MockContentResolver; 30import android.test.suitebuilder.annotation.MediumTest; 31import android.test.suitebuilder.annotation.SmallTest; 32 33import com.android.internal.telephony.InboundSmsHandler; 34import com.android.internal.telephony.SmsStorageMonitor; 35import com.android.internal.telephony.TelephonyTest; 36import com.android.internal.telephony.cdma.sms.SmsEnvelope; 37import com.android.internal.telephony.gsm.GsmInboundSmsHandlerTest; 38import com.android.internal.util.IState; 39import com.android.internal.util.StateMachine; 40 41import org.junit.After; 42import org.junit.Before; 43import org.junit.Test; 44import org.mockito.ArgumentCaptor; 45import org.mockito.Mock; 46 47import java.lang.reflect.Field; 48import java.lang.reflect.Method; 49 50import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 51import static org.junit.Assert.assertEquals; 52import static org.junit.Assert.assertFalse; 53import static org.junit.Assert.fail; 54import static org.mockito.Matchers.any; 55import static org.mockito.Mockito.anyBoolean; 56import static org.mockito.Mockito.anyInt; 57import static org.mockito.Mockito.doReturn; 58import static org.mockito.Mockito.never; 59import static org.mockito.Mockito.times; 60import static org.mockito.Mockito.verify; 61 62public class CdmaInboundSmsHandlerTest extends TelephonyTest { 63 @Mock 64 private SmsStorageMonitor mSmsStorageMonitor; 65 @Mock 66 private android.telephony.SmsMessage mSmsMessage; 67 @Mock 68 private SmsMessage mCdmaSmsMessage; 69 70 private CdmaInboundSmsHandler mCdmaInboundSmsHandler; 71 private TelephonyManager mTelephonyManager; 72 private SmsEnvelope mSmsEnvelope = new SmsEnvelope(); 73 private ContentValues mInboundSmsTrackerCV = new ContentValues(); 74 75 private class CdmaInboundSmsHandlerTestHandler extends HandlerThread { 76 77 private CdmaInboundSmsHandlerTestHandler(String name) { 78 super(name); 79 } 80 81 @Override 82 public void onLooperPrepared() { 83 mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(mContext, 84 mSmsStorageMonitor, mPhone, null); 85 setReady(true); 86 } 87 } 88 89 private IState getCurrentState() { 90 try { 91 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 92 method.setAccessible(true); 93 return (IState) method.invoke(mCdmaInboundSmsHandler); 94 } catch (Exception e) { 95 fail(e.toString()); 96 return null; 97 } 98 } 99 100 @Before 101 public void setUp() throws Exception { 102 super.setUp("CdmaInboundSmsHandlerTest"); 103 104 Field field = SmsMessage.class.getDeclaredField("mEnvelope"); 105 field.setAccessible(true); 106 field.set(mCdmaSmsMessage, mSmsEnvelope); 107 108 UserManager userManager = (UserManager) mContextFixture.getTestDouble(). 109 getSystemService(Context.USER_SERVICE); 110 doReturn(true).when(userManager).isUserUnlocked(); 111 112 try { 113 doReturn(new int[]{UserHandle.USER_SYSTEM}).when(mIActivityManager).getRunningUserIds(); 114 } catch (RemoteException re) { 115 fail("Unexpected RemoteException: " + re.getStackTrace()); 116 } 117 118 byte[] smsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF}; 119 mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage; 120 doReturn(smsPdu).when(mCdmaSmsMessage).getPdu(); 121 122 mTelephonyManager = TelephonyManager.from(mContext); 123 doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean()); 124 doReturn(true).when(mSmsStorageMonitor).isStorageAvailable(); 125 doReturn(1).when(mInboundSmsTracker).getMessageCount(); 126 doReturn(-1).when(mInboundSmsTracker).getDestPort(); 127 doReturn(mInboundSmsTrackerCV).when(mInboundSmsTracker).getContentValues(); 128 129 GsmInboundSmsHandlerTest.FakeSmsContentProvider contentProvider = 130 new GsmInboundSmsHandlerTest.FakeSmsContentProvider(); 131 ((MockContentResolver)mContext.getContentResolver()).addProvider( 132 Telephony.Sms.CONTENT_URI.getAuthority(), contentProvider); 133 134 new CdmaInboundSmsHandlerTestHandler(TAG).start(); 135 waitUntilReady(); 136 } 137 138 @After 139 public void tearDown() throws Exception { 140 // wait for wakelock to be released; timeout at 10s 141 int i = 0; 142 while (mCdmaInboundSmsHandler.getWakeLock().isHeld() && i < 100) { 143 waitForMs(100); 144 i++; 145 } 146 assertFalse(mCdmaInboundSmsHandler.getWakeLock().isHeld()); 147 mCdmaInboundSmsHandler = null; 148 super.tearDown(); 149 } 150 151 private void transitionFromStartupToIdle() { 152 // verify initially in StartupState 153 assertEquals("StartupState", getCurrentState().getName()); 154 155 // trigger transition to IdleState 156 mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_START_ACCEPTING_SMS); 157 waitForMs(50); 158 159 assertEquals("IdleState", getCurrentState().getName()); 160 } 161 162 @Test 163 @MediumTest 164 public void testNewSms() { 165 transitionFromStartupToIdle(); 166 167 // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION 168 doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService(); 169 mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, 170 new AsyncResult(null, mSmsMessage, null)); 171 waitForMs(100); 172 173 ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 174 verify(mContext).sendBroadcast(intentArgumentCaptor.capture()); 175 assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION, 176 intentArgumentCaptor.getValue().getAction()); 177 assertEquals("WaitingState", getCurrentState().getName()); 178 179 mContextFixture.sendBroadcastToOrderedBroadcastReceivers(); 180 181 intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 182 verify(mContext, times(2)).sendBroadcast(intentArgumentCaptor.capture()); 183 assertEquals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION, 184 intentArgumentCaptor.getAllValues().get(1).getAction()); 185 assertEquals("WaitingState", getCurrentState().getName()); 186 187 mContextFixture.sendBroadcastToOrderedBroadcastReceivers(); 188 waitForMs(50); 189 190 assertEquals("IdleState", getCurrentState().getName()); 191 } 192 193 @Test 194 @MediumTest 195 public void testNewSmsFromBlockedNumber_noBroadcastsSent() { 196 String blockedNumber = "123456789"; 197 doReturn(blockedNumber).when(mInboundSmsTracker).getAddress(); 198 mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber); 199 200 transitionFromStartupToIdle(); 201 202 doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService(); 203 mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, 204 new AsyncResult(null, mSmsMessage, null)); 205 waitForMs(100); 206 207 verify(mContext, never()).sendBroadcast(any(Intent.class)); 208 assertEquals("IdleState", getCurrentState().getName()); 209 } 210} 211