1 /* 2 * Copyright (C) 2020 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 package android.telephony.cts; 17 18 import static android.telephony.cts.FakeCarrierMessagingService.FAKE_MESSAGE_REF; 19 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assert.fail; 22 import static org.junit.Assume.assumeTrue; 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.eq; 25 26 import android.content.Context; 27 import android.content.pm.PackageManager; 28 import android.net.Uri; 29 import android.service.carrier.CarrierMessagingService; 30 import android.service.carrier.CarrierMessagingServiceWrapper; 31 import android.service.carrier.MessagePdu; 32 import android.telephony.SmsMessage; 33 import android.telephony.SubscriptionManager; 34 import android.telephony.TelephonyManager; 35 import android.telephony.cts.util.TelephonyUtils; 36 37 import androidx.test.InstrumentationRegistry; 38 39 import org.junit.After; 40 import org.junit.Before; 41 import org.junit.Test; 42 import org.mockito.Mock; 43 import org.mockito.Mockito; 44 import org.mockito.MockitoAnnotations; 45 46 import java.util.Arrays; 47 import java.util.Collections; 48 import java.util.List; 49 import java.util.concurrent.CompletableFuture; 50 import java.util.concurrent.ExecutionException; 51 import java.util.concurrent.TimeUnit; 52 import java.util.concurrent.TimeoutException; 53 54 /** 55 * Build, install and run the tests by running the commands below: 56 * make cts -j64 57 * cts-tradefed run cts -m CtsTelephonyTestCases --test android.telephony.cts. 58 * CarrierMessagingServiceWrapperTest 59 */ 60 public class CarrierMessagingServiceWrapperTest { 61 private TelephonyManager mTelephonyManager; 62 private int mTestSub; 63 private Context mContext; 64 private CarrierMessagingServiceWrapper mServiceWrapper; 65 private CompletableFuture<Void> mServiceReadyFuture = new CompletableFuture<>(); 66 private Runnable mOnServiceReadyCallback = () -> mServiceReadyFuture.complete(null); 67 private String mPdu = "07916164260220F0040B914151245584F600006060605130308A04D4F29C0E"; 68 private static final int TIMEOUT_IN_MS = 1000; 69 @Mock 70 private CarrierMessagingServiceWrapper.CarrierMessagingCallback mCallback; 71 getContext()72 private static Context getContext() { 73 return InstrumentationRegistry.getContext(); 74 } 75 76 @Before setUp()77 public void setUp() throws Exception { 78 assumeTrue(getContext().getPackageManager().hasSystemFeature( 79 PackageManager.FEATURE_TELEPHONY)); 80 81 MockitoAnnotations.initMocks(this); 82 mContext = getContext(); 83 mTestSub = SubscriptionManager.getDefaultSubscriptionId(); 84 mTelephonyManager = mContext.getSystemService(TelephonyManager.class) 85 .createForSubscriptionId(mTestSub); 86 } 87 88 @After tearDown()89 public void tearDown() throws Exception { 90 if (mServiceWrapper != null) mServiceWrapper.disconnect(); 91 InstrumentationRegistry.getInstrumentation().getUiAutomation() 92 .dropShellPermissionIdentity(); 93 } 94 95 /** 96 * Tests that the device properly connects to available CarrierMessagingServices. 97 */ 98 @Test testConnectToMessagingServiceWrapper()99 public void testConnectToMessagingServiceWrapper() { 100 String packageName = "android.telephony.cts"; 101 mServiceWrapper = new CarrierMessagingServiceWrapper(); 102 103 InstrumentationRegistry.getInstrumentation().getUiAutomation() 104 .adoptShellPermissionIdentity("android.permission.BIND_CARRIER_SERVICES"); 105 boolean bindResult = mServiceWrapper.bindToCarrierMessagingService( 106 mContext, packageName, Runnable::run, mOnServiceReadyCallback); 107 assertTrue(bindResult); 108 109 waitForServiceReady("Service " + packageName + " should be ready."); 110 } 111 112 @Test testCloseWrapper()113 public void testCloseWrapper() { 114 testConnectToMessagingServiceWrapper(); 115 mServiceWrapper.disconnect(); 116 try { 117 mServiceWrapper.close(); 118 fail("Should have throw an NPE on double-close"); 119 } catch (NullPointerException e) { 120 // expected 121 } finally { 122 mServiceWrapper = null; 123 } 124 } 125 126 /** 127 * Tests that the device the all CarrierMessagingServices can receive sms and 128 * triggers valid callback. 129 */ 130 @Test testReceiveSms()131 public void testReceiveSms() { 132 testConnectToMessagingServiceWrapper(); 133 134 Mockito.reset(mCallback); 135 mServiceWrapper.receiveSms(new MessagePdu(Collections.singletonList( 136 TelephonyUtils.hexStringToByteArray(mPdu))), SmsMessage.FORMAT_3GPP, -1, 137 mTestSub, Runnable::run, mCallback); 138 // Currently we just check if any result is returned. We don't test it being 139 // successful. 140 Mockito.verify(mCallback, Mockito.timeout(TIMEOUT_IN_MS)).onReceiveSmsComplete( 141 CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT); 142 } 143 144 /** 145 * Tests that the device the all CarrierMessagingServices can send text sms and 146 * triggers valid callback. 147 */ 148 @Test testSendTextSms()149 public void testSendTextSms() { 150 testConnectToMessagingServiceWrapper(); 151 152 String destAddress = getPhoneNumber(); 153 154 Mockito.reset(mCallback); 155 mServiceWrapper.sendTextSms("Testing CarrierMessagingService#sendTextSms", mTestSub, 156 destAddress, 0, Runnable::run, mCallback); 157 // Currently we just check if any result is returned. We don't test it being 158 // successful. 159 Mockito.verify(mCallback, Mockito.timeout(TIMEOUT_IN_MS)).onSendSmsComplete( 160 CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT, FAKE_MESSAGE_REF); 161 } 162 163 /** 164 * Tests that the device the all CarrierMessagingServices can send data sms and 165 * triggers valid callback. 166 */ 167 @Test testSendDataSms()168 public void testSendDataSms() { 169 testConnectToMessagingServiceWrapper(); 170 171 String destAddress = getPhoneNumber(); 172 173 Mockito.reset(mCallback); 174 mServiceWrapper.sendDataSms(TelephonyUtils.hexStringToByteArray( 175 "0123abcABC"), mTestSub, 176 destAddress, -1, 0, Runnable::run, mCallback); 177 // Currently we just check if any result is returned. We don't test it being 178 // successful. 179 Mockito.verify(mCallback, Mockito.timeout(TIMEOUT_IN_MS)).onSendSmsComplete( 180 CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT, FAKE_MESSAGE_REF); 181 } 182 183 /** 184 * Tests that the device the all CarrierMessagingServices can send multipart sms and 185 * triggers valid callback. 186 */ 187 @Test testSendMultipartTextSms()188 public void testSendMultipartTextSms() { 189 testConnectToMessagingServiceWrapper(); 190 191 String destAddress = getPhoneNumber(); 192 193 List<String> multipartTextSms = Arrays.asList( 194 "Testing CarrierMessagingService#sendMultipartTextSms#part1", 195 "Testing CarrierMessagingService#sendMultipartTextSms#part2"); 196 197 Mockito.reset(mCallback); 198 mServiceWrapper.sendMultipartTextSms(multipartTextSms, mTestSub, 199 destAddress, 0, Runnable::run, mCallback); 200 // Currently we just check if any result is returned. We don't test it being 201 // successful. 202 Mockito.verify(mCallback, Mockito.timeout(TIMEOUT_IN_MS)).onSendMultipartSmsComplete( 203 eq(CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT), 204 eq(new int[] {FAKE_MESSAGE_REF})); 205 } 206 207 /** 208 * Tests that the device the all CarrierMessagingServices can send data sms and 209 * triggers valid callback. 210 */ 211 @Test testDownloadMms()212 public void testDownloadMms() { 213 testConnectToMessagingServiceWrapper(); 214 Uri fakeUri = Uri.parse("fakeUriString"); 215 216 Mockito.reset(mCallback); 217 mServiceWrapper.downloadMms(fakeUri, mTestSub, fakeUri, Runnable::run, mCallback); 218 // Currently we just check if any result is returned. We don't test it being 219 // successful. 220 Mockito.verify(mCallback, Mockito.timeout(TIMEOUT_IN_MS)).onDownloadMmsComplete( 221 CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT); 222 } 223 224 /** 225 * Tests that the device the all CarrierMessagingServices can send mms and 226 * triggers valid callback. 227 */ 228 @Test testSendMms()229 public void testSendMms() { 230 testConnectToMessagingServiceWrapper(); 231 Uri fakeUri = Uri.parse("fakeUriString"); 232 233 Mockito.reset(mCallback); 234 mServiceWrapper.sendMms(fakeUri, mTestSub, fakeUri, Runnable::run, mCallback); 235 // Currently we just check if any result is returned. We don't test it being 236 // successful. 237 Mockito.verify(mCallback, Mockito.timeout(TIMEOUT_IN_MS)).onSendMmsComplete( 238 eq(CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT), any()); 239 } 240 isServiceReady()241 private boolean isServiceReady() { 242 return (mServiceReadyFuture != null && mServiceReadyFuture.isDone()); 243 } 244 245 private String mPhoneNumber; 246 getPhoneNumber()247 private String getPhoneNumber() { 248 if (mPhoneNumber == null) mPhoneNumber = mTelephonyManager.getLine1Number(); 249 return mPhoneNumber; 250 } 251 waitForServiceReady(String failMessage)252 private void waitForServiceReady(String failMessage) { 253 try { 254 mServiceReadyFuture.get(CarrierMessagingServiceWrapperTest.TIMEOUT_IN_MS, 255 TimeUnit.MILLISECONDS); 256 } catch (InterruptedException | ExecutionException e) { 257 assertTrue(isServiceReady()); 258 } catch (TimeoutException e) { 259 fail(failMessage + " within " 260 + CarrierMessagingServiceWrapperTest.TIMEOUT_IN_MS + " ms."); 261 } 262 } 263 } 264