CdmaInboundSmsHandlerTest.java revision a8857077b00d6c2856b3335a62ac43ae5403c142
1/* 2 * Copyright (C) 2015 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.BroadcastReceiver; 20import android.content.Context; 21import android.content.Intent; 22import android.os.AsyncResult; 23import android.os.Bundle; 24import android.os.Handler; 25import android.os.HandlerThread; 26import android.os.IBinder; 27import android.os.IDeviceIdleController; 28import android.os.ServiceManager; 29import android.os.UserHandle; 30import android.provider.Telephony; 31import android.telephony.*; 32import android.test.suitebuilder.annotation.SmallTest; 33import android.util.Log; 34 35import com.android.internal.telephony.CommandsInterface; 36import com.android.internal.telephony.ContextFixture; 37import com.android.internal.telephony.GsmCdmaPhone; 38import com.android.internal.telephony.InboundSmsHandler; 39import com.android.internal.telephony.Phone; 40import com.android.internal.telephony.SmsBroadcastUndelivered; 41import com.android.internal.telephony.SmsMessageBase; 42import com.android.internal.telephony.SmsStorageMonitor; 43import com.android.internal.telephony.TelephonyComponentFactory; 44import com.android.internal.telephony.TelephonyTestUtils; 45import com.android.internal.telephony.cdma.sms.SmsEnvelope; 46import com.android.internal.telephony.test.SimulatedCommands; 47import com.android.internal.telephony.uicc.UiccController; 48import com.android.internal.util.IState; 49import com.android.internal.util.StateMachine; 50 51import static org.junit.Assert.*; 52import static org.mockito.Mockito.*; 53 54import org.junit.After; 55import org.junit.Before; 56import org.junit.Test; 57import org.mockito.ArgumentCaptor; 58import org.mockito.InjectMocks; 59import org.mockito.Mock; 60import org.mockito.MockitoAnnotations; 61import org.mockito.Spy; 62 63import java.lang.reflect.Field; 64import java.lang.reflect.Method; 65import java.util.List; 66 67public class CdmaInboundSmsHandlerTest { 68 private static final String TAG = "CdmaInboundSmsHandlerTest"; 69 70 @Mock 71 private SmsStorageMonitor mSmsStorageMonitor; 72 @Mock 73 private Phone mPhone; 74 @Mock 75 private android.telephony.SmsMessage mSmsMessage; 76 @Mock 77 private SmsMessage mCdmaSmsMessage; 78 @Mock 79 private UiccController mUiccController; 80 @Mock 81 private IDeviceIdleController mIDeviceIdleController; 82 @Mock 83 private TelephonyComponentFactory mTelephonyComponentFactory; 84 85 private CdmaInboundSmsHandler mCdmaInboundSmsHandler; 86 private ContextFixture mContextFixture; 87 private SimulatedCommands mSimulatedCommands; 88 private TelephonyManager mTelephonyManager; 89 private SmsEnvelope mSmsEnvelope = new SmsEnvelope(); 90 91 private Object mLock = new Object(); 92 private boolean mReady; 93 94 private class CdmaInboundSmsHandlerTestHandler extends HandlerThread { 95 96 private CdmaInboundSmsHandlerTestHandler(String name) { 97 super(name); 98 } 99 100 @Override 101 public void onLooperPrepared() { 102 synchronized (mLock) { 103 mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler( 104 mContextFixture.getTestDouble(), mSmsStorageMonitor, mPhone, null); 105 mReady = true; 106 } 107 } 108 } 109 110 private void waitUntilReady() { 111 while(true) { 112 synchronized (mLock) { 113 if (mReady) { 114 break; 115 } 116 } 117 } 118 } 119 120 private IState getCurrentState() { 121 try { 122 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 123 method.setAccessible(true); 124 return (IState) method.invoke(mCdmaInboundSmsHandler); 125 } catch (Exception e) { 126 fail(e.toString()); 127 return null; 128 } 129 } 130 131 @Before 132 public void setUp() throws Exception { 133 MockitoAnnotations.initMocks(this); 134 135 //Use reflection to mock singletons 136 Field field = UiccController.class.getDeclaredField("mInstance"); 137 field.setAccessible(true); 138 field.set(null, mUiccController); 139 140 field = TelephonyComponentFactory.class.getDeclaredField("sInstance"); 141 field.setAccessible(true); 142 field.set(null, mTelephonyComponentFactory); 143 144 field = SmsMessage.class.getDeclaredField("mEnvelope"); 145 field.setAccessible(true); 146 field.set(mCdmaSmsMessage, mSmsEnvelope); 147 148 mContextFixture = new ContextFixture(); 149 mSimulatedCommands = new SimulatedCommands(); 150 mPhone.mCi = mSimulatedCommands; 151 152 mTelephonyManager = TelephonyManager.from(mContextFixture.getTestDouble()); 153 doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean()); 154 doReturn(true).when(mSmsStorageMonitor).isStorageAvailable(); 155 doReturn(mIDeviceIdleController).when(mTelephonyComponentFactory). 156 getIDeviceIdleController(); 157 158 mReady = false; 159 new CdmaInboundSmsHandlerTestHandler(TAG).start(); 160 waitUntilReady(); 161 } 162 163 @After 164 public void tearDown() throws Exception { 165 mCdmaInboundSmsHandler = null; 166 } 167 168 @Test @SmallTest 169 public void testNewSms() { 170 // verify initially in StartupState 171 assertEquals("StartupState", getCurrentState().getName()); 172 173 // start SmsBroadcastUndelivered thread to trigger transition to IdleState 174 SmsBroadcastUndelivered.initialize(mContextFixture.getTestDouble(), null, 175 mCdmaInboundSmsHandler); 176 TelephonyTestUtils.waitForMs(50); 177 178 assertEquals("IdleState", getCurrentState().getName()); 179 180 // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION 181 byte[] smsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF}; 182 mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage; 183 doReturn(smsPdu).when(mCdmaSmsMessage).getPdu(); 184 doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService(); 185 mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, 186 new AsyncResult(null, mSmsMessage, null)); 187 TelephonyTestUtils.waitForMs(100); 188 189 ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 190 verify(mContextFixture.getTestDouble(), times(2)). 191 sendBroadcast(intentArgumentCaptor.capture()); 192 193 List<Intent> list = intentArgumentCaptor.getAllValues(); 194 /* logd("list.size() " + list.size()); 195 for (int i = 0; i < list.size(); i++) { 196 logd("list.get(i) " + list.get(i)); 197 } */ 198 //todo: seems to be some issue with ArgumentCaptor. Both DELIVER and RECEIVED broadcasts 199 //can be seen in logs but according to list both are RECEIVED 200 //assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION, 201 // list.get(0).getAction()); 202 boolean smsReceivedAction = false; 203 for (Intent i : list) { 204 if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(i.getAction())) { 205 smsReceivedAction = true; 206 break; 207 } 208 } 209 assertTrue(smsReceivedAction); 210 211 assertEquals("IdleState", getCurrentState().getName()); 212 } 213 214 private static void logd(String s) { 215 Log.d(TAG, s); 216 } 217} 218