diff options
author | Quang Luong <qal@google.com> | 2022-04-21 14:10:53 -0700 |
---|---|---|
committer | Quang Luong <qal@google.com> | 2022-04-27 20:33:06 +0000 |
commit | d6c1f8c3e53dcca4285e727df538e9cdf2892f51 (patch) | |
tree | 90fbbab9538d9f753718bf8401ed6d5b2855933a | |
parent | 6456430de37c49835b11db49b53cdff942b9973d (diff) | |
download | wifi-d6c1f8c3e53dcca4285e727df538e9cdf2892f51.tar.gz |
Register for system default network instead of regular default network
ConnectivityManager.registerDefaultNetworkCallback provides updates to
the default network of the requestor, which could be a VPN using
cellular when the underlying system default network is Wifi. Thus
WifiTrackerLib should use registerDefaultNetworkCallback to know the
true underlying default network.
Bug: 224857908
Test: atest WifiTrackerlibTests SdkWifiTrackerLibTests
Change-Id: Id87eea1132568685fa2962ec907f2b05223b816e
14 files changed, 75 insertions, 42 deletions
diff --git a/libs/WifiTrackerLib/Android.bp b/libs/WifiTrackerLib/Android.bp index d57fc333d..ca94243ff 100644 --- a/libs/WifiTrackerLib/Android.bp +++ b/libs/WifiTrackerLib/Android.bp @@ -26,8 +26,8 @@ android_library { android_library { name: "SdkWifiTrackerLib", defaults: ["WifiTrackerLibDefaults"], - srcs: ["sdk_src/**/HiddenApiWrapper.java"], - exclude_srcs: ["src/**/HiddenApiWrapper.java"], + srcs: ["sdk_src/**/NonSdkApiWrapper.java"], + exclude_srcs: ["src/**/NonSdkApiWrapper.java"], sdk_version: "system_current", } diff --git a/libs/WifiTrackerLib/sdk_src/src/com/android/wifitrackerlib/HiddenApiWrapper.java b/libs/WifiTrackerLib/sdk_src/src/com/android/wifitrackerlib/NonSdkApiWrapper.java index 4345d266b..af0520f60 100644 --- a/libs/WifiTrackerLib/sdk_src/src/com/android/wifitrackerlib/HiddenApiWrapper.java +++ b/libs/WifiTrackerLib/sdk_src/src/com/android/wifitrackerlib/NonSdkApiWrapper.java @@ -20,17 +20,18 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; +import android.os.Handler; import androidx.annotation.NonNull; /** - * Wrapper class to decouple WifiTrackerLibDefaults from @hide API usage at build time. - * This version avoids @hide APIs for usage in apps that can only access SDK APIs, e.g. SetupWizard. + * Wrapper class to decouple WifiTrackerLibDefaults from non-SDK API usage at build time, for use + * by apps that build against the SDK (e.g. SetupWizard). * * Clients may wish to provide their own implementation of these methods when copying this * library over to their own codebase. */ -class HiddenApiWrapper { +class NonSdkApiWrapper { /** * Starts the System captive portal app. */ @@ -64,4 +65,17 @@ class HiddenApiWrapper { // This should be false since SUW is not used in demo mode. return false; } + + /** + * Registers the system default network callback. + */ + static void registerSystemDefaultNetworkCallback( + @NonNull ConnectivityManager connectivityManager, + @NonNull ConnectivityManager.NetworkCallback callback, + @NonNull Handler handler) { + // registerSystemDefaultNetworkCallback does not have visibility to non-updatable modules, + // so we have to use the regular registerDefaultNetworkCallback here. + // TODO(b/230643853): See if we can add registerSystemDefaultNetworkCallback to the SDK. + connectivityManager.registerDefaultNetworkCallback(callback, handler); + } } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java index a116878fe..abb660fa6 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java @@ -193,7 +193,7 @@ public class BaseWifiTracker implements LifecycleObserver { final boolean oldCellDefault = mIsCellDefaultRoute; // raw Wifi or VPN-over-Wifi or VCN-over-Wifi is default => Wifi is default. mIsWifiDefaultRoute = networkCapabilities.hasTransport(TRANSPORT_WIFI) - || HiddenApiWrapper.isVcnOverWifi(networkCapabilities); + || NonSdkApiWrapper.isVcnOverWifi(networkCapabilities); mIsCellDefaultRoute = !mIsWifiDefaultRoute && networkCapabilities.hasTransport(TRANSPORT_CELLULAR); if (mIsWifiDefaultRoute != oldWifiDefault @@ -308,8 +308,8 @@ public class BaseWifiTracker implements LifecycleObserver { /* broadcastPermission */ null, mWorkerHandler); mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback, mWorkerHandler); - mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback, - mWorkerHandler); + NonSdkApiWrapper.registerSystemDefaultNetworkCallback( + mConnectivityManager, mDefaultNetworkCallback, mWorkerHandler); handleOnStart(); }); } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HiddenApiWrapper.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/NonSdkApiWrapper.java index cb6748201..b84ab1e31 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/HiddenApiWrapper.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/NonSdkApiWrapper.java @@ -22,6 +22,7 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.TransportInfo; import android.net.vcn.VcnTransportInfo; +import android.os.Handler; import android.os.UserManager; import android.text.Annotation; import android.text.SpannableString; @@ -35,13 +36,13 @@ import androidx.annotation.NonNull; import com.android.settingslib.HelpUtils; /** - * Wrapper class to decouple WifiTrackerLibDefaults from @hide API usage at build time. - * This version uses @hide APIs for usage within the Android platform. + * Wrapper class to decouple WifiTrackerLibDefaults from non-SDK API usage at build time. + * This version uses non-SDK APIs for usage within the Android platform. * * Clients of WifiTrackerLib that can only access SDK APIs should use SdkWifiTrackerLib, which - * replaces this class with the version found in WifiTrackerLib/sdk_src/../HiddenApiWrapper.java. + * replaces this class with the version found in WifiTrackerLib/sdk_src/../NonSdkApiWrapper.java. */ -class HiddenApiWrapper { +class NonSdkApiWrapper { /** * Starts the System captive portal app. */ @@ -98,4 +99,14 @@ class HiddenApiWrapper { static boolean isDemoMode(@NonNull Context context) { return UserManager.isDeviceInDemoMode(context); } + + /** + * Registers the default network callback. + */ + static void registerSystemDefaultNetworkCallback( + @NonNull ConnectivityManager connectivityManager, + @NonNull ConnectivityManager.NetworkCallback callback, + @NonNull Handler handler) { + connectivityManager.registerSystemDefaultNetworkCallback(callback, handler); + } } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java index 1125bd303..4b7fbeffa 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java @@ -611,7 +611,7 @@ public class PasspointWifiEntry extends WifiEntry implements WifiEntry.WifiEntry if (canSignIn()) { // canSignIn() implies that this WifiEntry is the currently connected network, so use // getCurrentNetwork() to start the captive portal app. - HiddenApiWrapper.startCaptivePortalApp( + NonSdkApiWrapper.startCaptivePortalApp( mContext.getSystemService(ConnectivityManager.class), mWifiManager.getCurrentNetwork()); } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java index f7e0dac9c..249544b7d 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java @@ -433,7 +433,7 @@ public class StandardWifiEntry extends WifiEntry { if (canSignIn()) { // canSignIn() implies that this WifiEntry is the currently connected network, so use // getCurrentNetwork() to start the captive portal app. - HiddenApiWrapper.startCaptivePortalApp( + NonSdkApiWrapper.startCaptivePortalApp( mContext.getSystemService(ConnectivityManager.class), mWifiManager.getCurrentNetwork()); } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java index f46229f8e..26807b039 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java @@ -667,7 +667,7 @@ public class Utils { } // IMSI protection is not provided, return warning message. - return HiddenApiWrapper.linkifyAnnotation(context, context.getText( + return NonSdkApiWrapper.linkifyAnnotation(context, context.getText( R.string.wifitrackerlib_imsi_protection_warning), "url", context.getString(R.string.wifitrackerlib_help_url_imsi_protection)); } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java index 8ce87748e..c61f13105 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiTrackerInjector.java @@ -36,7 +36,7 @@ class WifiTrackerInjector { // TODO(b/201571677): Migrate the rest of the common objects to WifiTrackerInjector. WifiTrackerInjector(@NonNull Context context) { - mIsDemoMode = HiddenApiWrapper.isDemoMode(context); + mIsDemoMode = NonSdkApiWrapper.isDemoMode(context); mUserManager = context.getSystemService(UserManager.class); mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class); mNoAttributionAnnotationPackages = new ArraySet<>(); diff --git a/libs/WifiTrackerLib/tests/Android.bp b/libs/WifiTrackerLib/tests/Android.bp index 87b00332f..1a6b57a05 100644 --- a/libs/WifiTrackerLib/tests/Android.bp +++ b/libs/WifiTrackerLib/tests/Android.bp @@ -54,7 +54,7 @@ android_test { android_test { name: "SdkWifiTrackerLibTests", defaults: ["WifiTrackerLibTestDefaults"], - exclude_srcs: ["src/**/HiddenApiWrapperTest.java"], + exclude_srcs: ["src/**/NonSdkApiWrapperTest.java"], static_libs: [ "SdkWifiTrackerLib", diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/HiddenApiWrapperTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/NonSdkApiWrapperTest.java index 438095d4c..1d68b18ee 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/HiddenApiWrapperTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/NonSdkApiWrapperTest.java @@ -34,7 +34,7 @@ import android.text.style.ClickableSpan; import org.junit.Test; -public class HiddenApiWrapperTest { +public class NonSdkApiWrapperTest { @Test public void testLinkifyAnnotation_annotation_returnTextWithClickableSpan() { final String annotationId = "id"; @@ -45,7 +45,7 @@ public class HiddenApiWrapperTest { builder.append(testLink, new Annotation("key", annotationId), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - final CharSequence output = HiddenApiWrapper.linkifyAnnotation( + final CharSequence output = NonSdkApiWrapper.linkifyAnnotation( mock(Context.class), builder, annotationId, "url"); final SpannableString outputSpannableString = new SpannableString(output); @@ -64,7 +64,7 @@ public class HiddenApiWrapperTest { builder.append(testLink, new Annotation("key", annotationId), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - final CharSequence output = HiddenApiWrapper.linkifyAnnotation( + final CharSequence output = NonSdkApiWrapper.linkifyAnnotation( mock(Context.class), builder, annotationId, ""); final SpannableString outputSpannableString = new SpannableString(output); @@ -74,22 +74,22 @@ public class HiddenApiWrapperTest { } /** - * Verifies the functionality of {@link HiddenApiWrapper#isVcnOverWifi} + * Verifies the functionality of {@link NonSdkApiWrapper#isVcnOverWifi} */ @Test public void testIsVcnOverWifi() { NetworkCapabilities networkCapabilities = mock(NetworkCapabilities.class); - assertThat(HiddenApiWrapper.isVcnOverWifi(networkCapabilities)).isFalse(); + assertThat(NonSdkApiWrapper.isVcnOverWifi(networkCapabilities)).isFalse(); VcnTransportInfo vcnTransportInfo = mock(VcnTransportInfo.class); when(networkCapabilities.getTransportInfo()).thenReturn(vcnTransportInfo); - assertThat(HiddenApiWrapper.isVcnOverWifi(networkCapabilities)).isFalse(); + assertThat(NonSdkApiWrapper.isVcnOverWifi(networkCapabilities)).isFalse(); WifiInfo wifiInfo = mock(WifiInfo.class); when(vcnTransportInfo.getWifiInfo()).thenReturn(wifiInfo); - assertThat(HiddenApiWrapper.isVcnOverWifi(networkCapabilities)).isTrue(); + assertThat(NonSdkApiWrapper.isVcnOverWifi(networkCapabilities)).isTrue(); } } diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/PasspointWifiEntryTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/PasspointWifiEntryTest.java index c291ae02f..ac09b4494 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/PasspointWifiEntryTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/PasspointWifiEntryTest.java @@ -338,19 +338,19 @@ public class PasspointWifiEntryTest { NetworkCapabilities captivePortalCapabilities = new NetworkCapabilities.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL).build(); - MockitoSession session = mockitoSession().spyStatic(HiddenApiWrapper.class).startMocking(); + MockitoSession session = mockitoSession().spyStatic(NonSdkApiWrapper.class).startMocking(); try { // Simulate user tapping on the network and receiving captive portal capabilities. // This should trigger the captive portal app. entry.connect(null /* callback */); entry.updateNetworkCapabilities(captivePortalCapabilities); - verify(() -> HiddenApiWrapper.startCaptivePortalApp(any(), any()), times(1)); + verify(() -> NonSdkApiWrapper.startCaptivePortalApp(any(), any()), times(1)); // Update network capabilities again. This should not trigger the captive portal app. entry.updateNetworkCapabilities(captivePortalCapabilities); - verify(() -> HiddenApiWrapper.startCaptivePortalApp(any(), any()), times(1)); + verify(() -> NonSdkApiWrapper.startCaptivePortalApp(any(), any()), times(1)); } finally { session.finishMocking(); } diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java index 520eb8a29..1d6e1db68 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java @@ -943,19 +943,19 @@ public class StandardWifiEntryTest { NetworkCapabilities captivePortalCapabilities = new NetworkCapabilities.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL).build(); - MockitoSession session = mockitoSession().spyStatic(HiddenApiWrapper.class).startMocking(); + MockitoSession session = mockitoSession().spyStatic(NonSdkApiWrapper.class).startMocking(); try { // Simulate user tapping on the network and receiving captive portal capabilities. // This should trigger the captive portal app. entry.connect(null /* callback */); entry.updateNetworkCapabilities(captivePortalCapabilities); - verify(() -> HiddenApiWrapper.startCaptivePortalApp(any(), any()), times(1)); + verify(() -> NonSdkApiWrapper.startCaptivePortalApp(any(), any()), times(1)); // Update network capabilities again. This should not trigger the captive portal app. entry.updateNetworkCapabilities(captivePortalCapabilities); - verify(() -> HiddenApiWrapper.startCaptivePortalApp(any(), any()), times(1)); + verify(() -> NonSdkApiWrapper.startCaptivePortalApp(any(), any()), times(1)); } finally { session.finishMocking(); } diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java index c479eb75b..6b2a7e365 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java @@ -365,7 +365,7 @@ public class UtilsTest { final CharSequence testText = "test text"; final CharSequence output = - HiddenApiWrapper.linkifyAnnotation(mMockContext, testText, "id", "url"); + NonSdkApiWrapper.linkifyAnnotation(mMockContext, testText, "id", "url"); final SpannableString outputSpannableString = new SpannableString(output); assertEquals(output.toString(), testText.toString()); diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java index 176452e5f..22318da51 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java @@ -30,6 +30,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -611,9 +612,10 @@ public class WifiPickerTrackerTest { mTestLooper.dispatchAll(); verify(mMockConnectivityManager) .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any()); - verify(mMockConnectivityManager) - .registerDefaultNetworkCallback(mDefaultNetworkCallbackCaptor.capture(), any()); - + verify(mMockConnectivityManager, atLeast(0)).registerSystemDefaultNetworkCallback( + mDefaultNetworkCallbackCaptor.capture(), any()); + verify(mMockConnectivityManager, atLeast(0)).registerDefaultNetworkCallback( + mDefaultNetworkCallbackCaptor.capture(), any()); // Set cellular to be the default network mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(mMockNetwork, new NetworkCapabilities.Builder() @@ -1360,8 +1362,10 @@ public class WifiPickerTrackerTest { final Intent intent = new Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); intent.putExtra("subscription", subId); mBroadcastReceiverCaptor.getValue().onReceive(mMockContext, intent); - verify(mMockConnectivityManager) - .registerDefaultNetworkCallback(mDefaultNetworkCallbackCaptor.capture(), any()); + verify(mMockConnectivityManager, atLeast(0)).registerSystemDefaultNetworkCallback( + mDefaultNetworkCallbackCaptor.capture(), any()); + verify(mMockConnectivityManager, atLeast(0)).registerDefaultNetworkCallback( + mDefaultNetworkCallbackCaptor.capture(), any()); MergedCarrierEntry mergedCarrierEntry = wifiPickerTracker.getMergedCarrierEntry(); assertThat(mergedCarrierEntry.getConnectedState()) .isEqualTo(WifiEntry.CONNECTED_STATE_CONNECTED); @@ -1394,17 +1398,19 @@ public class WifiPickerTrackerTest { final Intent intent = new Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); intent.putExtra("subscription", subId); mBroadcastReceiverCaptor.getValue().onReceive(mMockContext, intent); - verify(mMockConnectivityManager) - .registerDefaultNetworkCallback(mDefaultNetworkCallbackCaptor.capture(), any()); + verify(mMockConnectivityManager, atLeast(0)).registerSystemDefaultNetworkCallback( + mDefaultNetworkCallbackCaptor.capture(), any()); + verify(mMockConnectivityManager, atLeast(0)).registerDefaultNetworkCallback( + mDefaultNetworkCallbackCaptor.capture(), any()); MergedCarrierEntry mergedCarrierEntry = wifiPickerTracker.getMergedCarrierEntry(); assertThat(mergedCarrierEntry.getConnectedState()) .isEqualTo(WifiEntry.CONNECTED_STATE_CONNECTED); // Wifi isn't default yet, so isDefaultNetwork returns false assertThat(mergedCarrierEntry.isDefaultNetwork()).isFalse(); - MockitoSession session = mockitoSession().spyStatic(HiddenApiWrapper.class).startMocking(); + MockitoSession session = mockitoSession().spyStatic(NonSdkApiWrapper.class).startMocking(); try { - doReturn(true).when(() -> HiddenApiWrapper.isVcnOverWifi(any())); + doReturn(true).when(() -> NonSdkApiWrapper.isVcnOverWifi(any())); mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(mMockNetwork, new NetworkCapabilities.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build()); @@ -1438,8 +1444,10 @@ public class WifiPickerTrackerTest { mTestLooper.dispatchAll(); verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(), any(), any(), any()); - verify(mMockConnectivityManager) - .registerDefaultNetworkCallback(mDefaultNetworkCallbackCaptor.capture(), any()); + verify(mMockConnectivityManager, atLeast(0)).registerSystemDefaultNetworkCallback( + mDefaultNetworkCallbackCaptor.capture(), any()); + verify(mMockConnectivityManager, atLeast(0)).registerDefaultNetworkCallback( + mDefaultNetworkCallbackCaptor.capture(), any()); // Set the default route to wifi mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(mMockNetwork, new NetworkCapabilities.Builder() |