1 /* 2 * Copyright (C) 2014 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.cts; 18 19 import static android.app.AppOpsManager.MODE_ALLOWED; 20 import static android.app.AppOpsManager.MODE_IGNORED; 21 import static android.app.AppOpsManager.OPSTR_READ_PHONE_STATE; 22 import static android.telephony.CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL; 23 import static android.telephony.CarrierConfigManager.KEY_CARRIER_NAME_STRING; 24 import static android.telephony.CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL; 25 import static android.telephony.ServiceState.STATE_IN_SERVICE; 26 27 import static androidx.test.InstrumentationRegistry.getContext; 28 import static androidx.test.InstrumentationRegistry.getInstrumentation; 29 30 import static com.android.compatibility.common.util.AppOpsUtils.setOpMode; 31 import static com.android.internal.telephony.TelephonyIntents.EXTRA_SPN; 32 import static com.android.internal.telephony.TelephonyIntents.SPN_STRINGS_UPDATED_ACTION; 33 34 import static org.junit.Assert.assertEquals; 35 import static org.junit.Assert.assertFalse; 36 import static org.junit.Assert.assertNotNull; 37 import static org.junit.Assert.assertTrue; 38 import static org.junit.Assert.fail; 39 40 import android.app.UiAutomation; 41 import android.content.BroadcastReceiver; 42 import android.content.Context; 43 import android.content.Intent; 44 import android.content.IntentFilter; 45 import android.net.ConnectivityManager; 46 import android.os.Looper; 47 import android.os.PersistableBundle; 48 import android.platform.test.annotations.SecurityTest; 49 import android.telephony.CarrierConfigManager; 50 import android.telephony.SubscriptionManager; 51 import android.telephony.TelephonyManager; 52 53 import com.android.compatibility.common.util.TestThread; 54 55 import org.junit.After; 56 import org.junit.Before; 57 import org.junit.Test; 58 59 import java.io.IOException; 60 61 public class CarrierConfigManagerTest { 62 63 private static final String CARRIER_NAME_OVERRIDE = "carrier_a"; 64 private CarrierConfigManager mConfigManager; 65 private TelephonyManager mTelephonyManager; 66 private static final int TOLERANCE = 2000; 67 private final Object mLock = new Object(); 68 69 @Before 70 public void setUp() throws Exception { 71 mTelephonyManager = (TelephonyManager) 72 getContext().getSystemService(Context.TELEPHONY_SERVICE); 73 mConfigManager = (CarrierConfigManager) 74 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 75 } 76 77 @After 78 public void tearDown() throws Exception { 79 try { 80 setOpMode("android.telephony.cts", OPSTR_READ_PHONE_STATE, MODE_ALLOWED); 81 } catch (IOException e) { 82 fail(); 83 } 84 } 85 86 /** 87 * Checks whether the telephony stack should be running on this device. 88 * 89 * Note: "Telephony" means only SMS/MMS and voice calls in some contexts, but we also care if 90 * the device supports cellular data. 91 */ 92 private boolean hasTelephony() { 93 ConnectivityManager mgr = 94 (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); 95 return mgr.isNetworkSupported(ConnectivityManager.TYPE_MOBILE); 96 } 97 98 private boolean isSimCardPresent() { 99 return mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE && 100 mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_UNKNOWN && 101 mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_ABSENT; 102 } 103 104 private boolean isSimCardAbsent() { 105 return mTelephonyManager.getSimState() == TelephonyManager.SIM_STATE_ABSENT; 106 } 107 108 private void checkConfig(PersistableBundle config) { 109 if (config == null) { 110 assertFalse("Config should only be null when telephony is not running.", hasTelephony()); 111 return; 112 } 113 assertNotNull("CarrierConfigManager should not return null config", config); 114 if (isSimCardAbsent()) { 115 // Static default in CarrierConfigManager will be returned when no sim card present. 116 assertEquals("Config doesn't match static default.", 117 config.getBoolean(CarrierConfigManager.KEY_ADDITIONAL_CALL_SETTING_BOOL), true); 118 119 assertEquals("KEY_VVM_DESTINATION_NUMBER_STRING doesn't match static default.", 120 config.getString(CarrierConfigManager.KEY_VVM_DESTINATION_NUMBER_STRING), ""); 121 assertEquals("KEY_VVM_PORT_NUMBER_INT doesn't match static default.", 122 config.getInt(CarrierConfigManager.KEY_VVM_PORT_NUMBER_INT), 0); 123 assertEquals("KEY_VVM_TYPE_STRING doesn't match static default.", 124 config.getString(CarrierConfigManager.KEY_VVM_TYPE_STRING), ""); 125 assertEquals("KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN doesn't match static default.", 126 config.getBoolean(CarrierConfigManager.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL), 127 false); 128 assertEquals("KEY_VVM_PREFETCH_BOOLEAN doesn't match static default.", 129 config.getBoolean(CarrierConfigManager.KEY_VVM_PREFETCH_BOOL), true); 130 assertEquals("KEY_CARRIER_VVM_PACKAGE_NAME_STRING doesn't match static default.", 131 config.getString(CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING), ""); 132 assertFalse(CarrierConfigManager.isConfigForIdentifiedCarrier(config)); 133 } 134 } 135 136 @Test 137 public void testGetConfig() { 138 PersistableBundle config = mConfigManager.getConfig(); 139 checkConfig(config); 140 } 141 142 @SecurityTest 143 @Test 144 public void testRevokePermission() { 145 PersistableBundle config; 146 147 try { 148 setOpMode("android.telephony.cts", OPSTR_READ_PHONE_STATE, MODE_IGNORED); 149 } catch (IOException e) { 150 fail(); 151 } 152 153 config = mConfigManager.getConfig(); 154 assertTrue(config.isEmptyParcel()); 155 156 try { 157 setOpMode("android.telephony.cts", OPSTR_READ_PHONE_STATE, MODE_ALLOWED); 158 } catch (IOException e) { 159 fail(); 160 } 161 162 config = mConfigManager.getConfig(); 163 checkConfig(config); 164 } 165 166 @Test 167 public void testGetConfigForSubId() { 168 PersistableBundle config = 169 mConfigManager.getConfigForSubId(SubscriptionManager.getDefaultSubscriptionId()); 170 checkConfig(config); 171 } 172 173 /** 174 * Tests the CarrierConfigManager.notifyConfigChangedForSubId() API. This makes a call to 175 * notifyConfigChangedForSubId() API and expects a SecurityException since the test apk is not signed 176 * by certificate on the SIM. 177 */ 178 @Test 179 public void testNotifyConfigChangedForSubId() { 180 try { 181 if (isSimCardPresent()) { 182 mConfigManager.notifyConfigChangedForSubId( 183 SubscriptionManager.getDefaultSubscriptionId()); 184 fail("Expected SecurityException. App doesn't have carrier privileges."); 185 } 186 } catch (SecurityException expected) { 187 } 188 } 189 190 /** 191 * This checks that {@link CarrierConfigManager#overrideConfig(int, PersistableBundle)} 192 * correctly overrides the Carrier Name (SPN) string. 193 */ 194 @Test 195 public void testCarrierConfigNameOverride() throws Exception { 196 if (!isSimCardPresent() 197 || mTelephonyManager.getServiceState().getState() != STATE_IN_SERVICE) { 198 return; 199 } 200 201 // Adopt shell permission so the required permission (android.permission.MODIFY_PHONE_STATE) 202 // is granted. 203 UiAutomation ui = getInstrumentation().getUiAutomation(); 204 ui.adoptShellPermissionIdentity(); 205 206 int subId = SubscriptionManager.getDefaultSubscriptionId(); 207 TestThread t = new TestThread(new Runnable() { 208 @Override 209 public void run() { 210 Looper.prepare(); 211 212 PersistableBundle carrierNameOverride = new PersistableBundle(3); 213 carrierNameOverride.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, true); 214 carrierNameOverride.putBoolean(KEY_FORCE_HOME_NETWORK_BOOL, true); 215 carrierNameOverride.putString(KEY_CARRIER_NAME_STRING, CARRIER_NAME_OVERRIDE); 216 mConfigManager.overrideConfig(subId, carrierNameOverride); 217 218 Looper.loop(); 219 } 220 }); 221 222 try { 223 BroadcastReceiver spnBroadcastReceiver = new BroadcastReceiver() { 224 @Override 225 public void onReceive(Context context, Intent intent) { 226 if (CARRIER_NAME_OVERRIDE.equals(intent.getStringExtra(EXTRA_SPN))) { 227 synchronized (mLock) { 228 mLock.notify(); 229 } 230 } 231 } 232 }; 233 234 getContext().registerReceiver( 235 spnBroadcastReceiver, 236 new IntentFilter(SPN_STRINGS_UPDATED_ACTION)); 237 238 synchronized (mLock) { 239 t.start(); 240 mLock.wait(TOLERANCE); // wait for SPN broadcast 241 } 242 243 assertEquals(CARRIER_NAME_OVERRIDE, mTelephonyManager.getSimOperatorName()); 244 } finally { 245 mConfigManager.overrideConfig(subId, null); 246 ui.dropShellPermissionIdentity(); 247 } 248 } 249 } 250