1 /* 2 * Copyright (C) 2019 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 17 package android.telephony.ims.cts; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.content.pm.ResolveInfo; 23 import android.service.carrier.CarrierService; 24 import android.telephony.SubscriptionInfo; 25 import android.telephony.SubscriptionManager; 26 import android.telephony.TelephonyManager; 27 28 import androidx.test.platform.app.InstrumentationRegistry; 29 30 import com.android.compatibility.common.util.ShellIdentityUtils; 31 32 import java.util.List; 33 import java.util.concurrent.Callable; 34 35 public class ImsUtils { 36 public static final boolean VDBG = false; 37 38 // ImsService rebind has an exponential backoff capping at 64 seconds. Wait for 70 seconds to 39 // allow for the new poll to happen in the framework. 40 public static final int TEST_TIMEOUT_MS = 70000; 41 42 // Id for non compressed auto configuration xml. 43 public static final int ITEM_NON_COMPRESSED = 2000; 44 // Id for compressed auto configuration xml. 45 public static final int ITEM_COMPRESSED = 2001; 46 shouldTestImsService()47 public static boolean shouldTestImsService() { 48 final PackageManager pm = InstrumentationRegistry.getInstrumentation().getContext() 49 .getPackageManager(); 50 boolean hasTelephony = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY); 51 boolean hasIms = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS); 52 return hasTelephony && hasIms; 53 } 54 getPreferredActiveSubId()55 public static int getPreferredActiveSubId() { 56 Context context = InstrumentationRegistry.getInstrumentation().getContext(); 57 SubscriptionManager sm = (SubscriptionManager) context.getSystemService( 58 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 59 List<SubscriptionInfo> infos = ShellIdentityUtils.invokeMethodWithShellPermissions(sm, 60 SubscriptionManager::getActiveSubscriptionInfoList); 61 62 int defaultSubId = SubscriptionManager.getDefaultVoiceSubscriptionId(); 63 if (defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID 64 && isSubIdInInfoList(infos, defaultSubId)) { 65 return defaultSubId; 66 } 67 68 defaultSubId = SubscriptionManager.getDefaultSubscriptionId(); 69 if (defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID 70 && isSubIdInInfoList(infos, defaultSubId)) { 71 return defaultSubId; 72 } 73 74 // Couldn't resolve a default. We can try to resolve a default using the active 75 // subscriptions. 76 if (!infos.isEmpty()) { 77 return infos.get(0).getSubscriptionId(); 78 } 79 // There must be at least one active subscription. 80 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 81 } 82 isSubIdInInfoList(List<SubscriptionInfo> infos, int subId)83 private static boolean isSubIdInInfoList(List<SubscriptionInfo> infos, int subId) { 84 return infos.stream().anyMatch(info -> info.getSubscriptionId() == subId); 85 } 86 87 /** 88 * If a carrier app implements CarrierMessagingService it can choose to take care of handling 89 * SMS OTT so SMS over IMS APIs won't be triggered which would be WAI so we do not run the tests 90 * if there exist a carrier app that declares a CarrierMessagingService 91 */ shouldRunSmsImsTests(int subId)92 public static boolean shouldRunSmsImsTests(int subId) { 93 if (!shouldTestImsService()) { 94 return false; 95 } 96 Context context = InstrumentationRegistry.getInstrumentation().getContext(); 97 TelephonyManager tm = 98 (TelephonyManager) InstrumentationRegistry.getInstrumentation().getContext() 99 .getSystemService(Context.TELEPHONY_SERVICE); 100 tm = tm.createForSubscriptionId(subId); 101 List<String> carrierPackages = tm.getCarrierPackageNamesForIntent( 102 new Intent(CarrierService.CARRIER_SERVICE_INTERFACE)); 103 104 if (carrierPackages == null || carrierPackages.size() == 0) { 105 return true; 106 } 107 final PackageManager packageManager = context.getPackageManager(); 108 Intent intent = new Intent("android.service.carrier.CarrierMessagingService"); 109 List<ResolveInfo> resolveInfos = packageManager.queryIntentServices(intent, 0); 110 for (ResolveInfo info : resolveInfos) { 111 if (carrierPackages.contains(info.serviceInfo.packageName)) { 112 return false; 113 } 114 } 115 116 return true; 117 } 118 119 /** 120 * Retry every 5 seconds until the condition is true or fail after TEST_TIMEOUT_MS seconds. 121 */ retryUntilTrue(Callable<Boolean> condition)122 public static boolean retryUntilTrue(Callable<Boolean> condition) throws Exception { 123 int retryCounter = 0; 124 while (retryCounter < (TEST_TIMEOUT_MS / 5000)) { 125 try { 126 Boolean isSuccessful = condition.call(); 127 isSuccessful = (isSuccessful == null) ? false : isSuccessful; 128 if (isSuccessful) return true; 129 } catch (Exception e) { 130 // we will retry 131 } 132 Thread.sleep(5000); 133 retryCounter++; 134 } 135 return false; 136 } 137 } 138