Merge "Revert "Don't unnecessarily reevaluate tethering provisioning""
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 62fe218..e520d0c 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -249,7 +249,6 @@
                 "CarrierConfigChangeListener", mContext, smHandler, filter,
                 (Intent ignored) -> {
                     mLog.log("OBSERVED carrier config change");
-                    updateConfiguration();
                     reevaluateSimCardProvisioning();
                 });
         // TODO: Remove SimChangeListener altogether. For now, we retain it
@@ -262,35 +261,28 @@
                 });
 
         mStateReceiver = new StateReceiver();
-
-        // Load tethering configuration.
-        updateConfiguration();
-
-        startStateMachineUpdaters();
-    }
-
-    private void startStateMachineUpdaters() {
-        mCarrierConfigChange.startListening();
-
-        final Handler handler = mTetherMasterSM.getHandler();
-        IntentFilter filter = new IntentFilter();
+        filter = new IntentFilter();
         filter.addAction(UsbManager.ACTION_USB_STATE);
         filter.addAction(CONNECTIVITY_ACTION);
         filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
-        mContext.registerReceiver(mStateReceiver, filter, null, handler);
+        mContext.registerReceiver(mStateReceiver, filter, null, smHandler);
 
         filter = new IntentFilter();
         filter.addAction(Intent.ACTION_MEDIA_SHARED);
         filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
         filter.addDataScheme("file");
-        mContext.registerReceiver(mStateReceiver, filter, null, handler);
+        mContext.registerReceiver(mStateReceiver, filter, null, smHandler);
 
-        final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
-        // This check is useful only for some unit tests; example: ConnectivityServiceTest.
-        if (umi != null) {
-            umi.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
+        UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);
+
+        // this check is useful only for some unit tests; example: ConnectivityServiceTest
+        if (userManager != null) {
+            userManager.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
         }
+
+        // load device config info
+        updateConfiguration();
     }
 
     private WifiManager getWifiManager() {
@@ -392,15 +384,17 @@
      */
     @VisibleForTesting
     protected boolean isTetherProvisioningRequired() {
-        final TetheringConfiguration cfg = mConfig;
+        String[] provisionApp = mContext.getResources().getStringArray(
+                com.android.internal.R.array.config_mobile_hotspot_provision_app);
         if (mSystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false)
-                || cfg.provisioningApp.length == 0) {
+                || provisionApp == null) {
             return false;
         }
+
         if (carrierConfigAffirmsEntitlementCheckNotRequired()) {
             return false;
         }
-        return (cfg.provisioningApp.length == 2);
+        return (provisionApp.length == 2);
     }
 
     // The logic here is aimed solely at confirming that a CarrierConfig exists
@@ -423,6 +417,20 @@
         return !isEntitlementCheckRequired;
     }
 
+    // Used by the SIM card change observation code.
+    // TODO: De-duplicate above code.
+    private boolean hasMobileHotspotProvisionApp() {
+        try {
+            if (!mContext.getResources().getString(com.android.internal.R.string.
+                    config_mobile_hotspot_provision_app_no_ui).isEmpty()) {
+                Log.d(TAG, "re-evaluate provisioning");
+                return true;
+            }
+        } catch (Resources.NotFoundException e) {}
+        Log.d(TAG, "no prov-check needed for new SIM");
+        return false;
+    }
+
     /**
      * Enables or disables tethering for the given type. This should only be called once
      * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks
@@ -1178,7 +1186,7 @@
     }
 
     private void reevaluateSimCardProvisioning() {
-        if (!mConfig.hasMobileHotspotProvisionApp()) return;
+        if (!hasMobileHotspotProvisionApp()) return;
         if (carrierConfigAffirmsEntitlementCheckNotRequired()) return;
 
         ArrayList<Integer> tethered = new ArrayList<>();
@@ -1537,6 +1545,7 @@
                     return;
                 }
 
+                mCarrierConfigChange.startListening();
                 mSimChange.startListening();
                 mUpstreamNetworkMonitor.start();
 
@@ -1554,6 +1563,7 @@
                 mOffload.stop();
                 mUpstreamNetworkMonitor.stop();
                 mSimChange.stopListening();
+                mCarrierConfigChange.stopListening();
                 notifyDownstreamsOfNewUpstreamIface(null);
                 handleNewUpstreamNetworkState(null);
             }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 454c579..09bce7f 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -21,23 +21,14 @@
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
-import static com.android.internal.R.array.config_mobile_hotspot_provision_app;
-import static com.android.internal.R.array.config_tether_bluetooth_regexs;
-import static com.android.internal.R.array.config_tether_dhcp_range;
-import static com.android.internal.R.array.config_tether_usb_regexs;
-import static com.android.internal.R.array.config_tether_upstream_types;
-import static com.android.internal.R.array.config_tether_wifi_regexs;
-import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
-import android.net.util.SharedLog;
 import android.telephony.TelephonyManager;
-import android.text.TextUtils;
+import android.net.util.SharedLog;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.R;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -60,8 +51,6 @@
 public class TetheringConfiguration {
     private static final String TAG = TetheringConfiguration.class.getSimpleName();
 
-    private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
     @VisibleForTesting
     public static final int DUN_NOT_REQUIRED = 0;
     public static final int DUN_REQUIRED = 1;
@@ -90,18 +79,18 @@
     public final String[] dhcpRanges;
     public final String[] defaultIPv4DNS;
 
-    public final String[] provisioningApp;
-    public final String provisioningAppNoUi;
-
     public TetheringConfiguration(Context ctx, SharedLog log) {
         final SharedLog configLog = log.forSubComponent("config");
 
-        tetherableUsbRegexs = getResourceStringArray(ctx, config_tether_usb_regexs);
+        tetherableUsbRegexs = ctx.getResources().getStringArray(
+                com.android.internal.R.array.config_tether_usb_regexs);
         // TODO: Evaluate deleting this altogether now that Wi-Fi always passes
         // us an interface name. Careful consideration needs to be given to
         // implications for Settings and for provisioning checks.
-        tetherableWifiRegexs = getResourceStringArray(ctx, config_tether_wifi_regexs);
-        tetherableBluetoothRegexs = getResourceStringArray(ctx, config_tether_bluetooth_regexs);
+        tetherableWifiRegexs = ctx.getResources().getStringArray(
+                com.android.internal.R.array.config_tether_wifi_regexs);
+        tetherableBluetoothRegexs = ctx.getResources().getStringArray(
+                com.android.internal.R.array.config_tether_bluetooth_regexs);
 
         dunCheck = checkDunRequired(ctx);
         configLog.log("DUN check returned: " + dunCheckString(dunCheck));
@@ -112,9 +101,6 @@
         dhcpRanges = getDhcpRanges(ctx);
         defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
 
-        provisioningApp = getResourceStringArray(ctx, config_mobile_hotspot_provision_app);
-        provisioningAppNoUi = getProvisioningAppNoUi(ctx);
-
         configLog.log(toString());
     }
 
@@ -130,10 +116,6 @@
         return matchesDownstreamRegexs(iface, tetherableBluetoothRegexs);
     }
 
-    public boolean hasMobileHotspotProvisionApp() {
-        return !TextUtils.isEmpty(provisioningAppNoUi);
-    }
-
     public void dump(PrintWriter pw) {
         dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs);
         dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs);
@@ -147,10 +129,6 @@
 
         dumpStringArray(pw, "dhcpRanges", dhcpRanges);
         dumpStringArray(pw, "defaultIPv4DNS", defaultIPv4DNS);
-
-        dumpStringArray(pw, "provisioningApp", provisioningApp);
-        pw.print("provisioningAppNoUi: ");
-        pw.println(provisioningAppNoUi);
     }
 
     public String toString() {
@@ -162,8 +140,6 @@
         sj.add(String.format("isDunRequired:%s", isDunRequired));
         sj.add(String.format("preferredUpstreamIfaceTypes:%s",
                 makeString(preferredUpstreamNames(preferredUpstreamIfaceTypes))));
-        sj.add(String.format("provisioningApp:%s", makeString(provisioningApp)));
-        sj.add(String.format("provisioningAppNoUi:%s", provisioningAppNoUi));
         return String.format("TetheringConfiguration{%s}", sj.toString());
     }
 
@@ -183,7 +159,6 @@
     }
 
     private static String makeString(String[] strings) {
-        if (strings == null) return "null";
         final StringJoiner sj = new StringJoiner(",", "[", "]");
         for (String s : strings) sj.add(s);
         return sj.toString();
@@ -220,7 +195,8 @@
     }
 
     private static Collection<Integer> getUpstreamIfaceTypes(Context ctx, int dunCheck) {
-        final int ifaceTypes[] = ctx.getResources().getIntArray(config_tether_upstream_types);
+        final int ifaceTypes[] = ctx.getResources().getIntArray(
+                com.android.internal.R.array.config_tether_upstream_types);
         final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
         for (int i : ifaceTypes) {
             switch (i) {
@@ -271,30 +247,14 @@
     }
 
     private static String[] getDhcpRanges(Context ctx) {
-        final String[] fromResource = getResourceStringArray(ctx, config_tether_dhcp_range);
+        final String[] fromResource = ctx.getResources().getStringArray(
+                com.android.internal.R.array.config_tether_dhcp_range);
         if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) {
             return fromResource;
         }
         return copy(DHCP_DEFAULT_RANGE);
     }
 
-    private static String getProvisioningAppNoUi(Context ctx) {
-        try {
-            return ctx.getResources().getString(config_mobile_hotspot_provision_app_no_ui);
-        } catch (Resources.NotFoundException e) {
-            return "";
-        }
-    }
-
-    private static String[] getResourceStringArray(Context ctx, int resId) {
-        try {
-            final String[] strArray = ctx.getResources().getStringArray(resId);
-            return (strArray != null) ? strArray : EMPTY_STRING_ARRAY;
-        } catch (Resources.NotFoundException e404) {
-            return EMPTY_STRING_ARRAY;
-        }
-    }
-
     private static String[] copy(String[] strarray) {
         return Arrays.copyOf(strarray, strarray.length);
     }
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index d241b32..8fb87f1 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -355,7 +355,6 @@
     @Test
     public void canRequireProvisioning() {
         setupForRequiredProvisioning();
-        sendConfigurationChanged();
         assertTrue(mTethering.isTetherProvisioningRequired());
     }
 
@@ -364,7 +363,6 @@
         setupForRequiredProvisioning();
         when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
                 .thenReturn(null);
-        sendConfigurationChanged();
         // Couldn't get the CarrierConfigManager, but still had a declared provisioning app.
         // We therefore still require provisioning.
         assertTrue(mTethering.isTetherProvisioningRequired());
@@ -374,7 +372,6 @@
     public void toleratesCarrierConfigMissing() {
         setupForRequiredProvisioning();
         when(mCarrierConfigManager.getConfig()).thenReturn(null);
-        sendConfigurationChanged();
         // We still have a provisioning app configured, so still require provisioning.
         assertTrue(mTethering.isTetherProvisioningRequired());
     }
@@ -414,11 +411,6 @@
         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
-    private void sendConfigurationChanged() {
-        final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
-        mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
     private void verifyInterfaceServingModeStarted() throws Exception {
         verify(mNMService, times(1)).getInterfaceConfig(TEST_WLAN_IFNAME);
         verify(mNMService, times(1))