Home | History | Annotate | Download | only in cts
      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