From 7bbe3eee52c08ee92a81b7bed395ca5499554cc4 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 24 Aug 2017 22:35:10 +0900 Subject: [PATCH] Declare support for Ethernet if the service is running. On some devices, support for TYPE_ETHERNET is not specified in the networkAttributes config resource, even though the device is capable of supporting Ethernet (e.g., via USB host adapters). This leads to Ethernet working but various connectivity APIs behaving as if it was not - for example, no CONNECTIVITY_ACTION broadcasts will be issues when it connects or disconnects. Ensure that ConnectivityService always treats Ethernet as available if the service is running. Currently the service is started if the device supports FEATURE_ETHERNET or FEATURE_USB_HOST. Bug: 37359230 Test: bullhead builds, boots Test: ConnectivityServiceTest passes Test: Ethernet is available even if removed from networkAttributes resource Test: ConnectivityManagerTest CTS test passes Change-Id: I58801bf4f0bbdc3ff6345ec6bfdc911ce045c8ab --- .../java/com/android/server/ConnectivityService.java | 14 ++++++++++++++ .../java/com/android/server/ConnectivityServiceTest.java | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index be236f946551..1f75b908f2aa 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -19,6 +19,7 @@ package com.android.server; import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.NETID_UNSET; +import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_NONE; import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.getNetworkTypeName; @@ -91,6 +92,7 @@ import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.os.UserHandle; @@ -782,6 +784,13 @@ public class ConnectivityService extends IConnectivityManager.Stub mNetworksDefined++; // used only in the log() statement below. } + // Do the same for Ethernet, since it's often not specified in the configs, although many + // devices can use it via USB host adapters. + if (mNetConfigs[TYPE_ETHERNET] == null && hasService(Context.ETHERNET_SERVICE)) { + mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET); + mNetworksDefined++; + } + if (VDBG) log("mNetworksDefined=" + mNetworksDefined); mProtectedNetworks = new ArrayList(); @@ -5552,6 +5561,11 @@ public class ConnectivityService extends IConnectivityManager.Stub return new WakeupMessage(c, h, s, cmd, 0, 0, obj); } + @VisibleForTesting + public boolean hasService(String name) { + return ServiceManager.checkService(name) != null; + } + private void logDefaultNetworkEvent(NetworkAgentInfo newNai, NetworkAgentInfo prevNai) { int newNetid = NETID_UNSET; int prevNetid = NETID_UNSET; diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index a8147380386f..9c498c795443 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -19,6 +19,8 @@ package com.android.server; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; +import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; import static android.net.ConnectivityManager.TYPE_NONE; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.getNetworkTypeName; @@ -782,6 +784,13 @@ public class ConnectivityServiceTest extends AndroidTestCase { return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj); } + @Override + public boolean hasService(String name) { + // Currenty, the only relevant service that ConnectivityService checks for is + // ETHERNET_SERVICE. + return Context.ETHERNET_SERVICE.equals(name); + } + public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() { return mLastCreatedNetworkMonitor; } @@ -929,6 +938,13 @@ public class ConnectivityServiceTest extends AndroidTestCase { // will fail. Failing here is much easier to debug. assertTrue(mCm.isNetworkSupported(TYPE_WIFI)); assertTrue(mCm.isNetworkSupported(TYPE_MOBILE)); + assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_MMS)); + assertFalse(mCm.isNetworkSupported(TYPE_MOBILE_FOTA)); + + // Check that TYPE_ETHERNET is supported. Unlike the asserts above, which only validate our + // mocks, this assert exercises the ConnectivityService code path that ensures that + // TYPE_ETHERNET is supported if the ethernet service is running. + assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET)); } @SmallTest -- 2.11.0