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