Always fetch dun APNs from apn db.

Also added emergency as a non-wildcardable APN type.

Test: Verified tethering manually for T-Mo and AT&T
Bug: 38186417
Change-Id: I6d0da610557f2f48bfc79a3a9015d5d01173bddf
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 10a5ec5..1faa9f2 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -543,13 +543,6 @@
     private int mSetDataProfileStatus = 0;
 
     /**
-     * Whether carrier allow user edited tether APN. Updated by carrier config
-     * KEY_EDITABLE_TETHER_APN_BOOL
-     * If true, APN with dun type from database will be used, see fetchDunApn for details.
-     */
-    private boolean mAllowUserEditTetherApn = false;
-
-    /**
      * Handles changes to the APN db.
      */
     private class ApnChangeObserver extends ContentObserver {
@@ -617,7 +610,6 @@
         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         filter.addAction(INTENT_DATA_STALL_ALARM);
         filter.addAction(INTENT_PROVISIONING_APN_ALARM);
-        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
 
         // TODO - redundent with update call below?
         mDataEnabledSettings.setUserDataEnabled(getDataEnabled());
@@ -1725,7 +1717,12 @@
         apnContext.requestLog(str);
     }
 
-    ApnSetting fetchDunApn() {
+    /**
+     * Fetch dun apn
+     * @return ApnSetting to be used for dun
+     */
+    @VisibleForTesting
+    public ApnSetting fetchDunApn() {
         if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
             log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
             return null;
@@ -1736,22 +1733,16 @@
         ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
         ApnSetting retDunSetting = null;
 
-        // Places to look for tether APN in order: TETHER_DUN_APN setting, APN database if
-        // carrier allows it, and config_tether_apndata resource.
+        // Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
+        // APN database, and config_tether_apndata resource (to be deprecated soon).
         String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
         if (!TextUtils.isEmpty(apnData)) {
             dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
             if (VDBG) log("fetchDunApn: dunCandidates from Setting: " + dunCandidates);
-        } else if (mAllowUserEditTetherApn) {
-            for (ApnSetting apn : mAllApnSettings) {
-                if (apn.canHandleType(PhoneConstants.APN_TYPE_DUN)) {
-                    dunCandidates.add(apn);
-                }
-            }
-            if (VDBG) log("fetchDunApn: dunCandidates from database: " + dunCandidates);
         }
-        // If TETHER_DUN_APN isn't set or
-        // mAllowUserEditTetherApn is true but APN database doesn't have dun APN,
+
+        // todo: remove this and config_tether_apndata after APNs are moved from overlay to apns xml
+        // If TETHER_DUN_APN isn't set or APN database doesn't have dun APN,
         // try the resource as last resort.
         if (dunCandidates.isEmpty()) {
             String[] apnArrayData = mPhone.getContext().getResources()
@@ -1766,6 +1757,17 @@
             }
         }
 
+        if (dunCandidates.isEmpty()) {
+            if (!ArrayUtils.isEmpty(mAllApnSettings)) {
+                for (ApnSetting apn : mAllApnSettings) {
+                    if (apn.canHandleType(PhoneConstants.APN_TYPE_DUN)) {
+                        dunCandidates.add(apn);
+                    }
+                }
+                if (VDBG) log("fetchDunApn: dunCandidates from database: " + dunCandidates);
+            }
+        }
+
         for (ApnSetting dunSetting : dunCandidates) {
             if (!ServiceState.bitmaskHasTech(dunSetting.bearerBitmask, bearer)) continue;
             if (dunSetting.numeric.equals(operator)) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index e57a211..1ca9acc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -50,6 +50,7 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.os.PersistableBundle;
+import android.provider.Settings;
 import android.provider.Telephony;
 import android.support.test.filters.FlakyTest;
 import android.telephony.CarrierConfigManager;
@@ -101,6 +102,7 @@
     public static final String FAKE_APN2 = "FAKE APN 2";
     public static final String FAKE_APN3 = "FAKE APN 3";
     public static final String FAKE_APN4 = "FAKE APN 4";
+    public static final String FAKE_APN5 = "FAKE APN 5";
     public static final String FAKE_IFNAME = "FAKE IFNAME";
     public static final String FAKE_PCSCF_ADDRESS = "22.33.44.55";
     public static final String FAKE_GATEWAY = "11.22.33.44";
@@ -307,6 +309,34 @@
                             ""                      // mnvo_match_data
                     });
 
+                    mc.addRow(new Object[]{
+                            2166,                   // id
+                            plmn,                   // numeric
+                            "b-mobile for Nexus",   // name
+                            FAKE_APN5,              // apn
+                            "",                     // proxy
+                            "",                     // port
+                            "",                     // mmsc
+                            "",                     // mmsproxy
+                            "",                     // mmsport
+                            "",                     // user
+                            "",                     // password
+                            -1,                     // authtype
+                            "dun",                  // types
+                            "IP",                   // protocol
+                            "IP",                   // roaming_protocol
+                            1,                      // carrier_enabled
+                            0,                      // bearer
+                            0,                      // bearer_bitmask
+                            0,                      // profile_id
+                            0,                      // modem_cognitive
+                            0,                      // max_conns
+                            0,                      // wait_time
+                            0,                      // max_conns_time
+                            0,                      // mtu
+                            "",                     // mvno_type
+                            ""                      // mnvo_match_data
+                    });
                     return mc;
                 }
             }
@@ -1108,6 +1138,31 @@
         assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
     }
 
+    // Test for fetchDunApn()
+    @Test
+    @SmallTest
+    public void testFetchDunApn() {
+        logd("Sending EVENT_RECORDS_LOADED");
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
+        waitForMs(200);
+
+        String dunApnString = "[ApnSettingV3]HOT mobile PC,pc.hotm,,,,,,,,,440,10,,DUN,,,true,"
+                + "0,,,,,,,,";
+        ApnSetting dunApnExpected = ApnSetting.fromString(dunApnString);
+
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.TETHER_DUN_APN, dunApnString);
+        // should return APN from Setting
+        ApnSetting dunApn = mDct.fetchDunApn();
+        assertTrue(dunApnExpected.equals(dunApn));
+
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.TETHER_DUN_APN, null);
+        // should return APN from db
+        dunApn = mDct.fetchDunApn();
+        assertEquals(FAKE_APN5, dunApn.apn);
+    }
+
     // Test oos
     @Test
     @SmallTest