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