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