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; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertNull; 21import static org.junit.Assert.assertTrue; 22import static org.mockito.Matchers.any; 23import static org.mockito.Matchers.anyString; 24import static org.mockito.Matchers.isNull; 25import static org.mockito.Mockito.anyInt; 26import static org.mockito.Mockito.doReturn; 27import static org.mockito.Mockito.verify; 28import static org.mockito.Mockito.eq; 29import static org.mockito.Mockito.times; 30 31import android.app.ActivityManagerNative; 32import android.app.PendingIntent; 33import android.content.BroadcastReceiver; 34import android.content.Context; 35import android.content.Intent; 36import android.content.IntentFilter; 37import android.os.HandlerThread; 38import android.os.Message; 39import android.test.suitebuilder.annotation.SmallTest; 40import android.util.Singleton; 41 42import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 43 44import org.junit.After; 45import org.junit.Before; 46import org.junit.Test; 47import org.mockito.ArgumentCaptor; 48import org.mockito.Mock; 49 50public class ImsSMSDispatcherTest extends TelephonyTest { 51 @Mock 52 private SMSDispatcher.SmsTracker mTracker; 53 54 private ImsSMSDispatcher mImsSmsDispatcher; 55 private ImsSmsDispatcherTestHandler mImsSmsDispatcherTestHandler; 56 private boolean mReceivedTestIntent = false; 57 private Object mLock = new Object(); 58 private static final String TEST_INTENT = "com.android.internal.telephony.TEST_INTENT"; 59 private BroadcastReceiver mTestReceiver = new BroadcastReceiver() { 60 @Override 61 public void onReceive(Context context, Intent intent) { 62 logd("onReceive"); 63 synchronized (mLock) { 64 mReceivedTestIntent = true; 65 } 66 } 67 }; 68 69 private class ImsSmsDispatcherTestHandler extends HandlerThread { 70 71 private ImsSmsDispatcherTestHandler(String name) { 72 super(name); 73 } 74 75 @Override 76 public void onLooperPrepared() { 77 mImsSmsDispatcher = new ImsSMSDispatcher(mPhone, mSmsStorageMonitor, 78 mSmsUsageMonitor); 79 //Initial state of RIL is power on, need to wait util RADIO_ON msg get handled 80 waitForMs(200); 81 setReady(true); 82 } 83 } 84 85 @Before 86 public void setUp() throws Exception { 87 super.setUp(getClass().getSimpleName()); 88 setupMockPackagePermissionChecks(); 89 90 mImsSmsDispatcherTestHandler = new ImsSmsDispatcherTestHandler(getClass().getSimpleName()); 91 mImsSmsDispatcherTestHandler.start(); 92 waitUntilReady(); 93 } 94 95 @After 96 public void tearDown() throws Exception { 97 mImsSmsDispatcher = null; 98 mImsSmsDispatcherTestHandler.quitSafely(); 99 super.tearDown(); 100 } 101 102 @Test @SmallTest 103 public void testSmsHandleStateUpdate() throws Exception { 104 assertEquals(SmsConstants.FORMAT_UNKNOWN, mImsSmsDispatcher.getImsSmsFormat()); 105 //Mock ImsNetWorkStateChange with GSM phone type 106 switchImsSmsFormat(PhoneConstants.PHONE_TYPE_GSM); 107 assertEquals(SmsConstants.FORMAT_3GPP, mImsSmsDispatcher.getImsSmsFormat()); 108 assertTrue(mImsSmsDispatcher.isIms()); 109 110 //Mock ImsNetWorkStateChange with Cdma Phone type 111 switchImsSmsFormat(PhoneConstants.PHONE_TYPE_CDMA); 112 assertEquals(SmsConstants.FORMAT_3GPP2, mImsSmsDispatcher.getImsSmsFormat()); 113 assertTrue(mImsSmsDispatcher.isIms()); 114 } 115 116 @Test @SmallTest 117 public void testSendImsGmsTest() throws Exception { 118 switchImsSmsFormat(PhoneConstants.PHONE_TYPE_GSM); 119 mImsSmsDispatcher.sendText("111"/* desAddr*/, "222" /*scAddr*/, TAG, 120 null, null, null, null, false); 121 verify(mSimulatedCommandsVerifier).sendImsGsmSms(eq("038122f2"), 122 eq("0100038111f1000014c9f67cda9c12d37378983e4697e5d4f29c0e"), eq(0), eq(0), 123 any(Message.class)); 124 } 125 126 @Test @SmallTest 127 public void testSendImsGmsTestWithOutDesAddr() throws Exception { 128 switchImsSmsFormat(PhoneConstants.PHONE_TYPE_GSM); 129 mImsSmsDispatcher.sendText(null, "222" /*scAddr*/, TAG, 130 null, null, null, null, false); 131 verify(mSimulatedCommandsVerifier, times(0)).sendImsGsmSms(anyString(), anyString(), 132 anyInt(), anyInt(), any(Message.class)); 133 } 134 135 @Test @SmallTest 136 public void testSendImsCdmaTest() throws Exception { 137 switchImsSmsFormat(PhoneConstants.PHONE_TYPE_CDMA); 138 mImsSmsDispatcher.sendText("111"/* desAddr*/, "222" /*scAddr*/, TAG, 139 null, null, null, null, false); 140 verify(mSimulatedCommandsVerifier).sendImsCdmaSms((byte[])any(), eq(0), eq(0), 141 any(Message.class)); 142 } 143 144 @Test @SmallTest 145 public void testSendRetrySmsCdmaTest() throws Exception { 146 // newFormat will be based on voice technology 147 ArgumentCaptor<byte[]> captor = ArgumentCaptor.forClass(byte[].class); 148 switchImsSmsFormat(PhoneConstants.PHONE_TYPE_CDMA); 149 replaceInstance(SMSDispatcher.SmsTracker.class, "mFormat", mTracker, 150 SmsConstants.FORMAT_3GPP2); 151 doReturn(PhoneConstants.PHONE_TYPE_CDMA).when(mPhone).getPhoneType(); 152 mImsSmsDispatcher.sendRetrySms(mTracker); 153 verify(mSimulatedCommandsVerifier).sendImsCdmaSms(captor.capture(), eq(0), eq(0), 154 any(Message.class)); 155 assertEquals(1, captor.getAllValues().size()); 156 assertNull(captor.getAllValues().get(0)); 157 } 158 159 @Test @SmallTest 160 public void testSendRetrySmsGsmTest() throws Exception { 161 // newFormat will be based on voice technology will be GSM if phone type is not CDMA 162 switchImsSmsFormat(PhoneConstants.PHONE_TYPE_GSM); 163 replaceInstance(SMSDispatcher.SmsTracker.class, "mFormat", mTracker, 164 SmsConstants.FORMAT_3GPP); 165 mImsSmsDispatcher.sendRetrySms(mTracker); 166 verify(mSimulatedCommandsVerifier).sendImsGsmSms((String)isNull(), (String)isNull(), eq(0), 167 eq(0), any(Message.class)); 168 } 169 170 @Test @SmallTest 171 public void testInjectNullSmsPdu() throws Exception { 172 // unmock ActivityManager to be able to register receiver, create real PendingIntent and 173 // receive TEST_INTENT 174 restoreInstance(Singleton.class, "mInstance", mIActivityManagerSingleton); 175 restoreInstance(ActivityManagerNative.class, "gDefault", null); 176 177 Context realContext = TestApplication.getAppContext(); 178 realContext.registerReceiver(mTestReceiver, new IntentFilter(TEST_INTENT)); 179 180 PendingIntent pendingIntent = PendingIntent.getBroadcast(realContext, 0, 181 new Intent(TEST_INTENT), 0); 182 183 // inject null sms pdu. This should cause intent to be received since pdu is null. 184 mImsSmsDispatcher.injectSmsPdu(null, SmsConstants.FORMAT_3GPP, pendingIntent); 185 waitForMs(100); 186 synchronized (mLock) { 187 assertEquals(true, mReceivedTestIntent); 188 } 189 } 190 191 private void switchImsSmsFormat(int phoneType) { 192 mSimulatedCommands.setImsRegistrationState(new int[]{1, phoneType}); 193 mSimulatedCommands.notifyImsNetworkStateChanged(); 194 /* wait for async msg get handled */ 195 waitForMs(200); 196 } 197}