Merge "Don't crash Tethering service when WiFi feature is missing" am: 736f8ec55a am: 5278b64768

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1577289

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ice05e20436c5bab99e72f61179df055c657cc248
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 385c691..ac5857d 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -1689,12 +1689,14 @@
             // If this is a Wi-Fi interface, tell WifiManager of any errors
             // or the inactive serving state.
             if (who.interfaceType() == TETHERING_WIFI) {
-                if (who.lastError() != TETHER_ERROR_NO_ERROR) {
-                    getWifiManager().updateInterfaceIpState(
-                            who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
+                final WifiManager mgr = getWifiManager();
+                final String iface = who.interfaceName();
+                if (mgr == null) {
+                    Log.wtf(TAG, "Skipping WifiManager notification about inactive tethering");
+                } else if (who.lastError() != TETHER_ERROR_NO_ERROR) {
+                    mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_CONFIGURATION_ERROR);
                 } else {
-                    getWifiManager().updateInterfaceIpState(
-                            who.interfaceName(), IFACE_IP_MODE_UNSPECIFIED);
+                    mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_UNSPECIFIED);
                 }
             }
         }
@@ -2421,6 +2423,19 @@
             mLog.log(iface + " is not a tetherable iface, ignoring");
             return;
         }
+
+        final PackageManager pm = mContext.getPackageManager();
+        if ((interfaceType == TETHERING_WIFI || interfaceType == TETHERING_WIGIG)
+                && !pm.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            mLog.log(iface + " is not tetherable, because WiFi feature is disabled");
+            return;
+        }
+        if (interfaceType == TETHERING_WIFI_P2P
+                && !pm.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
+            mLog.log(iface + " is not tetherable, because WiFi Direct feature is disabled");
+            return;
+        }
+
         maybeTrackNewInterfaceLocked(iface, interfaceType);
     }
 
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index f4b3749..60fddb5 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -586,6 +586,9 @@
                 ArgumentCaptor.forClass(SoftApCallback.class);
         verify(mWifiManager).registerSoftApCallback(any(), softApCallbackCaptor.capture());
         mSoftApCallback = softApCallbackCaptor.getValue();
+
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
+        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true);
     }
 
     private void setTetheringSupported(final boolean supported) {