CdmaInboundSmsHandlerTest.java revision 578df6250b7ca57ba044753b4bc62ad002cd8d40
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.test.mock.MockContentResolver; 29import android.test.suitebuilder.annotation.MediumTest; 30 31import com.android.internal.telephony.InboundSmsHandler; 32import com.android.internal.telephony.SmsStorageMonitor; 33import com.android.internal.telephony.TelephonyTest; 34import com.android.internal.telephony.cdma.sms.SmsEnvelope; 35import com.android.internal.telephony.gsm.GsmInboundSmsHandlerTest; 36import com.android.internal.util.IState; 37import com.android.internal.util.StateMachine; 38 39import org.junit.After; 40import org.junit.Before; 41import org.junit.Test; 42import org.mockito.ArgumentCaptor; 43import org.mockito.Mock; 44 45import java.lang.reflect.Field; 46import java.lang.reflect.Method; 47 48import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 49import static org.junit.Assert.assertEquals; 50import static org.junit.Assert.assertFalse; 51import static org.junit.Assert.fail; 52import static org.mockito.Matchers.any; 53import static org.mockito.Mockito.anyBoolean; 54import static org.mockito.Mockito.anyInt; 55import static org.mockito.Mockito.doReturn; 56import static org.mockito.Mockito.never; 57import static org.mockito.Mockito.times; 58import static org.mockito.Mockito.verify; 59 60public class CdmaInboundSmsHandlerTest extends TelephonyTest { 61 @Mock 62 private SmsStorageMonitor mSmsStorageMonitor; 63 @Mock 64 private android.telephony.SmsMessage mSmsMessage; 65 @Mock 66 private SmsMessage mCdmaSmsMessage; 67 68 private CdmaInboundSmsHandler mCdmaInboundSmsHandler; 69 private SmsEnvelope mSmsEnvelope = new SmsEnvelope(); 70 private ContentValues mInboundSmsTrackerCV = new ContentValues(); 71 72 private class CdmaInboundSmsHandlerTestHandler extends HandlerThread { 73 74 private CdmaInboundSmsHandlerTestHandler(String name) { 75 super(name); 76 } 77 78 @Override 79 public void onLooperPrepared() { 80 mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(mContext, 81 mSmsStorageMonitor, mPhone, null); 82 setReady(true); 83 } 84 } 85 86 private IState getCurrentState() { 87 try { 88 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 89 method.setAccessible(true); 90 return (IState) method.invoke(mCdmaInboundSmsHandler); 91 } catch (Exception e) { 92 fail(e.toString()); 93 return null; 94 } 95 } 96 97 @Before 98 public void setUp() throws Exception { 99 super.setUp("CdmaInboundSmsHandlerTest"); 100 101 Field field = SmsMessage.class.getDeclaredField("mEnvelope"); 102 field.setAccessible(true); 103 field.set(mCdmaSmsMessage, mSmsEnvelope); 104 105 UserManager userManager = (UserManager) mContextFixture.getTestDouble(). 106 getSystemService(Context.USER_SERVICE); 107 doReturn(true).when(userManager).isUserUnlocked(); 108 109 try { 110 doReturn(new int[]{UserHandle.USER_SYSTEM}).when(mIActivityManager).getRunningUserIds(); 111 } catch (RemoteException re) { 112 fail("Unexpected RemoteException: " + re.getStackTrace()); 113 } 114 115 byte[] smsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF}; 116 mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage; 117 doReturn(smsPdu).when(mCdmaSmsMessage).getPdu(); 118 119 doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean()); 120 doReturn(true).when(mSmsStorageMonitor).isStorageAvailable(); 121 doReturn(1).when(mInboundSmsTracker).getMessageCount(); 122 doReturn(-1).when(mInboundSmsTracker).getDestPort(); 123 doReturn(mInboundSmsTrackerCV).when(mInboundSmsTracker).getContentValues(); 124 doReturn(smsPdu).when(mInboundSmsTracker).getPdu(); 125 126 GsmInboundSmsHandlerTest.FakeSmsContentProvider contentProvider = 127 new GsmInboundSmsHandlerTest.FakeSmsContentProvider(); 128 ((MockContentResolver)mContext.getContentResolver()).addProvider( 129 Telephony.Sms.CONTENT_URI.getAuthority(), contentProvider); 130 131 new CdmaInboundSmsHandlerTestHandler(TAG).start(); 132 waitUntilReady(); 133 } 134 135 @After 136 public void tearDown() throws Exception { 137 // wait for wakelock to be released; timeout at 10s 138 int i = 0; 139 while (mCdmaInboundSmsHandler.getWakeLock().isHeld() && i < 100) { 140 waitForMs(100); 141 i++; 142 } 143 assertFalse(mCdmaInboundSmsHandler.getWakeLock().isHeld()); 144 mCdmaInboundSmsHandler = null; 145 super.tearDown(); 146 } 147 148 private void transitionFromStartupToIdle() { 149 // verify initially in StartupState 150 assertEquals("StartupState", getCurrentState().getName()); 151 152 // trigger transition to IdleState 153 mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_START_ACCEPTING_SMS); 154 waitForMs(50); 155 156 assertEquals("IdleState", getCurrentState().getName()); 157 } 158 159 @Test 160 @MediumTest 161 public void testNewSms() { 162 transitionFromStartupToIdle(); 163 164 // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION 165 doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService(); 166 mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, 167 new AsyncResult(null, mSmsMessage, null)); 168 waitForMs(100); 169 170 ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 171 verify(mContext).sendBroadcast(intentArgumentCaptor.capture()); 172 assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION, 173 intentArgumentCaptor.getValue().getAction()); 174 assertEquals("WaitingState", getCurrentState().getName()); 175 176 mContextFixture.sendBroadcastToOrderedBroadcastReceivers(); 177 178 intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 179 verify(mContext, times(2)).sendBroadcast(intentArgumentCaptor.capture()); 180 assertEquals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION, 181 intentArgumentCaptor.getAllValues().get(1).getAction()); 182 assertEquals("WaitingState", getCurrentState().getName()); 183 184 mContextFixture.sendBroadcastToOrderedBroadcastReceivers(); 185 waitForMs(50); 186 187 assertEquals("IdleState", getCurrentState().getName()); 188 } 189 190 @Test 191 @MediumTest 192 public void testNewSmsFromBlockedNumber_noBroadcastsSent() { 193 String blockedNumber = "123456789"; 194 doReturn(blockedNumber).when(mInboundSmsTracker).getAddress(); 195 mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber); 196 197 transitionFromStartupToIdle(); 198 199 doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService(); 200 mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, 201 new AsyncResult(null, mSmsMessage, null)); 202 waitForMs(100); 203 204 verify(mContext, never()).sendBroadcast(any(Intent.class)); 205 assertEquals("IdleState", getCurrentState().getName()); 206 } 207} 208